Подтвердить что ты не робот

Использование IOS Accelerate Framework для обработки 2D-сигналов на изображениях без питания?

//РЕДАКТИРОВАТЬ...

Я немного изменяю свой вопрос, чтобы решить проблему работы с изображениями, отличными от двух. У меня есть базовая структура, которая работает с квадратными изображениями в оттенках серого с размерами, такими как 256x256 или 1024x1024, но не может понять, как обобщать изображения произвольного размера. Fft-функции, похоже, хотят, чтобы вы включили log2 ширины и высоты, но затем неясно, как распаковывать результирующие данные или если данные не просто скремблируются. Я полагаю, что очевидным было бы сосредоточить изображение npot в более крупном, черном изображении, а затем игнорировать любые значения в этих позициях при просмотре данных. Но интересно, есть ли менее неудобный способ работы с данными npot.

//... END EDIT

У меня возникли проблемы с документацией Accelerate Framework. Я бы обычно использовал FFTW3, но у меня возникли проблемы с этим, чтобы скомпилировать на реальном устройстве IOS (см. Этот question). Может ли кто-нибудь указать мне на суперпростую реализацию, используя Accelerate, что-то вроде следующего:

1) Поворачивает данные изображения в соответствующую структуру данных, которые можно передать методам ускорения FFT.
 В FFTW3, в самом простом, используя изображение в градациях серого, это включает в себя размещение беззнаковых байтов в массиве "fftw_complex", который представляет собой просто структуру из двух поплавков, один из которых содержит реальное значение, а другой - мнимый (и где мнимый инициализируется до нуля для каждого пикселя).

2) Принимает эту структуру данных и выполняет БПФ на ней.

3) Распечатывает величину и фазу.

4) Выполняет на нем IFFT.

5) Восстанавливает исходное изображение из данных, полученных в результате IFFT.

Хотя это очень простой пример, у меня возникли проблемы с использованием документации с сайта Apple. Ответ SO от Pi здесь очень полезен, но я все еще несколько смущен тем, как использовать Accelerate для выполнения этой базовой функции с использованием полутонового (или цветного) 2D-изображения.

Во всяком случае, любые указатели или особенно простой рабочий код, обрабатывающий 2D-изображение, будут чрезвычайно полезны!

\\\ EDIT \\\

Хорошо, потратив некоторое время на погружение в документацию и очень полезный код на SO, а также на pkmital github repo, я У меня есть рабочий код, который, как я думал, я бы опубликовал с 1) мне потребовалось некоторое время, чтобы понять это, и 2), так как у меня есть несколько оставшихся вопросов...

Инициализировать FFT "план". Предположим, что изображение квадратной формы два-двух:

#include <Accelerate/Accelerate.h>
...
UInt32 N = log2(length*length);
UInt32 log2nr = N / 2; 
UInt32 log2nc = N / 2;
UInt32 numElements = 1 << ( log2nr + log2nc );
float SCALE = 1.0/numElements;
SInt32 rowStride = 1; 
SInt32 columnStride = 0;
FFTSetup setup = create_fftsetup(MAX(log2nr, log2nc), FFT_RADIX2);

Перейдите в массив байтов для изображения с квадратной степенью двух оттенков серого и превратите его в COMPLEX_SPLIT:

COMPLEX_SPLIT in_fft;
in_fft.realp = ( float* ) malloc ( numElements * sizeof ( float ) );
in_fft.imagp = ( float* ) malloc ( numElements * sizeof ( float ) );

for ( UInt32 i = 0; i < numElements; i++ ) {
    if (i < t->width * t->height) {
      in_fft.realp[i] = t->data[i] / 255.0;
      in_fft.imagp[i] = 0.0;
    }
}

Запустите БПФ на данные преобразованного изображения, затем захватите величину и фазу:

COMPLEX_SPLIT out_fft;
out_fft.realp = ( float* ) malloc ( numElements * sizeof ( float ) );
out_fft.imagp = ( float* ) malloc ( numElements * sizeof ( float ) );

fft2d_zop ( setup, &in_fft, rowStride, columnStride, &out_fft, rowStride, columnStride, log2nc, log2nr, FFT_FORWARD );

magnitude = (float *) malloc(numElements * sizeof(float));
phase = (float *) malloc(numElements * sizeof(float));

for (int i = 0; i < numElements; i++) {
   magnitude[i] = sqrt(out_fft.realp[i] * out_fft.realp[i] + out_fft.imagp[i] * out_fft.imagp[i]) ;
   phase[i] = atan2(out_fft.imagp[i],out_fft.realp[i]);
}

Теперь вы можете запустить IFFT по данным out_fft, чтобы получить исходное изображение...

COMPLEX_SPLIT out_ifft;
out_ifft.realp = ( float* ) malloc ( numElements * sizeof ( float ) );
out_ifft.imagp = ( float* ) malloc ( numElements * sizeof ( float ) );
fft2d_zop (setup, &out_fft, rowStride, columnStride, &out_ifft, rowStride, columnStride, log2nc, log2nr, FFT_INVERSE);   

vsmul( out_ifft.realp, 1, SCALE, out_ifft.realp, 1, numElements );
vsmul( out_ifft.imagp, 1, SCALE, out_ifft.imagp, 1, numElements );

Или вы можете запустить IFFT по величине, чтобы получить автокорреляцию...

COMPLEX_SPLIT in_ifft;
in_ifft.realp = ( float* ) malloc ( numElements * sizeof ( float ) );
in_ifft.imagp = ( float* ) malloc ( numElements * sizeof ( float ) );
for (int i = 0; i < numElements; i++) {
  in_ifft.realp[i] = (magnitude[i]);
  in_ifft.imagp[i] = 0.0;
}

fft2d_zop ( setup, &in_fft, rowStride, columnStride, &out_ifft, rowStride, columnStride, log2nc, log2nr, FFT_INVERSE );      

vsmul( out_ifft.realp, 1, SCALE, out_ifft.realp, 1, numElements );
vsmul( out_ifft.imagp, 1, SCALE, out_ifft.imagp, 1, numElements );

Наконец, вы можете вернуть результаты ifft в массив изображений:

for ( UInt32 i = 0; i < numElements; i++ ) {
  t->data[i] = (int) (out_ifft.realp[i] * 255.0);
}     

Я не понял, как использовать фреймворк Accelerate для обработки изображений без питания двух. Если я назначу достаточно памяти в настройке, тогда я могу сделать FFT, а затем IFFT, чтобы получить исходное изображение. Но если попытаться сделать автокорреляцию (с величиной БПФ), то мое изображение получится неустойчивым. Я не уверен в лучшем способе правильно подставить изображение, так что, надеюсь, у кого-то есть идея, как это сделать. (Или поделитесь рабочей версией метода vDSP_conv!)

4b9b3361

Ответ 1

Я бы сказал, что для выполнения работы над произвольными размерами изображений все, что вам нужно сделать, - это размер вашего массива входных значений соответственно до следующего значения 2.

Жесткая часть - это то, где можно поместить исходные данные изображения и заполнить их. То, что вы действительно пытаетесь сделать с изображением или шахтой данных с изображения, имеет решающее значение.

В связанном PDF ниже обратите особое внимание на пункт чуть выше 12.4.2 http://www.mathcs.org/java/programs/FFT/FFTInfo/c12-4.pdf

В то время как выше сказанное говорит о манипуляции по двум осям, мы могли бы реализовать аналогичную идею до второго измерения и следовать за вторым измерением. Если Im верно, то этот пример может применяться (и это еще далеко не точный алгоритм):

говорят, что у нас есть изображение 900 900: сначала мы могли разбить изображение на вертикальные полосы 512, 256, 128 и 4. Затем мы обрабатывали 4 1D БПФ для каждой строки, один для первых 512 пикселей, следующий для следующих 256 пикселей, следующий для следующих 128, затем последний для оставшихся 4. Так как выход БПФ - это по существу популярность частоты, то их можно было бы просто добавить (с точки зрения частоты ТОЛЬКО, а не с помощью смещения angular). Тогда мы могли бы использовать эту технику для второго измерения. На этом этапе мы учли бы каждый входной пиксель, не имея при этом пэда.

Это действительно просто пища для размышлений, я не пробовал это сам, и действительно должен исследовать это сам. Если вы действительно делаете такую ​​работу прямо сейчас, у вас может быть больше времени, чем я на данный момент.