Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
13 Views

Universal pyramid help

Hi,

I am trying to use the Universal pyramid functions to decompose and reconstruct a Gaussian as well as Laplacian pyramids (for image contrast/sharpness enhancement purposes). Before I actually implement the Laplacian pyramid, I wanted to decompose and reconstruct a Gaussian pyramid and test if the image reconstructs correctly.

The pyramid decomposition gives me the correct images for all levels i use, however, the reconstruction loop only reconstructs part of the image - IF the ROI provided is not square but a rectangle. For a square ROI the reconstruction works fine. Is this a limitation of the PyramidLayerUp function or is there a problem in my code that I cannot catch?

I followed the example given at the end of the Universal Pyramid section in the manual. I am using the following code for my testing:

IppiPyramid *gPyr; // pointer to Gaussian down pyramid structure
IppiPyramid *gUpPyr; // pointer to Gaussian Up pyramid structure

// allocate pyramid structures
Ipp32f rate = 2;
ippiPyramidInitAlloc (&gPyr, 3, srcRoi, rate);
ippiPyramidInitAlloc (&gUpPyr, 3, srcRoi, rate);

IppiPyramidDownState_32f_C1R **gState = (IppiPyramidDownState_32f_C1R**)&(gPyr->pState);

IppiPyramidUpState_32f_C1R **gUpState = (IppiPyramidUpState_32f_C1R**)&(gUpPyr->pState);

Ipp32f **gImage = (Ipp32f**)(gPyr->pImage);
IppiSize *pRoi = gPyr->pRoi;
int *gStep = gPyr->pStep;
int level = gPyr->level;
Ipp32f **gUpImage = (Ipp32f**)(gUpPyr->pImage);
int *gUpStep = gUpPyr->pStep;

// allocate structures to calculate pyramid layers
int mode = IPPI_INTER_LINEAR;

ippiPyramidLayerDownInitAlloc_32f_C1R(gState, srcRoi, rate, pKernel, kerSize, mode);

ippiPyramidLayerUpInitAlloc_32f_C1R (gUpState, srcRoi, rate, pKernel, kerSize, mode);

// build Gaussian pyramid with level+1 layers
gImage[0] = pSrc;
gStep[0] = srcStep;
for (int i=1; i<=level; i++)
{
gImage = ippiMalloc_32f_C1(pRoi.width,pRoi.height,gStep+i);

ippiPyramidLayerDown_32f_C1R(gImage[i-1], gStep[i-1], pRoi[i-1],
gImage, gStep, pRoi, *gState);

}

// build Gaussian UP pyramid with level layers
for (int i=level-1; i>=0; i--)
{
gUpImage = ippiMalloc_32f_C1(pRoi.width,pRoi.height,gUpStep+i);

resultStats = ippiPyramidLayerUp_32f_C1R(gImage[i+1], gStep[i+1], pRoi[i+1], gUpImage, gUpStep, pRoi, *gUpState);

}

ippiPyramidLayerDownFree_32f_C1R(*gState);
ippiPyramidLayerUpFree_32f_C1R (*gUpState);

// free allocated images
for (int i=1; i<=level; i++)
{
ippiFree(gImage);
ippiFree(gUpImage[i-1]);
}

// free pyramid structures
ippiPyramidFree (gPyr);
ippiPyramidFree (gUpPyr);

Please review and let me know if I am doing something wrong or if this is a l imitation of the function.

Thanks.

Mittal
0 Kudos
4 Replies
Highlighted
Employee
13 Views

Hello,

I reviewed your code and it looks good. However, I could not reproduce the problem with IPP 5.3. Thus, it is either a problem in an ealier version of IPP, or a bug somewhere outside this code (for example, check if srcRoi is set correctly).
Below is the complete sample, based on your code, that I ran with a few different images.
It is for MS Visual Studio, but it should not be difficult to adapt it for a different compiler or port it to Linux.

Regards,
Vadim

#include "cv.h"
#include "highgui.h"
#include "ipp.h"

#ifdef _DEBUG
#pragma comment( lib, "cvd.lib")
#pragma comment( lib, "cxcored.lib")
#pragma comment( lib, "highguid.lib")
#else
#pragma comment( lib, "cv.lib")
#pragma comment( lib, "cxcore.lib")
#pragma comment( lib, "highgui.lib")
#endif

#pragma comment( lib, "ippcore.lib")
#pragma comment( lib, "ippcv.lib")
#pragma comment( lib, "ippi.lib")
#pragma comment( lib, "ipps.lib")

void main(void)
{
IplImage* src = cvLoadImage( "C:/User/VP/Pictures/Art/Pics/DiagonalSand.jpg", 0 );
IplImage* srcf = cvCreateImage( cvGetSize(src), IPL_DEPTH_32F, 1 );
cvConvertScale( src, srcf, 1./255 );

IppStatus resultStats;
Ipp32f* pSrc = (Ipp32f*)srcf->imageData;
int srcStep = srcf->widthStep;
IppiSize srcRoi = { srcf->width, srcf->height };
const int kerSize = 7;
Ipp32f pKernel[kerSize];
CvMat _kernel = cvMat( 1, kerSize, CV_32F, pKernel );
CvSepFilter::init_gaussian_kernel( &_kernel, 1.5 );
cvNamedWindow( "layer", 1 );

IppiPyramid *gPyr; // pointer to Gaussian down pyramid structure
IppiPyramid *gUpPyr; // pointer to Gaussian Up pyramid structure

// allocate pyramid structures
Ipp32f rate = 2;
ippiPyramidInitAlloc (&gPyr, 3, srcRoi, rate);
ippiPyramidInitAlloc (&gUpPyr, 3, srcRoi, rate);

IppiPyramidDownState_32f_C1R **gState = (IppiPyramidDownState_32f_C1R**)&(gPyr->pState);
IppiPyramidUpState_32f_C1R **gUpState = (IppiPyramidUpState_32f_C1R**)&(gUpPyr->pState);

Ipp32f **gImage = (Ipp32f**)(gPyr->pImage);
IppiSize *pRoi = gPyr->pRoi;
int *gStep = gPyr->pStep;
int level = gPyr->level;
Ipp32f **gUpImage = (Ipp32f**)(gUpPyr->pImage);
int *gUpStep = gUpPyr->pStep;

// allocate structures to calculate pyramid layers
int mode = IPPI_INTER_LINEAR;

ippiPyramidLayerDownInitAlloc_32f_C1R(gState, srcRoi, rate, pKernel, kerSize, mode);
ippiPyramidLayerUpInitAlloc_32f_C1R (gUpState, srcRoi, rate, pKernel, kerSize, mode);

// build Gaussian pyramid with level+1 layers
gImage[0] = pSrc;
gStep[0] = srcStep;
&nbs p; for (int i=1; i<=level; i++)
{
gImage = ippiMalloc_32f_C1(pRoi.width,pRoi.height,gStep+i);
resultStats = ippiPyramidLayerDown_32f_C1R(gImage[i-1], gStep[i-1], pRoi[i-1],
gImage, gStep, pRoi, *gState);
assert( resultStats >= 0 );
{
CvMat tmp;
cvInitMatHeader( &tmp, pRoi.height, pRoi.width, CV_32F, gImage, gStep );
cvShowImage( "layer", &tmp );
cvWaitKey(0);
}
}

// build Gaussian UP pyramid with level layers
for (int i=level-1; i>=0; i--)
{
gUpImage = ippiMalloc_32f_C1(pRoi.width,pRoi.height,gUpStep+i);
resultStats = ippiPyramidLayerUp_32f_C1R(gImage[i+1], gStep[i+1], pRoi[i+1], gUpImage, gUpStep, pRoi, *gUpState);
assert( resultStats >= 0 );
{
CvMat tmp;
cvInitMatHeader( &tmp, pRoi.height, pRoi.width, CV_32F, gImage, gStep );
cvShowImage( "layer", &tmp );
cvWaitKey(0);
}
}

ippiPyramidLayerDownFree_32f_C1R(*gState);
ippiPyramidLayerUpFree_32f_C1R (*gUpState);

// free allocated images
for (int i=1; i<=level; i++)
{
ippiFree(gImage);
ippiFree(gUpImage[i-1]);
}

// free pyramid structures
ippiPyramidFree (gPyr);
ippiPyramidFree (gUpPyr);
}

0 Kudos
Highlighted
Beginner
13 Views

Hi,

I'm new to IPP and I want to implement Gaussian-Laplacian Pyramid decomposition/reconstruction. So I use the code here and make some revision to build a Gaussian pyramid and a Laplacian pyramid. I expect to get an identical image of the original after reconstruction, but the image I get is
quite diffrent.

I try to use ippiPyrDown_Gauss5x5_32f_C1R/ippiPyrUp_Gauss5x5_32f_C1R and ippiPyrDown_Gauss5x5_8u_C1R/ippiPyrUp_Gauss5x5_8u_C1R instead to build the pyramids from 32-bit float image and 8-bit unsigned image respectively, but the results are almost the same.

I'm wondering if there something wrong with the approach I get the Laplacian image, or this problem is due to the precision loss in the computation.

Please look through the following code to find the reason for me.

Thanks!


******************************************************************************************************

#include "cv.h"
#include "highgui.h"
#include "ipp.h"

#pragma comment( lib, "cv.lib")
#pragma comment( lib, "cxcore.lib")
#pragma comment( lib, "highgui.lib")

#pragma comment( lib, "ippcore.lib")
#pragma comment( lib, "ippcv.lib")
#pragma comment( lib, "ippi.lib")
#pragma comment( lib, "ipps.lib")

void ShowImage(IppiSize size, Ipp32f *image, int width_step)
{
static count = 0;
char title[256];
CvMat tmp;
cvInitMatHeader( &tmp, size.height, size.width, CV_32F, image, width_step );
sprintf(title, "image #%d", count++);
cvNamedWindow( title, 1 );
cvShowImage( title, &tmp );
cvWaitKey(0);
}

int main(int argc, char *argv[])
{
IplImage* src = cvLoadImage( "lena.jpg", 0 );
IplImage* srcf = cvCreateImage( cvGetSize(src), IPL_DEPTH_32F, 1 );
cvConvertScale( src, srcf, 1./255 );

IppStatus resultStats;
Ipp32f* pSrc = (Ipp32f*)srcf->imageData;
int srcStep = srcf->widthStep;
IppiSize srcRoi = { srcf->width, srcf->height };
const int kerSize = 7;
Ipp32f pKernel[kerSize];
CvMat _kernel = cvMat( 1, kerSize, CV_32F, pKernel );
CvSepFilter::init_gaussian_kernel( &_kernel, 1.5 );

IppiPyramid *gPyr; // pointer to Gaussian down pyramid structure
IppiPyramid *lPyr; // pointer to Laplacian pyramid structure

// allocate pyramid structures
Ipp32f rate = 2;
int layers = 3;
ippiPyramidInitAlloc (&gPyr, layers, srcRoi, rate);
ippiPyramidInitAlloc (&lPyr, layers, srcRoi, rate);

IppiPyramidDownState_32f_C1R **gState = (IppiPyramidDownState_32f_C1R**)&(gPyr->pState);
IppiPyramidUpState_32f_C1R **lState = (IppiPyramidUpState_32f_C1R**)&(lPyr->pState);

Ipp32f **gImage = (Ipp32f**)(gPyr->pImage);
IppiSize *pRoi = gPyr->pRoi;
in t *gStep = gPyr->pStep;
int level = gPyr->level;

Ipp32f **lImage = (Ipp32f**)(lPyr->pImage);
int *lStep = lPyr->pStep;

// allocate structures to calculate pyramid layers
int mode = IPPI_INTER_LINEAR;

ippiPyramidLayerDownInitAlloc_32f_C1R(gState, srcRoi, rate, pKernel, kerSize, mode);
ippiPyramidLayerUpInitAlloc_32f_C1R(lState, srcRoi, rate, pKernel, kerSize, mode);

// build Gaussian pyramid with level+1 layers
gImage[0] = pSrc;
gStep[0] = srcStep;

int i = 0, nStep;
Ipp32f *ptr = ippiMalloc_32f_C1(srcRoi.width, srcRoi.height, &nStep);

ShowImage(pRoi, gImage, gStep);
for (i=1; i<=level; i++)
{
gImage = ippiMalloc_32f_C1(pRoi.width, pRoi.height, gStep+i);
resultStats = ippiPyramidLayerDown_32f_C1R(gImage[i-1], gStep[i-1], pRoi[i-1],
gImage, gStep, pRoi, *gState);
ShowImage(pRoi, gImage, gStep);

lImage[i-1] = ippiMalloc_32f_C1(pRoi[i-1].width, pRoi[i-1].height, lStep+i-1);
resultStats = ippiPyramidLayerUp_32f_C1R(gImage, gStep, pRoi,
ptr, nStep, pRoi[i-1], *lState);
// build Laplacian pyramid
ippiSub_32f_C1R(gImage[i-1], gStep[i-1],
ptr, nStep, lImage[i-1], lStep[i-1], pRoi[i-1]);
ShowImage(pRoi[i-1], lImage[i-1], lStep[i-1]);
}

// reconstruction
for (i=level; i>0; i--)
{
resultStats = ippiPyramidLayerUp_32f_C1R(gImage, gStep, pRoi,
ptr, nStep, pRoi[i-1], *lState);
ShowImage(pRoi[i-1], ptr, nStep);
ippiAdd_32f_C1R(ptr, nStep, lImage[i-1], lStep[i-1], gImage[i-1], gStep[i-1], pRoi[i-1]);
ShowImage(pRoi[i-1], gImage[i-1], gStep[i-1]);
}

ippiFree(ptr);

ippiPyramidLayerDownFree_32f_C1R(*gState);
ippiPyramidLayerUpFree_32f_C1R(*lState);

for (i=1; i<=level; i++)
{
ippiFree(gImage);
ippiFree(lImage[i-1]);
}

ippiPyramidFree (gPyr);
ippiPyramidFree (lPyr);

return 0;
}
0 Kudos
Highlighted
Beginner
13 Views

Hi, all

The problem is caused by mistake in

ippiSub_32f_C1R(gImage[i-1], gStep[i-1],
ptr, nStep, lImage[i-1], lStep[i-1], pRoi[i-1]);

which should be

ippiSub_32f_C1R(ptr, nStep,
gImage[i-1], gStep[i-1], lImage[i-1], lStep[i-1], pRoi[i-1]);


0 Kudos
Highlighted
Beginner
13 Views

Hi, all

The problem is caused by mistake in

ippiSub_32f_C1R(gImage[i-1], gStep[i-1],
ptr, nStep, lImage[i-1], lStep[i-1], pRoi[i-1]);

which should be

ippiSub_32f_C1R(ptr, nStep,
gImage[i-1], gStep[i-1], lImage[i-1], lStep[i-1], pRoi[i-1]);


0 Kudos