17

I have a binary image, i want to detect/trace curves in that image. I don't know any thing (coordinates, angle etc). Can any one guide me how should i start? suppose i have this image enter image description here

I want to separate out curves and other lines. I am only interested in curved lines and their parameters. I want to store information of curves (in array) to use afterward.

Developer
  • 203
  • 1
  • 3
  • 6

5 Answers5

16

It really depends on what you mean by "curve".

If you want to simply identify each discrete collection of pixels as a "curve", you could use a connected-components algorithm. Each component would correspond to a collection of pixels. You could then apply some test to determine linearity or some other feature of the component.

If you're looking for straight lines, circular curves, or any other parametric curve you could use the Hough transform to detect the elements from the image.

The best approach is really going to depend on which curves you're looking for, and what information you need about the curves.

reference links:

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
John Percival Hackworth
  • 11,395
  • 2
  • 29
  • 38
  • 1
    Example of Curves are given in the example image, U can say as circular curves. Needed information includes all relevant things that are necessary to represent (or draw) curve, i wana store them. I have tried enough but not able to do that.. If possible help via some pseudo code or any link that is more close to my problem. Thanks – Developer Aug 13 '11 at 19:59
  • 1
    Consider using a circular hough transform, parameterizing on origin, and radius. Once you've localized the circular curves you can extract the appropriate angular range. See the answer for some more links. – John Percival Hackworth Aug 13 '11 at 20:05
  • @JohnPercivalHackworth Say I find edges of img_ori, then turn it into binary img_bin, then use connected-components algorithm to get the collections of pixels. For each collection, is there a way to scan the neighboring pixels from img_ori and find the dark ones and bright ones and store their locations into dark and bright groups? – June Wang Nov 29 '19 at 07:42
2

Since you already seem to have a good binary image, it might be easiest to just separate the different connected components of the image and then calculate their parameters.

First, you can do the separation by scanning through the image, and when you encounter a black pixel you can apply a standard flood-fill algorithm to find out all the pixels in your shape. If you have matlab image toolbox, you can find use bwconncomp and bwselect procedures for this. If your shapes are not fully connected, you might apply a morphological closing operation to your image to connect the shapes.

After you have segmented out the different shapes, you can filter out the curves by testing how much they deviate from a line. You can do this simply by picking up the endpoints of the curve, and calculating how far the other points are from the line defined by the endpoints. If this value exceeds some maximum, you have a curve instead of a line.

Another approach would be to measure the ratio of the distance of the endpoints and length of the object. This ratio would be near 1 for lines and larger for curves and wiggly shapes.

If your images have angles, which you wish to separate from curves, you might inspect the directional gradient of your curves. Segment the shape, pick set of equidistant points from it and for each point, calculate the angle to the previous point and to the next point. If the difference of the angle is too high, you do not have a smooth curve, but some angled shape.

Possible difficulties in implementation include thick lines, which you can solve by skeleton transformation. For matlab implementation of skeleton and finding curve endpoints, see matlab image processing toolkit documentation

aleator
  • 4,436
  • 20
  • 31
  • After segmented out the different shapes, how to scan the neighboring pixels of specific shape on the original image(not binary)? – June Wang Nov 30 '19 at 04:37
1

There is also another solution possible with the use of chain codes. Understanding Freeman chain codes for OCR

The chain code basically assigns a value between 1-8(or 0 to 7) for each pixel saying at which pixel location in a 8-connected neighbourhood does your connected predecessor lie. Thus like mention in Hackworths suggestions one performs connected component labeling and then calculates the chain codes for each component curve. Look at the distribution and the gradient of the chain codes, one can distinguish easily between lines and curves. The problem with the method though is when we have osciallating curves, in which case the gradient is less useful and one depends on the clustering of the chain codes!

Community
  • 1
  • 1
beedot
  • 652
  • 5
  • 12
1

1) Read a book on Image Analysis

2) Scan for a black pixel, when found look for neighbouring pixels that are also black, store their location then make them white. This gets the points in one object and removes it from the image. Just keep repeating this till there are no remaining black pixels.

If you want to separate the curves from the straight lines try line fitting and then getting the coefficient of correlation. Similar algorithms are available for curves and the correlation tells you the closeness of the point to the idealised shape.

QuentinUK
  • 2,997
  • 21
  • 20
-1

Im no computer vision expert, but i think that you could detect lines/curves in binary images relatively easy using some basic edge-detection algorithms (e.g. sobel filter).

DucatiNerd
  • 467
  • 4
  • 12
  • 8
    Since the people who voted you down did not leave an explanation: An edge detection algorithm (e.g. sobel filter) does not actually "detect" edges, it rather "strengthens" regions with large changes (edges), and "weakens" regions with low changes. After that you can "extract" edges by applying some sort of threshold. The result would be a binary image. – bjoernz Aug 15 '11 at 19:27