Detect edge from binary image using Canny edge detection from OpenCV - c++

I'm trying to extract the contour of some traffic signs. The images pass through several steps in order to get a good segmented image. In the final step before applying Canny method I get this image:
After applying Canny I get this image:
The algorithm performs as expected except the top left image for which returns an open contour.
So, my question is, is there any way to use Canny in a manner that the top left image returns an closed contour?

If you already have a binary image, Canny does not give much more information. Canny is useful for finding edges in grayscale images (it decides if a gradient is an edge or not), if the image is black and white, Canny will return the edges that you already have,
I think that you need to use findContours(), which depending on the parameters will return only white or black objects, with or without the holes. It also handles the edges of the image.

Image boundary conditions are problematic in most cases. In this particular case, I would try padding the original image with some extra pixels around the image. Depending on how you add those padding pixels, you should get a complete contour around the signs.

You can use Morphological Transformations before and after applying Canny Edge Detection to manipulate the result.

Related

Detecting Rectangular Shapes in edge image with OpenCV

I want to detect multiple (similar) rectangular objects in an image that have a lot of substructure within them. So, my current plan is to use gaussian blur, morphology and edge detection (Canny). After using edge detection I get this (with very low threshold parameters):
What I want in the end is the outline of the greater rectangles. See:
Currently I try to get this by using HoughLines and findContours afterwards. For this to work, I need to fiddle a lot with the threshold parameters for Canny and HoughLines.
When I get it right for one image the parameters most likely will not work for the next one (e.g. the edges in the previous image were less dominant leading to too many lines detected by the hough transformation). Another problem is that sometimes inner structures are equally or less dominant than one side of the outer edges.
I tried to use a stronger blur or morphology but at some point this blurred away the small gap between the rectangles.
Can I extract the bigger rectangles somehow else given the edge image (preferably with opencv)?
Getting the 4 corner points would be enough.

Is there a c/c++ function out there to detect circles in the edge map of an image

I have already tried OpenCV's HoughCircles (which takes grayscale images as input), which is not giving very favorable results. I want to findthe circles in the edge image because I could clean up the unnecessary edges thus reducing the scope for any confusion.
So is there a function that will find circles from the canny edges of the image?
Thanks.

Extending a contour in OpenCv

i have several contours that consist of several black regions in my image. Directly adjacent to these black regions are some brighter regions that do not belong to my contours. I want to add these brighter regions to my black region and therefor extend my contour in OpenCv.
Is there a convenient way to extend a contour? I thought about looking at intensity change from my gradient-image created with cv::Sobel and extend until the gradient changes again, meaning the intensity of pixel is going back to the neither black nor bright regions of the image.
Thanks!
Here are example images. The first picture shows the raw Image, the second the extracted Contour using Canny & findContours, the last one the Sobel-Gradient intensity Image of the same area.
I want to include the bright boundaries in the first image to the Contour.
Update: Now i've used some morphological operations on the Sobelgradients and added a contour around them (see Image below). Next step could be to find the adjacent pair of purple & red contours, but it seems very much like a waste of procession time to actually have to search for directly adjacent contours. Any better ideas?
Update 2: My solution for now is to search for morphed gradient (red) contours in a bounding box around my (purple) contours and pick the one with correct orientation & size. This works for gradient contours where the morphological operation closes the "rise" and "fall" gradient areas like in Figure 3. But it is still a bad solution for cases in which the lighted area is wider then in the image above. Any idea is still very much appreciated, thanks!
What you're trying to do is find two different features and merge them. It's not terribly difficult but you have to use multiple copies of the image to make it happen.
Make one copy, and threshold it for the dark portion
Make another copy and threshold it for the light portion
Merge both thresholded images into a new image
Apply a morphological operation like opening or closing (depending on how you threshold) This will connect nearby components
Find contours in the resultant image
Use those contours on your original image. This will work since all the images are the same size and all based off of the original.

Find the best Region of Interest after edge detection in OpenCV

I would like to apply OCR to some pictures of 7 segment displays on a wall. My strategy is the following:
Covert Img to Grayscale
Blur img to reduce false edges
Threshold the img to a binary img
Apply Canny Edge detection
Set Region of Interest (ROI) base on a pattern given by the silhouette of the number
Scale ROI and Template match the region
How to set a ROI so that my program doesn't have to look for the template through the whole image? I would like to set my ROI base on the number of edges found or something more useful if someone can help me.
I was looking into Cascade Classification and Haar but I don't know how to apply it to my problem.
Here is an image after being pre-processed and edge detected:
original Image
If this is representative of the number of edges you'll have to deal with you could try a nice naive strategy like sliding a ROI-finder window across the binary image which just sums the pixel values, and doesn't fire unless that value is above a threshold. That should optimise out all the blank surfaces.
Edit:
Ok some less naive approaches. If you have some a-priori knowledge, like you know the photo is well aligned (and not badly rotated or skewed), you could do some passes with a low-high-low-high grate tuned to capture the edges either side of a segment, using different scales in both x and y dimensions. A good hit in both directions will give clues not only about ROI but what scale of template to begin with (too large and too small grates won't hit both edges at once).
You could do blob detection, and then apply your templates to blobs in turn (falling back on merging blobs if the template matching score is below a threshold, in case your number segment is accidentally partitioned). The size of the blob might again give you some hint as to the scale of template to apply.
First of all, given that the original image has a LED display and so the illuminated region is has a higher intensity than the trest, I'd perform say a Yuv colour transformation on the original image and then work with the intensity plane (Y).
Next, if you know that the image is well aligned (i.e. not rotated) I would suggest applying separate horizontal and vertical edge detectors rather than a generic edge detector (you are not interested in diagonal lines). E.g.
sobelx = cv2.Sobel( img, cv2.CV_64F, 1, 0, ksize=5 )
sobely = cv2.Sobel( img, cv2.CV_64F, 0, 1, ksize=5 )
Otherwise you might use contour detection to find the bounds of the digits (though you may need to perform a dilate to close the gaps between LED segments.
Next I would construct horizontal and vertical histograms of the output from these edge or contour detections. These would help you to identify 'busy' regions of the image which contain many edges.
Finally, I'd threshold the Y plane and explore each of the ROIs with my template.

How to find contours in an image in OpenCV?

I need to find all contours in an image. I know the whole findcontours () and drawContours () thing, but its using the Canny edge detector that I am having trouble with. To use find contours, you either need to use canny edge detection or threshold the image. I cannot threshold the image because this would result in several edges getting blurred out ("merging" of the edges). So I decided to use Canny Edge detection. However, when I do use it instead of getting perfect edges, I get a variety of lines with gaps in them. This prevents me from getting good contours For example instead of getting the edges of a square, I would get 4 separate lines separated by small gaps resulting in me getting 4 contours instead of one. I tried dilating, opening, closing, Gaussian blurring and basically every morphological operator, but none of these are doing the job. Some do not merge the lines, while some merge the lines with non-relevant lines too. So I was wondering does anyone have a solution on how I can get actual contours from Canny Edge detection, or if not does someone have any alternatives to get all the contours from an image?
make blob, then contours come with it. :)
http://code.google.com/p/cvblob/