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

Some confusion about converting IPL 1bit funciton to IPP

sun_c_
Beginner
661 Views

My company still used old IPL  (IPL_DEPTH_1U functions)  , and let me change IPL 1bit function to IPP for build x64 software.

After used  ippiBinToGray_1u8u_C1R------>ipp functions------>ippiGrayToBin_8u1u_C1R, I find the result are different with IPL.

So, I do a test and find some difference.  I find old IPL 1 bit functions,gray to bin, convert 8 byte   to 1 byte with the older"high bit to low bit",

as opposed to IPP's   ippiGrayToBin_8u1u.

The test code is:

/////////////////////////////////////////////////////////code begin////////////////////////////////////////////////////////////////////

Ipp8u bitonalImage[8] = { 0 }; // for a 32x2 image
 bitonalImage[0] = 1;     //  00000001  high bit->low bit;
 bitonalImage[1] = 2;     //  00000010
 bitonalImage[2] = 4;     //  00000100
 bitonalImage[3] = 8;     //  00001000
 bitonalImage[4] = 16;   //  00010000
 bitonalImage[5] = 32;   //  00100000
 bitonalImage[6] = 64;   //  01000000
 bitonalImage[7] = 128; //  10000000

 Ipp8u grayImageIPP[64] = { 0 };

 ippiBinToGray_1u8u_C1R(bitonalImage, 4, 0, grayImageIPP, 32, { 32, 2 }, 0, 255);

 Ipp8u bitonalImageIPP[8] = { 0 };
 

 ippiGrayToBin_8u1u_C1R(grayImageIPP, 32, bitonalImageIPP, 4, 0, { 32, 2 }, 1);

IplImage *srcImage = iplCreateImageHeader(
  1,      // number of channels
  0,      // no alpha channel
  IPL_DEPTH_8U,   // data of byte type
  "Gray",     // color model
  "Gray",     // color order
  IPL_DATA_ORDER_PIXEL, // channel arrangement
  IPL_ORIGIN_TL,   // top left orientation
  IPL_ALIGN_DWORD,  // 4 bytes align
  32,    // image width
  2,    // image height
  NULL,     // no ROI
  NULL,     // no mask ROI
  NULL,     // no image ID
  NULL);     // not tiled

 if (NULL == srcImage)
  return 0;

 srcImage->imageData = (char *)grayImageIPP;

 

 Ipp8u bitonalImageIPL[8] = { 0 };
 IplImage *dstImage = iplCreateImageHeader(
  1,      // number of channels
  0,      // no alpha channel
  IPL_DEPTH_1U,   // data of byte type
  "Gray",     // color model
  "Gray",     // color order
  IPL_DATA_ORDER_PIXEL, // channel arrangement
  IPL_ORIGIN_TL,   // top left orientation
  IPL_ALIGN_DWORD,  // 4 bytes align
  32,    // image width
  2,    // image height
  NULL,     // no ROI
  NULL,     // no mask ROI
  NULL,     // no image ID
  NULL);     // not tiled

 if (NULL == dstImage)
  return 0;

 dstImage->imageData = (char *)bitonalImageIPL;
 iplThreshold(srcImage, dstImage, 1);


 iplDeallocate(srcImage, IPL_IMAGE_HEADER);
 iplDeallocate(dstImage, IPL_IMAGE_HEADER);

/////////////////////////////////////////////////////code end////////////////////////////////////////////////////////////////

 

 

 

The result of bitonalImageIPP is:

bitonalImage[0] = 1;   //  00000001  high bit->low bit;
bitonalImage[1] = 2;   //  00000010
bitonalImage[2] = 4;   //  00000100
bitonalImage[3] = 8;   //  00001000
bitonalImage[4] = 16;  //  00010000
bitonalImage[5] = 32;  //  00100000
bitonalImage[6] = 64;  //  01000000
bitonalImage[7] = 128; //  10000000
As the same with the bitonalImage.

The result of bitonalImageIPL is:

bitonalImageIPL[0] = 128; //  10000000 high bit------>low bit
 bitonalImageIPL[1] = 64;  //  01000000
 bitonalImageIPL[2] = 32;  //  00100000
 bitonalImageIPL[3] = 16;  //  00010000
 bitonalImageIPL[4] = 8;   //  00001000
 bitonalImageIPL[5] = 4;   //  00000100
 bitonalImageIPL[6] = 2;   //  00000010
 bitonalImageIPL[7] = 1;   //  00000001 

 

Are  all IPL 1 bit functions having these difference?

 

 

 

0 Kudos
1 Solution
Zhen_Z_Intel
Employee
661 Views

Hi sun,

We do not support for 1u type, I am afraid some Convert & Scale function could not binarize image. You probable need to use ippiReduceBits function. But in any case image step parameter in IPP is always measured in bytes, not in pixels nor elements.

{...
	ippiBinToGray_1u8u_C1R(bitonalImage, 4, 0, grayImageIPP, 32, { 32, 2 }, 0, 255);
	...
	ippiReduceBits_8u1u_C1R(grayImageIPP, 32, bitonalImageIPP, 4, 0, {32,2}, 0, 0, ippDitherNone, 1, 0);
	for(int i=0;i<sizeof(bitonalImageIPP);i++)
	{
		std::bitset<8> x(bitonalImageIPP);
		std::cout<<"bitonalImageIPP["<<i<<"]="<<x<<"\n";
	}
...}

Best regards,
Fiona

View solution in original post

0 Kudos
5 Replies
sun_c_
Beginner
661 Views

I convered IPL 1bit funciton to IPP successful.

All th IPL  1 bit funcitions(Intel® Image Processing Library 2.5 [IPL2.5W-B9]  )  have that difference.

0 Kudos
Zhen_Z_Intel
Employee
661 Views

Hi sun,

Here's an example of mapping IPL function to IPP functions, you could refer to take a try. I am afraid the functionality of using iplThreshold is not equals to IPP function ippiGrayToBin_8u1u_C1R. The iplThreshold function could be implemented by ippiSet_8u_C1R, ippiThreshold_LTVal_8u_C1R and ippiThreshold_GTVal_8u_C1IR.

Please learn more info from: https://software.intel.com/sites/default/files/m/6/7/d/1/6/876-ipl-ipp.pdf
I also attached sample code to you that you could access in download center for IPP 5.3.4 version.

 

Best regards,
Fiona

0 Kudos
sun_c_
Beginner
661 Views

Fiona Z. (Intel) wrote:

Hi sun,

Here's an example of mapping IPL function to IPP functions, you could refer to take a try. I am afraid the functionality of using iplThreshold is not equals to IPP function ippiGrayToBin_8u1u_C1R. The iplThreshold function could be implemented by ippiSet_8u_C1R, ippiThreshold_LTVal_8u_C1R and ippiThreshold_GTVal_8u_C1IR.

Please learn more info from: https://software.intel.com/sites/default/files/m/6/7/d/1/6/876-ipl-ipp.pdf
I also attached sample code to you that you could access in download center for IPP 5.3.4 version.

 

Best regards,
Fiona

Hi,Fiona.

I have seen the ipl-ipp.pdf and souce of IPL implements by IPP 5.3.4 in image processing sample.seems it does not support 1 bit function.

Part of souce code of IPLImage:

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

depth = (iplImage->depth&IPL_DEPTH_MASK);     /* absolute depth value    */
      /* +sag */
      if( 1 == depth ) depth = 8;   
      /* -sag */

      alignBit = (align<<3)-1;
      maskBit = ~alignBit;

      if( IPL_DATA_ORDER_PIXEL == dataOrder ) {
         iplImage->widthStep = ((width*depth*nChannels+alignBit)&maskBit)>>3; // For IPL_DEPTH_1U Image the depth should be 1, not 8
         iplImage->imageSize = iplImage->widthStep*height;
      } else {
         iplImage->widthStep = ((width*depth+alignBit)&maskBit)>>3;
         iplImage->imageSize = iplImage->widthStep*height*nChannels;
      }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

In my  case, I use iplThreshold (8bit gray Image(src),1bit image(dst),1), In the process 8bit src to 1 bit dst, it must have GraytoBin funciton, so I use  ippiGrayToBin_8u1u_C1R instead.

While ,I  use  ippiThreshold_LTVal_8u_C1R and ippiThreshold_GTVal_8u_C1IR first and then use  ippiGrayToBin_8u1u_C1R.The result are the same.

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Ipp8u bitonalImage[8] = { 0 }; // for a 32x2 image
 bitonalImage[0] = 1;   //  00000001  high bit->low bit;
 bitonalImage[1] = 2;   //  00000010
 bitonalImage[2] = 4;   //  00000100
 bitonalImage[3] = 8;   //  00001000
 bitonalImage[4] = 16;  //  00010000
 bitonalImage[5] = 32;  //  00100000
 bitonalImage[6] = 64;  //  01000000
 bitonalImage[7] = 128; //  10000000

 Ipp8u grayImageIPP[64] = { 0 };
 Ipp8u grayImageIPPTemp[64] = { 0 };
 
 ippiBinToGray_1u8u_C1R(bitonalImage, 4, 0, grayImageIPP, 32, { 32, 2 }, 0, 255);

 Ipp8u bitonalImageIPP[8] = { 0 };
 
 Ipp8u thresholdLT = (Ipp8u)1, thresholdGT = 0;
 Ipp8u valueLT = 0, valueGT = (Ipp8u)IPP_MAX_8U;
 ippiThreshold_LTVal_8u_C1R(grayImageIPP, 32, grayImageIPPTemp, 32, {32,2},
  thresholdLT, valueLT);
 ippiThreshold_GTVal_8u_C1IR(grayImageIPPTemp, 32, {32,2}, thresholdGT, valueGT);

 ippiGrayToBin_8u1u_C1R(grayImageIPPTemp, 32, bitonalImageIPP, 4, 0, { 32, 2 }, 1);

The result of bitonalImageIPP is:

bitonalImage[0] = 1;   //  00000001  high bit->low bit;
bitonalImage[1] = 2;   //  00000010
bitonalImage[2] = 4;   //  00000100
bitonalImage[3] = 8;   //  00001000
bitonalImage[4] = 16;  //  00010000
bitonalImage[5] = 32;  //  00100000
bitonalImage[6] = 64;  //  01000000
bitonalImage[7] = 128; //  10000000

No difference.

 

 

 

 

0 Kudos
Zhen_Z_Intel
Employee
662 Views

Hi sun,

We do not support for 1u type, I am afraid some Convert & Scale function could not binarize image. You probable need to use ippiReduceBits function. But in any case image step parameter in IPP is always measured in bytes, not in pixels nor elements.

{...
	ippiBinToGray_1u8u_C1R(bitonalImage, 4, 0, grayImageIPP, 32, { 32, 2 }, 0, 255);
	...
	ippiReduceBits_8u1u_C1R(grayImageIPP, 32, bitonalImageIPP, 4, 0, {32,2}, 0, 0, ippDitherNone, 1, 0);
	for(int i=0;i<sizeof(bitonalImageIPP);i++)
	{
		std::bitset<8> x(bitonalImageIPP);
		std::cout<<"bitonalImageIPP["<<i<<"]="<<x<<"\n";
	}
...}

Best regards,
Fiona

0 Kudos
sun_c_
Beginner
661 Views

Fiona Z. (Intel) wrote:

Hi sun,

We do not support for 1u type, I am afraid some Convert & Scale function could not binarize image. You probable need to use ippiReduceBits function. But in any case image step parameter in IPP is always measured in bytes, not in pixels nor elements.

{...
	ippiBinToGray_1u8u_C1R(bitonalImage, 4, 0, grayImageIPP, 32, { 32, 2 }, 0, 255);
	...
	ippiReduceBits_8u1u_C1R(grayImageIPP, 32, bitonalImageIPP, 4, 0, {32,2}, 0, 0, ippDitherNone, 1, 0);
	for(int i=0;i<sizeof(bitonalImageIPP);i++)
	{
		std::bitset<8> x(bitonalImageIPP);
		std::cout<<"bitonalImageIPP["<<i<<"]="<<x<<"\n";
	}
...}

Best regards,
Fiona

Thanks, ippiReduceBits_8u1u_C1R is OK, will check the diffirernce with ippiGrayToBin_8u1u_C1R 

0 Kudos
Reply