- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
As titled, I'm currently having trouble obtaining the equivalent pixels value between IPP7 and IPP9 when I'm trying to copy a 8-bit image using ippiCopy. To confirm the variance, I've print all of the pixel values of both images into CSV format individually and compare both of them using winMerge, the variance were off by somewhat a large amount (between 1 to 60). Due to that, the generated result after different types of image processing method were affected as well. Were this suppose to be a bug or intentional?
Code Snippet:
IppStatus status = ippiCopy_8u_C1R(src, srcPitch, dst, dstPitch, srcRoiSize);
Update 2.5:
Found the culprit, it was caused by ippiMalloc_<mod>, apparently the returned pStepBytes was not as same compared to Ipp7's even-though both heights and widths are the same. A bug perhaps?
Please advise.
Thanks,
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi John,
It is unknown problem. You mentioned, ippiMalloc_<mod>, and ippiCopy_8u_C1R, how do you call them together. Could you please show more parameters about your call? or one small test case should be help.
Best Regards,
Ying
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Ying,
Thank you for the prompt response. As mentioned in my updates, the problem no longer reside on ippiCopy_8u_C1R but actually on ippiMalloc_<mod>, although there are some other functions that still causes pixel variances, but one problem at a time.
Here's a small example:
int src_tempPitch = 0;
Ipp8u* src_temp = ippiMalloc_8u_C1(1089, 1089, &src_tempPitch);
When IPP7 ran the code above, the src_tempPitch I'll be getting will be 1120, where as IPP9 returned me 1152 instead. Was it intended?
Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi John,
Default alignment has changed to 64 bytes as IPP supports AVX-512 now. This approach guarantees aligned data load for any image row.
regards, Igor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Igor,
That do explains why I'm getting different stepBytes. But unfortunately some of the results generated from IPP9 program are not equivalent with IPP7's due to ippiMalloc_<mod>. Is there any way to change the default alignment as same as the one that the IPP7 is using?
Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi John,
the ippiMalloc can help aligned memory with 32 bytes(8.0) or 64bytes (9.0), but it is not required, so if you'd make sure the src_tempPitch be 1120 , you may try Malloc(1089*1120) or ippsMalloc_8u(1089*1120) and set them manually.
On the other hand, when you get such Pitch, there are padding at the end of row. you may take care of them and keep the result correct.
For example,
int src_tempPitch = 0;
Ipp8u* src_temp = ippiMalloc_8u_C1(1089, 1089, &src_tempPitch);
Ipp8u* dst = Malloc(1089*1120);
int distPitch = 1120;
IppStatus status = ippiCopy_8u_C1R(src, src_tempPitch, dst, dstPitch, srcRoiSize);
Best Regards,
Ying
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Ying,
First and foremost, thank you for the prompt response. Could you further elaborate on the examples you have given? Unfortunately the srcPitch will not be affix on 1120, as my program support wide variety size of images. In addition, what needs to be done if I want to apply the same method on 8-bit to 32-bit conversion?
Here's some examples:
CASE A:
//srcPitch = 1120 int srcWidth = 1089; int srcHeight = 1089; int src_tempPitch = 0; Ipp8u* src_temp = ippiMalloc_8u_C1(srcWidth, srcHeight, &src_tempPitch); // Returned 1152 instead of 1120 IppStatus status = status = ippiCopy_8u_C1R(src, srcPitch, src_temp, src_tempPitch, srcRoiSize);
CASE B:
//srcPitch = 1120 int srcWidth = 1089; int srcHeight = 1089; int src32Pitch = 0; Ipp32f* src32f = ::ippiMalloc_32f_C1(srcWidth, srcHeight, &src32fPitch); // Returned 4412 instead of 4384 IppiSize const srcRoiSize = {srcWidth, srcHeight}; IppStatus status = ippiConvert_8u32f_C1R(src, srcPitch, src32f, src32fPitch, srcRoiSize);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi John,
I attach one sample, which show the result like below.
ippIP AVX2 (l9) 7.1.1 (r37466) 7.1.1.37466
src_tempPitch : 64
original src :
1 ; 2 ; 127 ; 4 ; 5 ; 0 ;
ippiCopy_8u_C1R status ippStsNoErr: No errors.:
1 ; 2 ; 127 ; 75 ; 0 ; 0 ;
ippiCopy_8u_C1R correct result should be :
1 ; 2 ; 127 ; 4 ; 5 ; 0 ;
Press any key to continue . . .
ippIP AVX2 (l9) 2017.0.1 (r53196) 2017.0.1.53196
src_tempPitch : 64
original src :
1 ; 2 ; 127 ; 4 ; 5 ; 0 ;
ippiCopy_8u_C1R status ippStsNoErr: No errors.:
1 ; 2 ; 127 ; 0 ; 0 ; 0 ;
ippiCopy_8u_C1R correct result should be :
1 ; 2 ; 127 ; 4 ; 5 ; 0 ;
Press any key to continue . . .
Actually, whatever of src_tempPitch is or ippiMalloc aligned with 32 or 64, you may take care of the result image based on it. for example, when your read image, you should drop the padding pixel, like
printf("\n ippiCopy_8u_C1R correct result should be :\n"); for(int i = 0; i < 2; i++) for(int j = 0; j < 3; j++) printf("%hd ; ", src_temp[i*src_tempPitch + j]);
Same as 32f type.
#include "stdafx.h" #include "ipp.h" //#define IPP_90 int _tmain(int argc, _TCHAR* argv[]) { const IppLibraryVersion* lib = ippiGetLibVersion(); printf("%s %s %d.%d.%d.%d\n",lib->Name, lib->Version,lib->major, lib->minor, lib->majorBuild, lib->build); Ipp8u src[2*3] = {1,2,127,4,5,0}; #ifdef IPP_70 int srcWidth = 3; int srcHeight = 2; int src_tempPitch = 0; Ipp8u* src_temp = ippiMalloc_8u_C1(srcWidth, srcHeight, &src_tempPitch); // Returned 1152 instead of 1120 IppStatus status = ippiCopy_8u_C1R(src, srcPitch, src_temp, src_tempPitch, srcRoiSize); #else int srcWidth = 3; int srcHeight = 2; IppiSize srcRoiSize={srcWidth,srcHeight}; int srcPitch = 3; int src_tempPitch = 0; Ipp8u* src_temp = ippiMalloc_8u_C1(srcWidth, srcHeight, &src_tempPitch); // Returned 1152 instead of 1120 printf("src_tempPitch : %d\n", src_tempPitch ); IppStatus status = ippiCopy_8u_C1R(src, srcPitch, src_temp, src_tempPitch, srcRoiSize); #endif printf("original src :\n"); for(int i = 0; i < 6; i++) printf("%hd ; ", src); printf("\n ippiCopy_8u_C1R status %s:\n", ippGetStatusString(status)); for(int i = 0; i < 6; i++) printf("%hd ; ", src_temp); printf("\n ippiCopy_8u_C1R correct result should be :\n"); for(int i = 0; i < 2; i++) for(int j = 0; j < 3; j++) printf("%hd ; ", src_temp[i*src_tempPitch + j]); printf("\n"); }
Best Regards,
Ying
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Ying,
Thank you, that really helps a lot.
Just another question, does the ippiColorToGray function respecting the pitch of the image? Because somehow pixels variance occurs after that function between IPP7 and IPP9. Previously I tried ippiRGBToGray_<mod> instead but variance was even worse.
Here's a snippet:
int srcWidth = 1089; int srcHeight = 1089; int dstWidth = 1089; int dstHeight = 1089; int dst8uPitch = 0; Ipp8u* dst8uC3 = ::ippiMalloc_8u_C3(srcWidth , srcHeight , &dst8uPitch); ::IppiSize const srcRoiSize = { srcWidth , srcHeight }; ::IppiSize const dstRoiSize = { dstWidth , dstHeight }; ::IppiRect srcRect = { 0, 0, srcWidth , srcHeight }; Ipp32f coeffs[3] = { 0.2126f, 0.7152f, 0.0722f }; //Luminance status = ::ippiCFAToRGB_8u_C1C3R(src, srcRect, srcRoiSize, srcPitch, dst8uC3, dst8uPitch, ippiBayerRGGB, 0); status = ::ippiColorToGray_8u_C3C1R(dst8uC3, dst8uPitch, dst, dstPitch, srcRoiSize, coeffs); // Variance happens here
Again, you're help is greatly appreciated.
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi John,
Yes, whatever aligned, all of IPP functions will respect to the stepBytes, (that is why the parameter was designed here.) You mentioned that "somehow pixels variance occurs ", if default assume that ippiCFAToRBG and ippiColorToGray haven't bug, then it should be get same result in IPP 7.0 and 2017. .
and read the dst data based on dstPitchs.
printf("\n Dst[2*3] result should be :\n");
for(int i = 0; i < dstHeight ; i++)
for(int j = 0; j < dstWidth; j++)
printf("%hd ; ", src_temp[i*dstPitch + j]);
I test the piece of the code you attached with 2017 update 1, Please tell if any change in 7.1.
best Regards,
Ying
ippIP AVX2 (l9) 2017.0.1 (r53196) 2017.0.1.53196
src_tempPitch : 64
original src :
1 ; 2 ; 127 ; 4 ; 5 ; 0 ;
ippiCopy_8u_C1R status ippStsNoErr: No errors.:
1 ; 2 ; 127 ; 0 ; 0 ; 0 ;
ippiCopy_8u_C1R correct result should be :
1 ; 2 ; 127 ; 4 ; 5 ; 0 ;
Dst[2*3] result should be :
1 ; 2 ; 127 ; 0 ; 0 ; 0 ;
Press any key to continue . . .
#include "stdafx.h" #include "ipp.h" //#define IPP_90 int _tmain(int argc, _TCHAR* argv[]) { const IppLibraryVersion* lib = ippiGetLibVersion(); printf("%s %s %d.%d.%d.%d\n",lib->Name, lib->Version,lib->major, lib->minor, lib->majorBuild, lib->build); Ipp8u src[2*3] = {1,2,127,4,5,0}; #ifdef IPP_70 int srcWidth = 3; int srcHeight = 2; int src_tempPitch = 0; Ipp8u* src_temp = ippiMalloc_8u_C1(srcWidth, srcHeight, &src_tempPitch); // Returned 1152 instead of 1120 IppStatus status = ippiCopy_8u_C1R(src, srcPitch, src_temp, src_tempPitch, srcRoiSize); #else int srcWidth = 3; int srcHeight = 2; IppiSize srcRoiSize={srcWidth,srcHeight}; int srcPitch = 3; int src_tempPitch = 0; Ipp8u* src_temp = ippiMalloc_8u_C1(srcWidth, srcHeight, &src_tempPitch); // Returned 1152 instead of 1120 printf("src_tempPitch : %d\n", src_tempPitch ); IppStatus status1 = ippiCopy_8u_C1R(src, srcPitch, src_temp, src_tempPitch, srcRoiSize); int dstWidth = 3; int dstHeight = 2; int dstPitch = dstWidth *sizeof(Ipp8u); Ipp8u dst[2*3]; int dst8uPitch = 0; Ipp8u* dst8uC3 = ::ippiMalloc_8u_C3(srcWidth , srcHeight , &dst8uPitch); //IppiSize const srcRoiSize = { srcWidth , srcHeight }; IppiSize const dstRoiSize = { dstWidth , dstHeight }; IppiRect srcRect = { 0, 0, srcWidth , srcHeight }; Ipp32f coeffs[3] = { 0.2126f, 0.7152f, 0.0722f }; //Luminance IppStatus status2 = ippiCFAToRGB_8u_C1C3R(src, srcRect, srcRoiSize, srcPitch, dst8uC3, dst8uPitch, ippiBayerRGGB, 0); IppStatus status3 = ippiColorToGray_8u_C3C1R(dst8uC3, dst8uPitch, dst, dstPitch, srcRoiSize, coeffs); #endif printf("original src :\n"); for(int i = 0; i < 6; i++) printf("%hd ; ", src); printf("\n ippiCopy_8u_C1R status %s:\n", ippGetStatusString(status1)); for(int i = 0; i < 6; i++) printf("%hd ; ", src_temp); printf("\n ippiCopy_8u_C1R correct result should be :\n"); for(int i = 0; i < 2; i++) for(int j = 0; j < 3; j++) printf("%hd ; ", src_temp[i*src_tempPitch + j]); printf("\n Dst[2*3] result should be :\n"); for(int i = 0; i < dstHeight ; i++) for(int j = 0; j < dstWidth; j++) printf("%hd ; ", src_temp[i*dstPitch + j]); printf("\n"); }
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Ying,
I can confirmed the variance doesn't occurs with the sample array you've given. But it does happens on the 1089 x 1089 images I'm currently processing.
The function below were used to generate CSV files containing the images pixels for comparison:
static void debugCSV(unsigned char const* const src, IppiSize srcRoiSize, const char* savePath, int srcPitch) { std::ofstream file(savePath, std::ios_base::out | std::ios_base::app); for (int i = 0; i< srcRoiSize.height; ++i) for (int j = 0; j< srcRoiSize.width; ++j) { file << j << "," << i << "," << static_cast<int>(src[i*srcPitch + j]) << std::endl; } }
Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi John,
Could you send the CSV or the jpg image to us to test?
Best Regards,
Ying

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