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

Problem with Convert function

trlinux
Beginner
875 Views
Hi there i'm trying something like that;
Ipp16u *imgResult = 0;
Ipp8u *imgMain = 0;
IppiSize size;
size.width = 620;
size.height = 470;
imgMain = ippsMalloc_8u(620*470*4);
imgResult = ippsMalloc_16u(620*470*4);
for (int i=0; i<16; ++i) {
oss << "img";oss << i;oss << ".jpg";
image = cvLoadImage(oss.str().c_str());
oss.str("");
}
ippiCopy_8u_C3AC4R((Ipp8u *)image[0]->imageData, image[0]->widthStep, imgMain, size.width * 4, size);
start = clock();
for (int i=0; i
for (int j=3; j
*(imgMain + (i * size.width * 4 ) + j ) = 128;
}
}
iplTemp = cvCreateImage(cvSize(620,470), IPL_DEPTH_16U, 4);
ippiConvert_8u16u_AC4R(imgMain, size.width * 4, imgResult, iplTemp->widthStep, size);
cvSetData(iplTemp, (void *)imgResult, iplTemp->widthStep);
std::cout << " = " << (float)( clock() - start ) / CLOCKS_PER_SEC;
cvShowImage("test",iplTemp);
cvSaveImage("C:/test.png", iplTemp);
It's working well with imgMain i can see image and correctly saving to disk, but if i use ippiConvert it doesn't work, there is a full transparent image ... Is there any idea ? Thanks for your help ...
0 Kudos
1 Solution
Vladimir_Dudnik
Employee
875 Views
Hello,

IPP provides AC4 and C4 functions to work with 4-channel images. According IPP Reference Manual functions with 'A'descriptor do not process alpha channel in source image and do not pass alpha values to destination image. You may need to use ippiConvert_8u16u_C4R function instead.

I would recommend consideringcode like this

Ipp16u* imgResult = 0;
Ipp8u* imgMain = 0;
intm_Step;
int r_Step;
IppiSize size;

size.width = 620;
size.height = 470;

// IPP provides auxiliary functions to allocate aligned memory for 2D buffers
Ipp8u* imgMain = ippiMalloc_8u_C4(size.width, size.height,&m_Step);
Ipp16* imgResult = ippiMalloc_16u_C4(size.width, size.height,&r_Step);

... your code to load 3-channel image ...

// copy your 3-channel image to 4-channel 2D buffer, leave alpha not initialized
ippiCopy_8u_C3AC4R((Ipp8u *)image[0]->imageData, image[0]->widthStep, imgMain, size.width * 4, size);

// initialize alpha channel with constant value (need toshift imgMain pointer to desired channel)
ippiSet_8u_C4CR(128,imgMain+3,size.width*4,m_Step);

// convert all four channels from 8 bit to 16 bits
ippiConvert_8u16u_C4R(imgMain,m_Step,imgResult,r_Step,size);

... subsequent processing ...

// free allocated memory with appropriate deallocation functions
ippiFree(..)

Regards,
Vladimir

View solution in original post

0 Kudos
5 Replies
Vladimir_Dudnik
Employee
876 Views
Hello,

IPP provides AC4 and C4 functions to work with 4-channel images. According IPP Reference Manual functions with 'A'descriptor do not process alpha channel in source image and do not pass alpha values to destination image. You may need to use ippiConvert_8u16u_C4R function instead.

I would recommend consideringcode like this

Ipp16u* imgResult = 0;
Ipp8u* imgMain = 0;
intm_Step;
int r_Step;
IppiSize size;

size.width = 620;
size.height = 470;

// IPP provides auxiliary functions to allocate aligned memory for 2D buffers
Ipp8u* imgMain = ippiMalloc_8u_C4(size.width, size.height,&m_Step);
Ipp16* imgResult = ippiMalloc_16u_C4(size.width, size.height,&r_Step);

... your code to load 3-channel image ...

// copy your 3-channel image to 4-channel 2D buffer, leave alpha not initialized
ippiCopy_8u_C3AC4R((Ipp8u *)image[0]->imageData, image[0]->widthStep, imgMain, size.width * 4, size);

// initialize alpha channel with constant value (need toshift imgMain pointer to desired channel)
ippiSet_8u_C4CR(128,imgMain+3,size.width*4,m_Step);

// convert all four channels from 8 bit to 16 bits
ippiConvert_8u16u_C4R(imgMain,m_Step,imgResult,r_Step,size);

... subsequent processing ...

// free allocated memory with appropriate deallocation functions
ippiFree(..)

Regards,
Vladimir
0 Kudos
trlinux
Beginner
875 Views
Woot, thanks a lot Vladimir... as you guess i'm new on ipp i'm still digging guides, thanks for reference manual too ^^
0 Kudos
Vladimir_Dudnik
Employee
875 Views
BTW, some correction needed to code I suggested

insead of

ippiCopy_8u_C3AC4R((Ipp8u *)image[0]->imageData, image[0]->widthStep, imgMain, size.width * 4, size);

should be used

ippiCopy_8u_C3AC4R((Ipp8u *)image[0]->imageData, image[0]->widthStep, imgMain, m_Step, size);

The reason is when you allocate image memory with ippiMalloc function it will compute and return image step (aka pitch) value, which may not be equal to just width*nchannels.

Vladimir
0 Kudos
trlinux
Beginner
875 Views
Hi Vladimir, I'm trying to understand something my final code like that,
int main()
{
IplImage *iplImage = 0;
IplImage *iplTemp = 0;
Ipp16u *imgResult = 0;
Ipp8u *imgMain = 0;
IppiSize imgSize;
int m_Step;
int r_Step;
time_t start;
imgSize.width = 620;
imgSize.height = 470;
//m_Step = 2496 when i was create IPL_DEPTH_8U, 4 Channels image it was always nChannels * width = 2480 what is the difference ?
imgMain = ippiMalloc_8u_C4(imgSize.width , imgSize.height, &m_Step);
// r_Step and iplTemp->widthStep booth 4960 looks normal for me (:
imgResult = ippiMalloc_16u_C4(imgSize.width , imgSize.height, &r_Step);
//IPL_DEPTH_16U i made unsigned but data type looks char , it must be unsigned char or something wrong with opencv
iplTemp = cvCreateImage(cvSize(imgSize.width,imgSize.height), IPL_DEPTH_16U, 4);
iplImage = cvLoadImage("img0.jpg");
start = clock();
ippiCopy_8u_C3AC4R(reinterpret_cast(iplImage->imageData), iplImage->widthStep, imgMain, m_Step, imgSize);
ippiSet_8u_C4CR(128, imgMain + 3, m_Step, imgSize);
ippiConvert_8u16u_C4R(imgMain, m_Step, imgResult, r_Step, imgSize);
cvSetData(iplTemp,reinterpret_cast<void *>(imgResult), r_Step);
std::cout << "Elapsed Time = " << (float)( clock() - start ) / CLOCKS_PER_SEC;
cvShowImage("test",iplTemp);
cvSaveImage("C:/test.png", iplTemp);
cvWaitKey();
cvReleaseImage(&iplImage);
ippiFree(imgMain);
ippiFree(imgResult);
return 0;
}
PS. i'm using OpenCV just for load image from hdd and save result image to hdd, is there another way for this?
Still it's not working for 16u i see full transparent iplTemp.
Out of Content : By the way, i saw something like CIppImage , how can i use that object i think it's struct like IplImage am i right?
0 Kudos
trlinux
Beginner
875 Views
I figured out something ;
ippiSet_8u_C4CR(128, imgMain + 3, m_Step, imgSize);
is applying 4th. channel(alpha) to 128 value then it's working fine for imgMain, i can also see imgMain[3], ..[7]....[x*4+3] value of 128 correctly but after i used to ;
ippiConvert_8u16u_C4R(imgMain, m_Step, imgResult, r_Step, imgSize); or
ippiConvert_8u16u_AC4R(imgMain, m_Step, imgResult, r_Step, imgSize);

4th. alpha channel doesn't apply to imgResult, Alpha channel of imgResult with full 0, this is the reason why i see full transperent image. After converting i set alpha channel of imgResult with
ippiSet_16u_C4CR(65535,imgResult +3 , r_Step, imgSize);
it's look fine atm ...
0 Kudos
Reply