Need only one edge in Canny edge algorithm
Asked Answered
C

1

7

When i use the canny edge algorithm, it produces the 2 edges opposite the thick colored line as expected, but i want only one edge to be displayed so as to make my line and curve detection algorithm much less complicated, any ideas on how i can make that happen ?

enter image description here

Here is the code :

bool CannyEdgeDetection(DataStructure& col)
{

Mat src, src_gray;
Mat dst, detected_edges, fin;
int WhiteCount = 0, BCount = 0;

char  szFil1[32] = "ocv.bmp";
char  szFil2[32] = "dst.bmp";
src = imread(szFil1);
dst = imread(szFil1);
blur( src_gray, detected_edges, Size(3,3) );
Canny( src, dst, 100, 200, 3 );
imwrite(szFil2, dst );

IplImage* img = cvLoadImage(szFil2);
int height    = img->height;
int width     = img->width;
int step      = img->widthStep;
int channels  = img->nChannels;
uchar * datau      = (uchar *)img->imageData;

for(int i=0;i<height;i++){
for(int j=0;j<width;j++){
for(int k=0;k<channels;k++){
datau[i*step+j*channels+k] = 255 - datau[i*step+j*channels+k];   
if (datau[i*step+j*channels+k]==0){
WhiteCount++;
col.pixel_col [i][j] = 2;
}
else{BCount++;
col.pixel_col[i][j] = 0;
}
}
}
}

cvSaveImage("img.bmp" ,img);

return 0;

}

This is not the original image but similar :

enter image description here

Which part do i comment out to be able to read black images in white backgrounds ? or any colored image ?

bool done;
do
{
  cv::morphologyEx(img, temp, cv::MORPH_OPEN, element);
  cv::bitwise_not(temp, temp);
  cv::bitwise_and(img, temp, temp);
  cv::bitwise_or(skel, temp, skel);
  cv::erode(img, img, element);

  double max;
  cv::minMaxLoc(img, 0, &max);
  done = (max == 0);
} while (!done);
Confederate answered 15/7, 2012 at 14:5 Comment(3)
What have you tried so far? Can you post some code? Or at least the input image?Salado
can you upload a link to your original image? May be other people can provide better methods.Lord
The dumb-simple method to do it is to resize the image - make it small enough that the edges will be 1-2 pixels. You will have both 1-pixel canny edges and an instant performance boost.Saber
L
3

That process is called skeletonization or thinning. You can google for that.

Here is a simple method for skeletonization : skeletonization OpenCV In C#

Below is the output I got when applied above method to your image ( Image is inverted before skeletonization because above method work for white images in black background, just opposite case of your input image).

enter image description here

Lord answered 15/7, 2012 at 14:8 Comment(10)
This looks really useful, why isn't skeletonization prefered to canny in image processing ( i'm assuming this because i have not heard of this at all )Confederate
I am not sure about it, but canny edge detection is commonly used, and also skeletonization is still a developing approach, more methods are being prepared day-by-day (the approach in my answer is not so good). Any way I haven't used skeletonization yet.Lord
that's impressive! but would it work if you didn't know the color of the image or background ?Confederate
I am not sure of it. May be checking amount of white and black pixels before thinning and decide whether to invert or not, may work since normally background has more area than foreground.Lord
i've got it working too.. but i don't want to invert it. which should i comment out ( not, and, or ) ?Confederate
If you got it working, why should you comment out any line? I don't get your question.Lord
beacuse i've inverted the image in paint and then applied the algorithm, otherwise it wouldn't workConfederate
you need not invert the image so. You can use cv2.bitwise_not() function to invert the image programmatically.Lord
i've posted the code above, with the bitwise_not function it does not produce any output, but when i invert the image in paint and then run the program it worksConfederate
Not there, you should invert image at the beginning of the full code, just after loading the image. pastebin.com/e91gX57tLord

© 2022 - 2024 — McMap. All rights reserved.