iOS 사용 비 전원-of-2 이미지에서 2D 신호 처리를 위해 프레임 워크를 가속화합니까?

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

문제

// 편집 ...

비정상적인 두 이미지로 특별히 일하는 문제를 해결하기 위해 내 질문을 약간 편집하고 있습니다. 256x256 또는 1024x1024와 같은 크기의 사각형 회색조 이미지와 함께 작동하는 기본 구조가 있지만 임의로 크기의 이미지로 일반화하는 방법을 볼 수는 없습니다. FFT 기능은 폭과 높이의 log2를 포함시키는 것 같지만 결과 데이터의 포장을 풀고 데이터가 스크램블 된 경우 불분명합니다. 나는 명백한 일이 더 큰, 모든 검은 색 이미지 내에서 NPOT 이미지를 중심적으로 중앙에두고 데이터를 볼 때 해당 위치의 값을 무시하는 것입니다. 그러나 NPOT 데이터로 작업하는 데 어색한 방법이 덜 있는지 궁금해합니다.

// ... 종료 편집

가속 프레임 워크 문서에 약간의 문제가 발생합니다. 나는 일반적으로 FFTW3을 사용하지만 실제 iOS 장치에서 컴파일하는 데 어려움을 겪고 있습니다 (이 질문 ). 누구도 다음과 같은 것을 수행하는 가속을 사용하여 슈퍼 간단한 구현으로 나를 지적 할 수 있습니다.

1) 이미지 데이터를 가속화의 FFT 방법으로 전달할 수있는 적절한 데이터 구조로 전환합니다.
FFTW3에서는 그레이 스케일 이미지를 사용하여 간단한 가장 단순한 바이트를 사용하여 부호없는 바이트를 "fftw_complex"배열로 배치하는 것이 포함되며, 이는 단순히 두 개의 수레의 구조체, 하나는 실제 가치와 다른 상상의 (그리고 상상의 위치는 각 픽셀마다 0으로 초기화).

2)이 데이터 구조를 가져 와서 FFT를 수행합니다.

3) 크기와 위상을 인쇄합니다.

4) IFFT를 수행합니다.

5) IFFT로 인한 데이터에서 원본 이미지를 재창조합니다.

이것은 매우 기본적인 예이지만 Apple의 사이트에서 문서를 사용하는 데 어려움을 겪고 있습니다. SO Pi에 의해 답변 는 매우 도움이되지만, 나는 아직도 있습니다. 다소 혼란스러워서 회색조 (또는 색상) 2D 이미지를 사용 하여이 기본 기능을 수행하기 위해 가속화하는 방법에 대해 혼란스러워합니다.

어쨌든, 어떤 포인터 또는 특히 2D 이미지를 처리하는 간단한 작업 코드가 매우 도움이 될 것입니다!

\\\ 편집 \\\

는 문서에 잠수하고 매우 유용한 코드뿐만 아니라 pkmital의 github repo , 나는 내가 게시 할 것이라고 생각한 몇 가지 작업 코드를 가지고 있습니다. 1) 나는 그것을 알아내는 동안 그것을 알아 내고 2) 두 사람이 있기 때문에 나머지 질문 ...

FFT "계획"을 초기화합니다. 정사각형 2의 이미지를 가정합니다 :

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

은 정사각형 전원 - 2 회색 스케일 이미지에 대한 바이트 배열을 통과하여 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]);
}
.

이제 OUT_FFT 데이터에서 iFFT를 실행하여 원래 이미지를 얻을 수 있습니다 ...

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

i가 가속 프레임 워크를 사용하여 비 전원 -2 이미지를 처리하는 방법을 알 수 없습니다. 설정에 충분한 메모리를 할당하면 FFT를 수행하고 IFFT가 내 원본 이미지를 얻을 수 있습니다. 그러나 (FFT의 크기로) 자기 상관을 시도하는 경우 내 이미지가 원하지 않는 결과를 얻습니다. 나는 이미지를 적절하게 패딩하는 가장 좋은 방법을 확신하지 못하기 때문에, 그렇지 않으면 누군가 가이 일을하는 방법에 대한 아이디어를 가지고 있습니다. (또는 VDSP_CONV 메서드의 작업 버전을 공유하십시오!)

도움이 되었습니까?

해결책

임의의 이미지 크기에 대한 작업을 수행하기 위해서는 입력 값 배열의 크기가 2의 다음 전원에 적절하게 크기에 맞추어야한다고 말합니다.

하드 부분은 원본 이미지 데이터와 채우기 위해 무엇을 채우는지입니다. 이미지에서 이미지 나 데이터를 정말로하려고 노력하고있는 것은 중요합니다.

아래의 연결된 PDF에서 12.4.2 단락에 특히주의를 기울이십시오. http://www.mathcs.org/java/programs/fft. /fftinfo/c12-4.pdf

위의 내용은 2 축의 조작에 대해 이야기하는 동안, 우리는 두 번째 차원 이전에 유사한 아이디어를 수행하고 두 번째 차원에 다음과 같은 이후에 수행 할 수 있습니다. IM이 올바른 경우이 예제가 적용될 수 있습니다 (아직 정확한 알고리즘이 아니라는 것은 아닙니다) :

우리는 900 x 900 인 이미지가 있습니다. 먼저 이미지를 512, 256, 128 및 4의 수직 스트립으로 분할 할 수 있습니다. 그런 다음 우리는 각 행에 4 개의 1D FFT를 처리 할 것입니다, 첫 번째 512 픽셀의 경우 다음 128에 대한 다음 256 픽셀의 경우 다음 128에 대해 다음 128, FFT의 출력이 본질적으로 인기이기 때문에 나머지 4에 대한 마지막 것입니다. 주파수의 경우, 이들은 단순히 (각도 오프셋이 아닌 주파수의 관점에서만) 추가 될 수 있습니다. 그런 다음이 동일한 기술을 2 차 치수로 밀어 넣을 수 있습니다. 이 시점에서 우리는 실제로 패드가없는 모든 입력 픽셀을 고려해야했습니다.

이것은 정말로 생각을위한 음식이며, 나는 이것을 자신을 시도하지 않았으며, 실제로 이것을 나 자신을 연구해야한다. 지금 이런 종류의 일을 진정으로하고 있다면, 당신은이 시점에서 나보다 더 많은 시간을 가질 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top