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

Error with ippiConvert_8u1u_C1R

alessandroferrucci
677 Views
Hello,

I have an application that reads JPEG's, converts them to grayscale and then binarizes them using ippiConvert_8u1u_C1R function. When I save the binarized image and view it, it looks squished horitontally (I think I'm not setting the dstStep correctly or something). Below is the relevant piece of code:

//m_image.Precision() is 8
monochrome_image.Alloc( grayscale_image.Size(), 1, m_image.Precision() );
//width: 5104, Height: 2204
IppiSize roiSize={grayscale_image.Width(),grayscale_image.Height()};
IppStatus mystatus;
mystatus = ippiConvert_8u1u_C1R(
(const Ipp8u*)grayscale_image.DataPtr(),grayscale_image.Step(),
(Ipp8u*)monochrome_image,monochrome_image.Width(),0,roiSize,(Ipp8u)148);

I looked at the available documentation but all they had was a description of dstStep for bitonal images, not a sample of how to set it. grayscale_image and monochrome image are both of type CIppImage. Prior to binarizing, I was saving the grayscale image on disk and it looked fine. Can anyone help me in this issue? Thanks!

Alessandro Ferrucci

0 Kudos
10 Replies
Vladimir_Dudnik
Employee
677 Views

Hi Alessandro,

to binarize image you probable need to use ippiReduceBits function rather than Convert_8u1u. But in any case image step parameter in IPP is always measured in bytes, not in pixels nor elements.

Regards,
Vladimir
0 Kudos
alessandroferrucci
677 Views

Hi Alessandro,

to binarize image you probable need to use ippiReduceBits function rather than Convert_8u1u. But in any case image step parameter in IPP is always measured in bytes, not in pixels nor elements.

Regards,
Vladimir

Hello Vladimir,

Thank you for response. I had looked at using ippiReduceBits_8u_C1R to convert grayscale to monochrome, however I need to be able to provide threshold level to the binarization algorithm (and Convert_8u1u allows for one).

I have converted my call to convert to:

ippiConvert_8u1u_C1R((const Ipp8u*)grayscale_image.DataPtr(),grayscale_image.Step(),(Ipp8u*)monochrome_image,monochrome_image.Step(),0,roiSize,(Ipp8u)148);

To just call my monochrome_image CIppImage's Step() method.

I create my monochrome_image like this:

monochrome_image.Alloc( grayscale_image.Size(), 1, 8 );

when I print out monochrome_image.Step(), I get 5401, which is same value as pixel width amount (and same amount as my grayscale_image Step() amount) . I would assume that on a monochrome image, the pixels would be packed 8 per byte, so I would assume to get something like 5401/8 Step() amount... am I missing something?

With this call to convert the image is still "scrunched" on the width, and the remaining width area is filled with black pixels.

Any insight?

thank you

Alessandro Ferrucci
0 Kudos
Ying_H_Intel
Employee
677 Views

Hello Alessandro,

Have you tried to use (5401+8)/8 as dstStep? how was the result?

Right, the ippiConvert request that Dst image is a bitonal image (monochrome image), 1bit per pixel. So the dstStep should be at least (5401+7)/8.

Or if you alloc the monochrome image with 32 bytes row align, thenthe dstStepmaybe ((5401+7)/8+31)/32.

Kind Regards,
Ying
0 Kudos
alessandroferrucci
677 Views
Quoting - Ying H (Intel)

Hello Alessandro,

Have you tried to use (5401+8)/8 as dstStep? how was the result?

Right, the ippiConvert request that Dst image is a bitonal image (monochrome image), 1bit per pixel. So the dstStep should be at least (5401+7)/8.

Or if you alloc the monochrome image with 32 bytes row align, thenthe dstStepmaybe ((5401+7)/8+31)/32.

Kind Regards,
Ying

Hi Ying,

thank you very much for response. I have tried both methods to calculate the Step count for the Binary CIppImage and neither provided me results I expected.

This is entire flow of code:
CIppImage image;
CIppImage grayscale_image;
CIppImage monochrome_image;
ReadImageJPEG(in,m_param_jpeg,image);
image.ToGray(grayscale_image);
IppiSize roiSize={grayscale_image.Width(),grayscale_image.Height()};

//I just throught about this..but is this incorrect?
// wouldn't roisize be 1/8 on the width and some other
//number for the width? since we are bit-packing the pixels
//1 per bit?? is this Alloc call incorrect?
monochrome_image.Alloc( roiSize, 1, 8);

ippiConvert_8u1u_C1R((const Ipp8u*)grayscale_image.DataPtr(),grayscale_image.Step(),(Ipp8u*)monochrome_image,monochrome_image.Step(),0,roiSize,(Ipp8u)160);

CStdFileOutput fo;

fo.Open("C:\bitonal.jpg");

SaveImageJPEG(monochrome_image, m_param_jpeg, fo);

fo.Close();


Note my Alloc call for the monochrome image...is that incorrect? Should the image be a roisize given that we're packing 8 pixels per bit??
0 Kudos
Vladimir_Dudnik
Employee
677 Views
Your problem might be the way how you store bitonal image. I think JPEG standard only support lossless compression mode for 2..16 bits images.

Regards,
Vladimir
0 Kudos
alessandroferrucci
677 Views
Your problem might be the way how you store bitonal image. I think JPEG standard only support lossless compression mode for 2..16 bits images.

Regards,
Vladimir

When I Alloc a bitonal image, is the ROI units in bytes or pixels? Meaning if I have a 500x500 pixel image and I want to alloc a bitonal would it be

IppiSize myRoi = {500/8, 500};
CIppImage mono;
mono.Alloc(myRoi, 1,8);

or

IppiSize myRoi = {500, 500};
CIppImage mono;
mono.Alloc(myRoi, 1,8);

I think it's the first, since I don't know how IPP would know to bitpack the pixels in the bytes with a 500,500 ROI.

thanks
0 Kudos
alessandroferrucci
677 Views
Your problem might be the way how you store bitonal image. I think JPEG standard only support lossless compression mode for 2..16 bits images.

Regards,
Vladimir

Hello Ying and Vladimir.. thank you for your assistance in this matter, however I was unable to get ippiConvert_8u1u_C1R to work correctly so I implemented my own.

Thanks again.

Regards,

Alessandro Ferrucci
0 Kudos
Ying_H_Intel
Employee
677 Views

Hello Alessandro,

I saw your sourcecode have the class CIppImage and function Alloc().Arethey fromIPPimage processing sample code or you createthem by yourself?

If you are seeing the IPPimage processing sample code at http://software.intel.com/en-us/articles/intel-integrated-performance-primitives-code-samples/. then it actually includes one ippiConvert_8u1u_C1R sample. andyoucan easily check it's function by the ippiDemo.exe in your IPP install directory.

For example, the below screencopy is I convert one 567x372 gray image. And the result image is 71x372. Is that what your expected, right? (The bitonal image is shown in bytes in the image, so squished. what tools do you use to show bitonal image?)

ifboth thegray and monchrome image are allocatedbased onthe IPPsample,then
the standardcall
monochrome_image.Alloc( grayscale_image.Size(), 1, m_image.Precision() );
//width: 5104, Height: 2204
IppiSize roiSize={grayscale_image.Width(),grayscale_image.Height()};

mystatus = ippiConvert_8u1u_C1R(
(const Ipp8u*)grayscale_image.DataPtr(),grayscale_image.Step(),
(Ipp8u*)monochrome_image,monochrome_image.Step(),0,roiSize,(Ipp8u)148);
should be right. But the result imageoccupy only the first 71 colum (bytes)and other parts is blank.

if you'd like to see the result imae is all packed pixel without blank pixel,
then, you can define,
IppiSize myRoi = {(iWidth+7)/8, iHeight};
CIppImage mono;
mono.Alloc(myRoi, 1,8);
and
call mystatus = ippiConvert_8u1u_C1R(
(const Ipp8u*)grayscale_image.DataPtr(),grayscale_image.Step(),
(Ipp8u*)monochrome_image,monochrome_image.Step(),0,roiSize,(Ipp8u)148);

Please note, always use the monochrome_image.Step() here, thus you don't need take care of the exact step.
( for example, here ifyour image is4 byte aligned , thengrayscla_image.Step is 568 and monochrome_image.Step() is 72


Best Regards,
Ying
0 Kudos
alessandroferrucci
677 Views
Quoting - Ying H (Intel)

Hello Alessandro,

I saw your sourcecode have the class CIppImage and function Alloc().Arethey fromIPPimage processing sample code or you createthem by yourself?

If you are seeing the IPPimage processing sample code at http://software.intel.com/en-us/articles/intel-integrated-performance-primitives-code-samples/. then it actually includes one ippiConvert_8u1u_C1R sample. andyoucan easily check it's function by the ippiDemo.exe in your IPP install directory.

For example, the below screencopy is I convert one 567x372 gray image. And the result image is 71x372. Is that what your expected, right? (The bitonal image is shown in bytes in the image, so squished. what tools do you use to show bitonal image?)

ifboth thegray and monchrome image are allocatedbased onthe IPPsample,then
the standardcall
monochrome_image.Alloc( grayscale_image.Size(), 1, m_image.Precision() );
//width: 5104, Height: 2204
IppiSize roiSize={grayscale_image.Width(),grayscale_image.Height()};

mystatus = ippiConvert_8u1u_C1R(
(const Ipp8u*)grayscale_image.DataPtr(),grayscale_image.Step(),
(Ipp8u*)monochrome_image,monochrome_image.Step(),0,roiSize,(Ipp8u)148);
should be right. But the result imageoccupy only the first 71 colum (bytes)and other parts is blank.

if you'd like to see the result imae is all packed pixel without blank pixel,
then, you can define,
IppiSize myRoi = {(iWidth+7)/8, iHeight};
CIppImage mono;
mono.Alloc(myRoi, 1,8);
and
call mystatus = ippiConvert_8u1u_C1R(
(const Ipp8u*)grayscale_image.DataPtr(),grayscale_image.Step(),
(Ipp8u*)monochrome_image,monochrome_image.Step(),0,roiSize,(Ipp8u)148);

Please note, always use the monochrome_image.Step() here, thus you don't need take care of the exact step.
( for example, here ifyour image is4 byte aligned , thengrayscla_image.Step is 568 and monochrome_image.Step() is 72


Best Regards,
Ying

Hello Ying,
turns out I had it right and I was not using correct method of encoding image. I was encoding using LOSSLESS JPEG compression and assumed that the JPEG viewer would tread bitpacked image correctly (unfolding bits to be individual pixels). I have since modified this to encoding buffer to CCITT_T6 encoded TIFF and it works (I used libtiff). I have question though. something weird happens. I use pretty much exact code as you put there. I convert image using convert_8u1u_C1R and then encode using libtiff. the image shows fine and it's bitonal HOWEVER, the image colors are **ALWAYS** inverted, blacks are whites and blacks are where whites are supposed to be (no matter if I put MIN_IS_BLACK or MIN_IS_WHITE, when encoding. My own binarizing method works fine when I use that to create bitonal buffer and encode it). Does convert operation use 0 or 1 for white? Also I'm assuming that Convert function treat pixels in order Most Significant to Least Significant?

Thank you.

Alessandro Ferrucci
0 Kudos
Ying_H_Intel
Employee
677 Views

Hello Ying,
turns out I had it right and I was not using correct method of encoding image. I was encoding using LOSSLESS JPEG compression and assumed that the JPEG viewer would tread bitpacked image correctly (unfolding bits to be individual pixels). I have since modified this to encoding buffer to CCITT_T6 encoded TIFF and it works (I used libtiff). I have question though. something weird happens. I use pretty much exact code as you put there. I convert image using convert_8u1u_C1R and then encode using libtiff. the image shows fine and it's bitonal HOWEVER, the image colors are **ALWAYS** inverted, blacks are whites and blacks are where whites are supposed to be (no matter if I put MIN_IS_BLACK or MIN_IS_WHITE, when encoding. My own binarizing method works fine when I use that to create bitonal buffer and encode it). Does convert operation use 0 or 1 for white? Also I'm assuming that Convert function treat pixels in order Most Significant to Least Significant?

Thank you.

Alessandro Ferrucci
Alessandro,
As to ippiConvert_8u1u itself, it use 1 for white. 0 for black as the above image (255->1).
Regards,
Ying
0 Kudos
Reply