Я провел двумерное преобразование Фурье на матрице 4436413x3 с помощью команды matlab fft2 (эта: https://www.mathworks.com/help/matlab/ref/fft2.html). Продукт представляет собой матрицу 4436413x3, содержащую комплексные значения. Когда я пытаюсь отобразить данные, я получаю график одного цвета или сообщение об ошибке, которое ссылается на сложные значения в моих данных.
Я попытался интерполировать для создания 2D-набора значений с помощью функции griddata(), однако при применении к моему 3D-набору данных она возвращает 1D-вектор, равный z-столбцу в моем исходном 3D-наборе данных. Мой набор 3D-данных состоит из точек x, y и z, и при попытке интерполяции я использовал vq = griddata(x,y,z,x,y). Я также пытался создать сетку 4436412x3 для своих точек запроса (используя [xq, yq] = meshgrid (4436412, 3), а затем используя xq и yq в качестве точек запроса), но это возвращало NaN.
Когда я бегу Y = fft2(x); imagesc(abs(fftshift(Y))) Я получаю одну фиолетовую коробку.
Когда я бегу Y = fft2(x); изображенияc(Y) Я получаю следующее сообщение об ошибке:
Error using image
Complex values are not supported. Specify the color data as numeric or logical values.
Error in imagesc (line 52)
hh = image(varargin{:}, 'CDataMapping', 'scaled');
Итак, ошибка вполне очевидна и имеет смысл, комплексное значение по сути состоит из 2 значений, поэтому вы не можете построить его как изображение, потому что каждый пиксель может иметь только 1 значение.
@AnderBiguri, как я могу преобразовать значения в несложные?
@CrisLuengo Меня попросили выполнить 2Dfft для набора данных. Я знаю, что он огромный - это сканирование поверхности в белом свете с высоким разрешением. Я также запутался в том, как выполнить 2D-преобразование в наборе 3D-данных — я очень давно не думал о преобразованиях Фурье.
Вы уверены, что 3 — это не размер RGB, а 4M — это не 2000x2000 или что-то в этом роде? Возможно, вы захотите выполнить 2D-БПФ по двум пространственным измерениям, по одному для каждого цветового канала.
Хммм… 4436413 — простое число. Я предполагаю, что кто-то дергает вас за ногу. Ничего из этого не имеет смысла. Зачем сканеру создавать массив с простым числом выборок?
@CrisLuengo Не должно быть измерения RGB, потому что для сканирования нет данных о цвете. Мы пытаемся количественно определить шероховатость поверхности, поэтому сканирование записывает только расстояние от поверхности до сканера в z-измерении по каждой координате x и y. Первоначально в наборе данных было 9006000 наблюдений, однако для многих из них не было данных о высоте, и поэтому они были опущены (оставив мне 4436413 наблюдений). Никто не «тянет меня за ногу» — я делаю это как последний проект для класса.
О, так один из ваших столбцов равен x, другой — y, а третий — z? Это имеет гораздо больше смысла. Не рассматривайте это как двумерный массив, это облако точек. Применять к нему БПФ нет смысла. Если вы хотите использовать БПФ, вам нужно будет интерполировать, чтобы создать двумерный массив значений z, выбранных на регулярной сетке x-y. Вы также можете попробовать 2D-неоднородное БПФ (nuFFT), но не уверены, насколько хорошо они работают.
@CrisLuengo Большое спасибо за помощь. Можете ли вы сказать мне, как сделать этот тип интерполяции, или указать мне ресурс, который может научить меня, как это сделать? Я никогда не делал ничего подобного раньше.
Используйте эту функцию: mathworks.com/help/matlab/ref/griddata.html
@CrisLuengo Спасибо, но не похоже, что это решает мою проблему. Я все еще получаю график, который все только один цвет.
На этот вопрос пока нет ответов, поэтому вы можете обновить его, указав то, что уже сделали. Сказать «это не сработало», не показав, что это такое, не позволяет мне помочь.
@CrisLuengo Извините за абстрактность. Я обновил вопрос - все еще пытаюсь сопоставить мой набор 3D-данных с 2D.
Чтобы применить БПФ, вам нужно, чтобы данные были выбраны на регулярной сетке. Ваши данные представляют (x, y, z) координаты точек. Вот как использовать griddata
для повторной выборки этих координат в обычную (x, y) сетку:
% Generate example data, let's say x and y are in the range [-3,3]:
n = 62500;
x = rand(n, 1) * 6 - 3;
y = rand(n, 1) * 6 - 3;
z = sin(4*x) + cos(2*y); % an example function
data = [x,y,z]; % This is a 4436413x3 array with (x,y,z) coordinates
% Interpolate z values onto a regular (x,y) grid:
[xq, yq] = meshgrid(linspace(min(x), max(x), sqrt(n)), ...
linspace(min(y), max(y), sqrt(n)));
zq = griddata(x, y, z, xq, yq);
% griddata doesn't extrapolate, writes NaN instead. Let's fill those
% in with zeros (maybe a different value is more meaningful in your
% application).
zq(isnan(zq)) = 0;
% Now you can apply a 2D Fourier transform:
Z = fft2(zq);
imshow(log(abs(fftshift(Z))), []);
Я сделал это, используя [xq, yq] = meshgrid(linspace(min(x), max(x), 2), ... linspace(min(y), max(y), 4436413)), создав 4436413x2 zq . Я думаю, это то, что я хотел, учитывая, что я хочу набор 2D-данных? Есть ли причина, по которой я должен интерполировать на квадратную сетку?
@bluekangaroo Почему вы выбрали ось x только дважды, а ось y - 4 миллиона раз? Вам не нужна квадратная сетка, но вам нужна разумная сетка. Начните с scatter3(x,y,z)
и посмотрите на свои данные. Как отбираются точки? Теперь выберите сетку, которая имеет смысл, когда вы смотрите на нее. Решите, как вы хотите разделить каждую ось. Затем постройте эту сетку с помощью meshgrid
.
4 миллиона умножить на 3? Это крайнее соотношение сторон для изображения. Вы не должны отображать это как изображение, а лучше отображать 3 столбца в виде линейных графиков. Вы уверены, что хотите выполнить 2D FFT, а не 3 1D FFT?