Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.

Product in Fourier Space

j_bossu
Beginner
478 Views
Well,

I must filter an image with a Gabor filter. I know the expression of the fourier transform, so I compute a kernel directly in the fourier space. To compute the FFT of my Image, I use the ippiFFTFwd_RToPack_32f_C1R function but the result in RCPack2D format, I transform this result with the PackToCplxExtend function and I compute a simple product. But to compute the IFFT, the input buffer must be in RCPack2D format, How make a RCPack2D.

Thanks.
0 Kudos
3 Replies
Vladimir_Dudnik
Employee
478 Views

Hi,

there is answer fromour expert:
The best way from the performance point of view is to convert Gabor filter to the pack format and than use ippiMulPack function. Unfortunately there is no such function in IPP. Use IPPI manual p.10.5 for such conversion:

Table 10-4 RCPack2D Storage for Odd Number of Rows

Re A(0,0) Re A(0,1) Im A(0,1) ... Re A(0,(N-1)/2) Im A(0,(N-1)/2) Re A(0,N/2)
Re A(1,0) Re A(1,1) Im A(1,1) ... Re A(1,(N-1)/2) Im A(1,(N-1)/2) Re A(1,N/2)
Im A(1,0) Re A(2,1) Im A(2,1) ... Re A(2,(N-1)/2) Im A(2,(N-1)/2) Im A(1,N/2)
... ... ... ... ... ... ...
Re A
(M/2,0) Re A(M-2,1) Im A(M-2,1) ... Re A(M-2,(N-1)/2) Im A(M-2,(N-1)/2) Re A(M/2,N/2)
Im A(M/2,0) Re A(M-1,1) Im A(M-1,1) ... Re A(M-1,(N-1)/2) Im A(M-1,(N-1)/2) Im A(M/2,N/2)

Table 10-5 RCPack2D Storage for Even Number of Rows

Re A(0,0) Re A(0,1) Im A(0,1) ... Re A(0,(N-1)/2) Im A(0,(N-1)/2) Re A(0,N/2)
Re A(1,0) Re A(1,1) Im A(1,1) ... Re A(1,(< FONT face=Courier size=1>N-1)/2) Im A(1,(N-1)/2) Re A(1,N/2)
Im A(1,0) Re A(2,1) Im A(2,1) ... Re A(2,(N-1)/2) Im A(2,(N-1)/2) Im A(1,N/2)
... ... ... ... ... ... ...
Re A
(M/2-1,0) Re A(M-3,1) Im A(M-3,1) ... Re A(M-3,(N-1)/2) Im A(M-3,(N-1)/2) Re A(M/2-1,N/2)
Im A(M/2-1,0) Re A(M-2,1) Im A(M-2,1) ... Re A(M-2,(N-1)/2) Im A(M-2,(N-1)/2) Im A(M/2-1,N/2)
Re A(M/2,0) Re A(M-1,1) Im A(M-1,1) ... Re A(M-1,(N-1)/2) Im A(M-1,(N-1)/2) Re A(M/2,N/2)

Note the above tables show the arrangement of coefficients for one channel. For multichannel images the channel coefficients are clustered and stored consecutively, for example, for 3-channel image they are stored in the following way:

C1-Re A(0,0); C2-Re A(0,0); C3-Re A(0,0);
C1-Re A(0,1); C2-Re A(0,1); C3-Re A(0,1);
C1-Im A(0,1); C2-Im A(0,1); ...

The remaining Fourier coefficients are obtained using the following relationships based on conjugate-symmetric properties:

A(i,j) = conj(A(M-i,N-j)) i = 1,..., M-1; j = 1,..., N-1
A(0,j) = conj(A(0,N-j)) j = 1,..., N-1
A(i,0) = conj(A(M-i,0)) i = 1,..., M-1

Regards,
Vladimir

0 Kudos
j_bossu
Beginner
478 Views
Hi,

I understood the RCpack2D format. But to transform my gabor filter in the rcpack2D format, I must to have a complexe format. My Gabor filter is a real filter, all the imaginary parts are null.
How to copy a real Ipp to a complexe Ipp.

I tried this but I have a problem

Ipp32f *filter;
Ipp32fc *filter_complex;
IppiSize size;
int step_filter, step_filter_complexe;

size.width=512;
size.height=512;

filter=ippiMalloc_32f_C1(size.width,size.height,&step_filter);
filter_complex=ippiMalloc_32fc_C1(size.width,size.height,&step_filter_complex);

filter=gabor(......);//gabor filter value. Real value

ippiSet_32f_C1R(0,&filter_complex->im,step_filter_complex,size);//imaginary //value=0;

//copy gabor filter to real part of filter_complex
ippiCopy_32f_C1R(filter,step_filter,&filter_complex->re,step_filter_complex,size);

//end

But, this method is not suitable because, I have a problem beween the real and imaginary value.

Can you help me, please ?

Thanks a lot.

Jrmie.
0 Kudos
Vladimir_Dudnik
Employee
478 Views

Hi,

comments from our expert:

Copying is not right. The order should be: re, im, re, im, re, im,

There is a special function for such purpose (ippSP domain only, no such in ippIP, therefore you should use a loop through filter height):

/* /////////////////////////////////////////////////////////////////////////////
// Name: ippsRealToCplx
// Purpose: form complex vector from the real and imaginary components
// Parameters:
// pSrcRe pointer to the input vector with real part, may be NULL
// pSrcIm pointer to the input vector with imaginary part, may be NULL
// pDst pointer to the output complex vector
// len length of the vectors
// Return:
// ippStsNullPtrErr pointer to the destination data is NULL
// ippStsSizeErr length of the vectors is less or equal zero
// ippStsNoErr otherwise
//
// Notes: one of the two input pointers may be NULL. In this case
// the corresponding values of the output complex elements is 0
*/

IPPAPI(IppStatus, ippsRealToCplx_64f,( const Ipp64f* pSrcRe, const Ipp64f* pSrcIm, Ipp64fc* pDst, int len ))
IPPAPI(IppStatus, ippsRealToCplx_32f,( const Ipp32f* pSrcRe, const Ipp32f* pSrcIm, Ipp32fc* pDst, int len ))
IPPAPI(IppStatus, ippsRealToCplx_16s,( const Ipp16s* pSrcRe, const Ipp16s* pSrcIm, Ipp16sc* pDst, int len ))

Regards,
Vladimir

0 Kudos
Reply