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

Canny Edge Detector

Alexandr_S_1
Beginner
467 Views

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.

 

0 Kudos
5 Replies
Igor_A_Intel
Employee
467 Views

Hi Alexandr,

Is it legitimate work? I see pictures now and I see that you are trying to analyze some capture... It is clear from "ipp" picture that my 1st diagnose is correct - I see some mess with scan lines because of bad image step definition.

regards, Igor

0 Kudos
Alexandr_S_1
Beginner
467 Views

I'm working on handwriting recognition, and in plain text, or geometric figures ippiCanny works correctly, and complex text, such as a capture(it is easier to generate a lot of captures that scan a lot of text), ippiCanny does not work properly2.jpg

res.jpg

0 Kudos
Igor_A_Intel
Employee
467 Views

This code works fine, result images attached,

int main( int argc, char **argv )

{

int k, tmpStep;

FILE *f1, *w;

tImage img1, img2;

IppStatus status = ippStsNoErr;

IppiSize roi;

IppiMaskSize mask;

Ipp8u *src, *tmp, *tmp1, *pBuffer;

if( argc < 2 ){

printf("\nusage: cannydemo <FileName.bmp> [masksize]\n");

return 1;

}

if (argc > 2){

if (sscanf(argv[2], "%d", &k) <= 0){

printf("\nmask size <%s> is invalid\n", argv[2]);

return 1;

}

}

else {

k = 3;

}

if( argc > 3 ){

printf("\nusage: cannydemo <FileName.bmp> [masksize]\n");

return 1;

}

f1 = fopen( argv[1], "rb" );

w = fopen("my.bmp", "wb");

if (NULL == f1){

printf("\nfile %s not found\n", argv[1] );

return 1;

}

if (3 == k)

mask = ippMskSize3x3;

else

mask = ippMskSize5x5;

img1.infohdr = NULL;

img1.data = NULL ;

if( readBMP( f1, w, &img1 )){

ippsFree( img1.infohdr );

ippsFree( img1.data );

return 1;

}

roi.width = img1.infohdr->biWidth;

roi.height = img1.infohdr->biHeight;

if(( roi.width <= 0 )||( roi.height <= 0 )){

printf("\nError: bad image.\n");

ippsFree( img1.infohdr );

ippsFree( img1.data );

return 1;

}

src = img1.data;

libInfo();

printf("Image info: %ld x %ld, number of channels = %d\n",

img1.infohdr->biWidth, img1.infohdr->biHeight, img1.nchan );

img2.data = ippsMalloc_8u( img1.infohdr->biSizeImage );

ippsCopy_8u( img1.data, img2.data, img1.infohdr->biSizeImage );

tmp = ippiMalloc_8u_C1(roi.width, roi.height, &tmpStep);

tmp1 = ippiMalloc_8u_C1(roi.width, roi.height, &tmpStep);

 

switch (img1.infohdr->biBitCount){

case 8:

ippiCopy_8u_C1R( src, img1.step, tmp, tmpStep, roi );

break;

case 16:

printf( "\nUnsupported bmp pixel format.\n" );

ippsFree( img1.infohdr );

ippsFree( img1.data );

return 1;

case 24:

ippiRGBToGray_8u_C3C1R(src, img1.step, tmp, tmpStep, roi);

break;

case 32:

printf( "\nUnsupported bmp pixel format.\n" );

ippsFree( img1.infohdr );

ippsFree( img1.data );

return 1;

}

ippiCannyBorderGetSize( roi, ippFilterSobel, mask, ipp8u, &k );

pBuffer = ippsMalloc_8u( k );

status = ippiCannyBorder_8u_C1R(tmp, tmpStep, tmp1, tmpStep, roi, ippFilterSobel, mask, ippBorderRepl, 0,

100.f, 100.f, ippNormL1, pBuffer);

if( status != ippStsNoErr ){

ippsFree( img1.infohdr );

ippsFree( img1.data ); ippsFree( img2.data );

printf( "\nippiCanny function return error status:\n %s\n",

ippGetStatusString( status ));

return 1;

}

img = &myimg;

ippsCopy_8u((Ipp8u*)&img1, (Ipp8u*)img, sizeof(img1));

switch (img1.infohdr->biBitCount){

case 8:

ippiCopy_8u_C1R(tmp1, tmpStep, img2.data, img1.step, roi);

fwrite(img2.data, 1, img1.infohdr->biSizeImage, w);

break;

case 24:

ippiGrayToRGB_8u_C1C3R(tmp1, tmpStep, img2.data, img1.step, roi);

fwrite(img2.data, 1, img1.infohdr->biSizeImage, w);

}

ippsFree( img1.infohdr );

ippsFree( img1.data );

ippsFree( img2.data );

ippsFree( pBuffer );

return 0;

}

0 Kudos
Igor_A_Intel
Employee
467 Views

+ attachments

0 Kudos
Alexandr_S_1
Beginner
467 Views

Hi Igor.

Thanks for your help, now the problem is solved.

0 Kudos
Reply