- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, I have some problems width canny edge detector using IPP
I make three steps:
I have 3-channel image(byte array), that ordered like this RGBRGB...
The first step is applying grayScale filter.
The second is calculation gradients dx and dy using IPP vertical and horizontal Sobel filters with border,
The last step is using ippiCanny
Code:
unsigned char * RGBToGrayScaleIpp(unsigned char * src, int width, int height, int channels)
{
IppiSize ROI = {width, height};
Ipp8u *GrayScaleImg = new Ipp8u[width * height];
ippiRGBToGray_8u_C3C1R(src, width * channels * sizeof(Ipp8u), GrayScaleImg, width * sizeof(Ipp8u), ROI);
return GrayScaleImg;
}
extern "C" __declspec(dllexport) unsigned char* __stdcall Canny(unsigned char * img, int channels, int width, int height)
{
Ipp8u *GrayScaleImg = RGBToGrayScaleIpp(img, width, height, channels);
IppiSize roiSize = {width - 1, height - 1};
int horizBufferSize, vertBufferSize;
IppiMaskSize maskSize = ippMskSize3x3;
ippiFilterSobelVertGetBufferSize_8u16s_C1R(roiSize, maskSize, &vertBufferSize);
ippiFilterSobelHorizGetBufferSize_8u16s_C1R(roiSize, maskSize, &horizBufferSize);
Ipp8u *horizBuffer = ippsMalloc_8u(horizBufferSize);
Ipp8u *vertBuffer = ippsMalloc_8u(vertBufferSize);
Ipp16s *dx = new Ipp16s[width * height];
Ipp16s *dy = new Ipp16s[width * height];
ippiFilterSobelVertBorder_8u16s_C1R(GrayScaleImg, width * sizeof(Ipp8u), dx, (width - 1) * sizeof(Ipp16s), roiSize, maskSize, ippBorderRepl, 0, vertBuffer);
ippiFilterSobelHorizBorder_8u16s_C1R(GrayScaleImg, width * sizeof(Ipp8u), dy, (width - 1) * sizeof(Ipp16s), roiSize, maskSize, ippBorderRepl, 0, horizBuffer);
Ipp8u *buffer;
if (vertBufferSize < horizBufferSize)
{
ippiCannyGetSize(roiSize, &horizBufferSize);
buffer = ippsMalloc_8u(horizBufferSize);
}
else
{
ippiCannyGetSize(roiSize, &vertBufferSize);
buffer = ippsMalloc_8u(vertBufferSize);
}
Ipp32f low=100.0f, high=100.0f;
Ipp8u* dst = new Ipp8u[width * height];
ippiCanny_16s8u_C1R(dx, (width - 1) * sizeof(Ipp16s), dy, (width - 1) * sizeof(Ipp16s), dst, width * sizeof(Ipp8u), roiSize, low, high, buffer);
ippsFree(buffer);
return dst;
}
I get incorrect result. In attach files there are 3 images source, filtered using .NET Aforge and filtered using IPP. Can you see any mistakes in my code? Please, help.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Alexandr,
in the latest IPP versions you can find more advanced function:
/*F///////////////////////////////////////////////////////////////////////////////////////
// Name: ippiCannyBorder_8u_C1R
// Purpose: Perform convolution operation with fixed kernels 3x3 and 5x5 and creates binary image of source's image edges,
// using derivatives of the first order.
// Parameters:
// pSrc The pointer to the source image
// srcStep The step in the source image
// pDst The pointer to the destination image
// dstStep The step in the destination image
// roiSize The image ROI size
// filterType the filter type(ippFilterSobel,ippFilterScharr)
// mask The mask size(ippMskSize3x3,ippMskSize5x5)
// borderType Type of border. Possible values are:
// ippBorderConst Values of all border pixels are set to constant.
// ippBorderRepl Border is replicated from the edge pixels.
// ippBorderInMem Border is obtained from the source image pixels in memory.
// Mixed borders are also supported. They can be obtained by the bitwise operation OR between ippBorderRepl and ippBorderInMemTop, ippBorderInMemBottom, ippBorderInMemLeft, ippBorderInMemRight.
// borderValue The value for the constant border
// lowThresh Low threshold for edges detection
// highThresh Upper threshold for edges detection
// norm Norm type (ippNormL1,ippNormL2)
// pBuffer Pointer to the pre-allocated temporary buffer, which size can be
// calculated using ippiCannyEdgeDetectionGetSize function
// Return:
// ippStsNoErr Ok
// ippStsNullPtrErr One of pointers is NULL
// ippStsSizeErr The width or height of images is less or equal zero
// ippStsNotEvenStepErr Step is not multiple of element.
// ippStsBadArgErr Bad thresholds
//
//F*/
IPPAPI(IppStatus, ippiCannyBorder_8u_C1R,( const Ipp8u* pSrc, int srcStep, Ipp8u* pDst, int dstStep, IppiSize roiSize,
IppiDifferentialKernel filterType, IppiMaskSize mask,IppiBorderType borderType, Ipp8u borderValue,
Ipp32f lowThresh, Ipp32f highThresh, IppNormType norm,Ipp8u* pBuffer ))
/*F///////////////////////////////////////////////////////////////////////////////////////
// Name: ippiCannyBorderGetSize
//
// Purpose: Calculates size of temporary buffer, required to run ippiCannyBorder_8u_C1R function.
// Parameters:
// roiSize Size of image ROI in pixel
// filterType The filter type(ippFilterSobel,ippFilterScharr)
// mask The mask size(ippMskSize3x3,ippMskSize5x5)
// dataType Data type of the image. Possible values are Ipp8u, Ipp16u, Ipp16s, or Ipp32f.
// pBufferSize Pointer to the variable that returns the size of the temporary buffer
//
// Return:
// ippStsNoErr Ok
// ippStsNullPtrErr Pointer bufferSize is NULL
// ippStsMaskSizeErr Indicates an error when mask has an illegal value.
// ippStsDataTypeErr Indicates an error when dataType has an illegal value.
// ippStsSizeErr roiSize has a field with zero or negative value
//
//F*/
IPPAPI(IppStatus, ippiCannyBorderGetSize,( IppiSize roiSize, IppiDifferentialKernel filterType,IppiMaskSize mask, IppDataType dataType, int* pBufferSize ))
And I can't find any attachments...
regards, Igor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
one more thing: I don't understand your manipulations with "width" - if you have allocated image of width*height, you can't use " (width - 1) * sizeof(Ipp16s)" as a step - you can set any roi inside this image (for example (width-N)x(height-M)), but image step still is == width...
regards, Igor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Igor, thanks for your answer
I rewrote the code like this:
Ipp8u *GrayScaleImg = RGBToGrayScaleIpp(img, width, height, channels);
Ipp8u* pBuffer = 0;
int bufferSize;
IppiSize roiSize = {width, height};
IppiDifferentialKernel filterType = ippFilterSobel;
ippiCannyBorderGetSize( roiSize, filterType,ippMskSize3x3, ipp8u, &bufferSize);
pBuffer = ippsMalloc_8u( bufferSize );
Ipp32f low = 100.0f, high = 100.0f;
ippiCannyBorder_8u_C1R(GrayScaleImg, width, GrayScaleImg, width, roiSize, filterType, ippMskSize3x3, ippBorderRepl,0, low, high, ippNormL2, pBuffer);
ippsFree(pBuffer);
but I have almost the same result, and I did not understand what values should take "src step", "dst step " and "roi size" in my case.
regards, Alexandr
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Alexander,
Check this document on the step, ROI for image function:
https://software.intel.com/en-us/node/503725
Thanks,
Chao
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Chao,
thanks for your response, I solved the problem
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page