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

StackOverflow https://stackoverflow.com//questions/10708667

Вопрос

// Редактировать ...

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

// ... End Edit

У меня есть немного неприятностей с ускоренной каркасной документацией. У меня обычно использую FFTW3, но у меня возникли проблемы с получением этого для компиляции на фактическом устройстве iOS (см. Это Вопрос ). Кто-нибудь может указать мне суперпростую реализацию, используя ускорение, которое делает что-то вроде следующее:

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

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

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

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

5) воссоздает исходное изображение из данных, возникающих в результате IFFT.

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

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

\\\ Редактировать \\\

Хорошо, после того, как потребув некоторое время, чтобы погрузиться в документацию и какой-то очень полезный код на так, а также на Github repo pkmital 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;
    }
}
.

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

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);
}     
.

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

Это было полезно?

Решение

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

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

в связанном PDF ниже, обратите особое внимание на абзацу чуть выше 12.4.2. http://www.mathcs.org/java/programs/fft /Fftinfo/c12-4.pdf

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

Скажем, у нас есть изображение 900 на 900: Сначала мы могли бы разделить изображение в вертикальные полосы 512, 256, 128 и 4. Затем мы обрабатым 4 1D FFTS для каждой строки, один для первых 512 пикселей, следующий для следующих 256 пикселей, следующий на следующий 128, то последний для оставшихся 4. Поскольку вывод FFT по существу популярна частоты, то это можно просто добавить (от частоты только перспективы, а не углового смещения). Затем мы могли бы толкать эту же технику к 2-м измерению. На этом этапе мы бы приняли во внимание каждый входной пиксель, не имея находящихся на прокладке.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top