- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I'm using IPP for filtering. I'm having a hard time getting my source image data into IPP types and then back again.
Only the R channel is making it all the way through to Out_Img. I'm not sure if the problem is in the SourceToIpp function or in the IppToSource function. The non-Ipp code is working fine. It's something to do with the Ipp_Img and temp.
I'll most likely multithread these functions once I get them working. For now, I tried to keep them as clean as possible. I'm new to IPP so if there is a more efficient to copy the data inside the nested loops I would appreciate suggestions.
Any thoughts on why only the red channel is making it through? Thanks!!
[cpp]int In_StepBytes; Ipp32f *Ipp_In; IppiSize In_Size; // Get input images In_Img = (Image *)InImage->GetValue(req); Ipp_In = ippiMalloc_32f_C3(In_Img->Width, In_Img->Height, &In_StepBytes); SourceToIpp(In_Img, Ipp_In); /////// //Do filtering with Ipp_In /////// // Copy In_Img to Out_Img Out_Img = In_Img->CopyOfImage(); IppToSource(Out_Img, Ipp_In); void SourceToIpp(Image *S_Img, Ipp32f *Ipp_Img) { int temp_StepBytes; Ipp32f *temp; IppiSize temp_Size; int p_StepBytes; Ipp32f *p_Color[3]; int x = 0; int y = 0; PixPtr p_Img(S_Img); FltPixel p; // Allocate memory for temp Ipp image to represent pixel temp = ippiMalloc_32f_C3(1, 1, &temp_StepBytes); // Allocate memory for p_Color p_Color[0] = ippiMalloc_32f_C1(1, 1, &p_StepBytes); p_Color[1] = ippiMalloc_32f_C1(1, 1, &p_StepBytes); p_Color[2] = ippiMalloc_32f_C1(1, 1, &p_StepBytes); // Set temp size temp_Size.height = 1; temp_Size.width = 1; // Loop through image and copy data for (y = 0; y < S_Img->Height; y++) { p_Img.GotoXY(0, y); for (x = 0; x < S_Img->Width; x++) { // Advance through source pixels in current row if (x == 0) p = p_Img; else p >>= p_Img; // Copy source pixel data to Ipp p_Color *p_Color[0] = p.R; *p_Color[1] = p.G; *p_Color[2] = p.B; // Set temp IPP image to p_Color ippiCopy_32f_P3C3R(p_Color, p_StepBytes, temp, temp_StepBytes, temp_Size); // Copy IPP temp value to IPP bg at pointer locatoin offset by x and y *(Ipp_Img + (y * S_Img->Width) + x ) = *temp; } } // Free memory allocated for temp ippiFree(temp); ippiFree(p_Color[0]); ippiFree(p_Color[1]); ippiFree(p_Color[2]); } void IppToSource(Image *S_Img, Ipp32f *Ipp_Img) { int temp_StepBytes; Ipp32f *temp; IppiSize temp_Size; int p_StepBytes; Ipp32f *p_Color[3]; int x = 0; int y = 0; PixPtr p_Img(S_Img); FltPixel p; // Allocate memory for temp Ipp image to represent pixel temp = ippiMalloc_32f_C3(1, 1, &temp_StepBytes); // Allocate memory for p_Color p_Color[0] = ippiMalloc_32f_C1(1, 1, &p_StepBytes); p_Color[1] = ippiMalloc_32f_C1(1, 1, &p_StepBytes); p_Color[2] = ippiMalloc_32f_C1(1, 1, &p_StepBytes); // Set temp size temp_Size.height = 1; temp_Size.width = 1; // Loop through image and copy data for (y = 0; y < S_Img->Height; y++) { p_Img.GotoXY(0, y); for (x = 0; x < S_Img->Width; x++) { // Copy IPP value at pixel pointer position to temp *temp = *(Ipp_Img + (y * S_Img->Width) + x); ippiCopy_32f_C3P3R(temp, temp_StepBytes, p_Color, p_StepBytes, temp_Size); // Copy Ipp color data to p.R = *p_Color[0]; p.G = *p_Color[1]; p.B = *p_Color[2]; p.A = 0; // Advance through source pixels in current row if (x == 0) p_Img = p; else p_Img >>= p; } } // Free memory allocated for temp ippiFree(temp); ippiFree(p_Color[0]); ippiFree(p_Color[1]); ippiFree(p_Color[2]); }[/cpp]
Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I don't understand your code, especiallythe next construction - p >>= p_Img;
I don't understand your code, especiallythe next construction - p >>= p_Img;
Don't use P3C3 copy for 1 pixel - it's not efficient at all.
The next construction is wrong:
*(Ipp_Img + (y * S_Img->Width) + x ) = *temp;
you are copying here only R value and you should go from row to row by image step, not by its width:
tmpPtr = (Ipp32f*)( (Ipp8u*)Ipp_Img + y * in_StepBytes + 3 * SizeOf( Ipp32f ) * x );
tmpPtr[0] = p.R;
tmpPtr[1] = p.G;
tmpPtr[2] = p.B;
as C3 IPP image is represented as packed RGB values + align bytes for each row:
RGBRGBRGBRGB....RGBxxxxx
where xxxxx means a number of bytes (depends on image width) to align the beginning of the next row to 16-byte boundary
Regards,
Igor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Igor,
Thank you for the reply.
p is a variable holding one pixel using a type defined outside of IPP. p>>=p_Img copys the data in p into P_Img which is a pointer to a pixel in the non-IPP image type. As well as copying the data, >>= also advanves p_Img to the next pixel. Moreover, p>>=p_Img simply sets the pixel at at x,y equal p and advances to the next pixel in the row. p_Img.Goto(0,y) is used to set the start of each row.
I'll use the bytestep from now on instead of width. Thanks.
tmpPtr = (Ipp32f*) ( (Ipp8u*)Ipp_Img + y*in_StepBytes + 3 * SizeOf(Ipp32f)*x );
What is the purpose of (Ipp8u*)?
Is the above expression valid when tmpPtr is a 3-plane Ipp32f_C1 and Ipp_Img is a pixel-ordered Ipp32f_C3?
Best,
Ryan
Thank you for the reply.
p is a variable holding one pixel using a type defined outside of IPP. p>>=p_Img copys the data in p into P_Img which is a pointer to a pixel in the non-IPP image type. As well as copying the data, >>= also advanves p_Img to the next pixel. Moreover, p>>=p_Img simply sets the pixel at at x,y equal p and advances to the next pixel in the row. p_Img.Goto(0,y) is used to set the start of each row.
I'll use the bytestep from now on instead of width. Thanks.
tmpPtr = (Ipp32f*) ( (Ipp8u*)Ipp_Img + y*in_StepBytes + 3 * SizeOf(Ipp32f)*x );
What is the purpose of (Ipp8u*)?
Is the above expression valid when tmpPtr is a 3-plane Ipp32f_C1 and Ipp_Img is a pixel-ordered Ipp32f_C3?
Best,
Ryan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Ryan,
Could you please tell how you store yoursource image data?Are they are in continous array or discretedpoint in large array?
As you see, ipp image processing funtion(include ippiFilter_* function) use continous array.
They can be any continous array
frompSrc[512][512]
orpsr =malloc(width*height*sizeof(float)*channel).
or used aligned memory: Ipp_In=ippiMalloc_32f_C3(In_Img->Width,In_Img->Height,&In_StepBytes);
or fromyourImage class, where image data are stored in continous array.
(there is nospecial IPP image type needed).
So if your source image data are stored continously, then you may use them directly to ippiFilter function. like the C++ sample in IPP code sample or do search the sample code in the forum
ippiFilterGauss_8u_C1R( (Ipp8u*)pSrc->DataPtr(), pSrc->Step(),
(Ipp8u*)pDst->DataPtr(), pDst->Step(), pSrc->Size(),
,ippMskSize3x3)
It is not need to do the moving in or out.
If your souce image data are stored in discreted points, you may copy them to an array pSrc[width][height].
thus there is not needed to call ipp function like ippiCopy to copy only one pixel also. (it is inefficient).
but you have to use IPP function call, it may need to understand the bytestep,please see the article
http://software.intel.com/en-us/articles/intel-integrated-performance-primitives-intel-ipp-processing-an-image-from-edge-to-edge/
stepBytes.It is the distance in bytes of imagerow.It depends on your array memory layout and datatype.
AsstepBytesare in bytes, sothestart pointer IPP_img should be byte type. (either ipp 8u*, actually unsignedchar *)
Such the Ipp_Img + y*in_StepBytespoint tothe firstaddress of y row. then convert it to (IPP 32f*,actually float *) to get float pixel (whateveryRRRRRR, or RGBRGB store) .
Best Regards,
Ying
IppiSizeroiSize={1022,1022}; IppiSizeimgSize={1024,1024}; size_tsize=imgSize.width*imgSize.height*sizeof(Ipp8u); intsrcStep=imgSize.width*sizeof(Ipp8u); Ipp8u*data=(Ipp8u*)malloc(size); Ipp8u*pStartPoint; pStartPoint=data; ippiImageJaehne_8u_C1R(pStartPoint,srcStep,imgSize); intdstStep=roiSize.width*sizeof(Ipp8u); size_tdstSize=roiSize.width*roiSize.height; Ipp8u*dst=(Ipp8u*)malloc(dstSize); ippiFilterGauss_8u_C1R(data+srcStep/sizeof(Ipp8u)+1,srcStep,dst,dstStep,roiSize,ippMskSize3x3
Could you please tell how you store yoursource image data?Are they are in continous array or discretedpoint in large array?
As you see, ipp image processing funtion(include ippiFilter_* function) use continous array.
They can be any continous array
frompSrc[512][512]
orpsr =malloc(width*height*sizeof(float)*channel).
or used aligned memory: Ipp_In=ippiMalloc_32f_C3(In_Img->Width,In_Img->Height,&In_StepBytes);
or fromyourImage class, where image data are stored in continous array.
(there is nospecial IPP image type needed).
So if your source image data are stored continously, then you may use them directly to ippiFilter function. like the C++ sample in IPP code sample or do search the sample code in the forum
ippiFilterGauss_8u_C1R( (Ipp8u*)pSrc->DataPtr(), pSrc->Step(),
(Ipp8u*)pDst->DataPtr(), pDst->Step(), pSrc->Size(),
,ippMskSize3x3)
It is not need to do the moving in or out.
If your souce image data are stored in discreted points, you may copy them to an array pSrc[width][height].
thus there is not needed to call ipp function like ippiCopy to copy only one pixel also. (it is inefficient).
but you have to use IPP function call, it may need to understand the bytestep,please see the article
http://software.intel.com/en-us/articles/intel-integrated-performance-primitives-intel-ipp-processing-an-image-from-edge-to-edge/
stepBytes.It is the distance in bytes of imagerow.It depends on your array memory layout and datatype.
AsstepBytesare in bytes, sothestart pointer IPP_img should be byte type. (either ipp 8u*, actually unsignedchar *)
Such the Ipp_Img + y*in_StepBytespoint tothe firstaddress of y row. then convert it to (IPP 32f*,actually float *) to get float pixel (whateveryRRRRRR, or RGBRGB store) .
Best Regards,
Ying
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It looks like some ATL'sCOM objects are used:
>>...
>>PixPtrp_Img( S_Img );
>>FltPixel p;
>>...
and PixPtr is an MIDL's generatedCOM-class-wrapper.
>>...
>>p >>= p_Img;
>>...
and '>>=' is a C++ operator that moves some data to 'p_Img'...
Best regards,
Sergey
>>...
>>PixPtrp_Img( S_Img );
>>FltPixel p;
>>...
and PixPtr is an MIDL's generatedCOM-class-wrapper.
>>...
>>p >>= p_Img;
>>...
and '>>=' is a C++ operator that moves some data to 'p_Img'...
Best regards,
Sergey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Guys. I was able to get it working using this code:
[cpp] p.R = *(Ipp32f*)((Ipp8u*)Ipp_Img + (y * Ipp_StepBytes) + 3*sizeof(Ipp32f)*x ); p.G = *(Ipp32f*)((Ipp8u*)Ipp_Img + (y * Ipp_StepBytes) + 3*sizeof(Ipp32f)*x + sizeof(Ipp32f) ); p.B = *(Ipp32f*)((Ipp8u*)Ipp_Img + (y * Ipp_StepBytes) + 3*sizeof(Ipp32f)*x + 2*sizeof(Ipp32f) );[/cpp]

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page