Vous êtes sur la page 1sur 8

How to find circular objects in an image?

- Mathematica Stack Exchange

1 of 8

file:///F:/alex/backup/personal/research/Computer Vision/Find Handrawn...


sign up

Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no
registration required.

log in

tour

help

How to find circular objects in an image?


How could I use morphological processing to find circular objects in an image? More specifically, I need to detect
road signs.
I need to get the "80 speed limit" sign from this image:

image-processing

image

edited Oct 8 '12 at 12:08

Sjoerd C. de Vries
29.1k
8 61 155

asked Oct 8 '12 at 10:44


Elfet
309

10

Welcome to Mathematica.SE, Elfet! It would help if you described what you have tried so far and where you got
stuck. Verbeia Oct 8 '12 at 10:47

This blog post might be useful. VLC Oct 8 '12 at 11:06

Also this one cormullion Oct 8 '12 at 12:01

Because the road signs will rarely be seen head-on, you probably want to generalize the question to detecting
elliptical objects--perhaps just ellipses with near-vertical major axes. whuber Oct 8 '12 at 16:13

3 Answers
The following method doesn't require parameters and discovers also oblique views.
obl[transit_Image] :=
(SelectComponents[

MorphologicalComponents[

DeleteSmallComponents@ChanVeseBinarize[#, "TargetColor" -> Red],


Method -> "ConvexHull"],

{"Count", "SemiAxes"}, Abs[Times @@ #2 Pi - #1] < #1/100 &]) & @ transit;


GraphicsGrid[{#, obl@# // Colorize, ImageMultiply[#, Image@Unitize@obl@#]} & /@
(Import /@ ("http://tinyurl.com/" <> # &/@ {"aw74tvc", "aycppg4", "9vnfrko",

"bak4uzx"}))]

4/17/2016 10:13 PM

How to find circular objects in an image? - Mathematica Stack Exchange

2 of 8

file:///F:/alex/backup/personal/research/Computer Vision/Find Handrawn...

If you want to detect non-reddish edged ellipses just remove the "TargetColor" -> Red option.
edited Nov 21 '12 at 12:00

answered Oct 8 '12 at 15:37


belisarius
45.7k
6

67

168

That's more like it...! Will it work with red birds on signs, though? :) cormullion Oct 8 '12 at 16:19
@cormullion Your raven is one of my examples :D belisarius Oct 8 '12 at 17:07
:) I meant that, if the bird was bright red (like a parrot) it might upset things. But your code is too clever to be fooled, I
think! cormullion Oct 8 '12 at 17:46
@cormullion Now we only have to find a photograph of a bright red bird sitting on a transit signal and test it :)
belisarius Oct 8 '12 at 17:58
will an amphibian do? cormullion Oct 8 '12 at 18:59

Basically, you import the image:


i = Import["http://upload.wikimedia.org/wikipedia/commons
/2/2c/Crow_on_the_sign_of_no_parking.jpg"]

4/17/2016 10:13 PM

How to find circular objects in an image? - Mathematica Stack Exchange

3 of 8

file:///F:/alex/backup/personal/research/Computer Vision/Find Handrawn...

Tidy it up:
mb = MorphologicalBinarize[i]

Isolate the areas of interest:


cn = ColorNegate[Closing [mb, 10]]

Use component analysis:


sc = SelectComponents[

cn, {"Eccentricity",

"Circularity"}, #1 < .5

Colorize[sc]

&& #2 < 0.8 &];

4/17/2016 10:13 PM

How to find circular objects in an image? - Mathematica Stack Exchange

4 of 8

file:///F:/alex/backup/personal/research/Computer Vision/Find Handrawn...

Now use this information to process your original image...


ImageApply[# * 0.25 &, i, Masking -> ColorNegate[sc]]

Of course, I've cheated in this answer: to process arbitrary images - or to detect crows on road signs is much much harder!
(I chose this image because, when I wrote this answer, you hadn't supplied your example.)
edited Oct 8 '12 at 13:36

answered Oct 8 '12 at 11:52


cormullion
15.3k
2

24

77

This is good! Try to do this also for image in my question. Is there are is way to use EdgeDetect? Elfet Oct 8 '12
at 12:00

Have a go, show us what happens ... :) cormullion Oct 8 '12 at 12:01
How now get using this information (Colorized) to select sign from original image? Elfet Oct 8 '12 at 12:34
have a look at some of the relevant tutorials and videos: reference.wolfram.com/mathematica/tutorial
/ImageProcessing.html should be built-in to the help; wolfram.com/broadcast/video.php?channel=97&video=839 is a
good video introduction cormullion Oct 8 '12 at 14:04

Circular Hough Transform

I have had fun implementing a circular Hough transform based solution for this question (in part using
some MMA9 Image3D functionality which has become available in between). By this shape-related
approach we can overcome the color restrictions of the approaches tried so far.
The method starts with an edge detection, followed by a circular Hough transform (also see this Java
applet demonstration, or these lecture slides, or this paper).
In the following this is demonstrated using a test picture (with inscribed radius numbers) taken from
www.markschulze.net/java/hough/. For this implementation the core part is the extensive use of

4/17/2016 10:13 PM

How to find circular objects in an image? - Mathematica Stack Exchange

5 of 8

file:///F:/alex/backup/personal/research/Computer Vision/Find Handrawn...

ListConvolve , while the convolution is being done using annulus-shaped kernels.


markschulze = Import["http://i.stack.imgur.com/XoqbW.png"]

markschulzeedges=EdgeDetect[markschulze, 10, Method -> "Sobel"]

ParallelMap[Image@
Divide[

ListConvolve[
#,

ImageData@markschulzeedges,
Ceiling[(Length@#)/2]

],

Total[#, 2]

] &,
Map[

Function[{r}, DiskMatrix[r] - ArrayPad[DiskMatrix[r - 1], 1]][#] &,


Range[14, 18, 1]

}
These five images represent the circular Hough transform within the radius interval [14,18].
In order to utilize the transform for circle or circular area detection this transform is both binarized and
labeled. According to the detected coordinates of candidate circles inside the 3D Hough transform
volume, radii and image positions are determined, so that masks for the original image can be
computed:
HoughCircleDetection[image_Image, radiusmin_Integer: 1,
radiusmax_Integer: 40, edgedetectradius_Integer: 10,
minfitvalue_Real: .25, radiusstep_Integer: 1,
minhoughvoxels_Integer: 4] :=

Module[{edgeimage, hough3dbin, hough3dbinlabels, coords, arraydim},


edgeimage =

SelectComponents[

DeleteBorderComponents[

EdgeDetect[image, edgedetectradius, Method -> "Sobel"]

],

"EnclosingComponentCount", # == 0 &

4/17/2016 10:13 PM

How to find circular objects in an image? - Mathematica Stack Exchange

6 of 8

file:///F:/alex/backup/personal/research/Computer Vision/Find Handrawn...

];
hough3dbin =

DeleteSmallComponents[
Image3D[

ParallelMap[

Binarize[Image@
Divide[

ListConvolve[#, ImageData@edgeimage, Ceiling[(Length@#)/2]],


Total[#, 2]

],

minfitvalue

] &,
Map[

Function[{r}, DiskMatrix[r] - ArrayPad[DiskMatrix[r - 1], 1]][#] &,

Range[radiusmin, radiusmax, radiusstep]

],

minhoughvoxels

];

hough3dbinlabels = MorphologicalComponents[hough3dbin];
coords =

ParallelMap[

Round[Mean[Position[hough3dbinlabels, #]]] &,

Sort[Rest@Tally@Flatten@hough3dbinlabels, #1[[2]] > #2[[2]] &][[All, 1]]

];

arraydim = Rest@Dimensions[hough3dbinlabels];
Print["Radii: ", radiusmin + coords[[All, 1]] - 1];
ParallelMap[

Function[{level, offx, offy},


ImageMultiply[
image,

Image@ArrayPad[

DiskMatrix[radiusmin + level - 1],

{{offx - radiusmin - level, First@arraydim - offx - radiusmin - level + 1},


]

{offy - radiusmin - level, Last@arraydim - offy - radiusmin - level + 1}}

][Sequence @@ #] &,
]

coords

];

Practically it is useful to restrict the method to eligible radii. Also, sometimes parameters, like the
edge detection radius, and the minimum fit value might be adapted:
Show[ImageApply[Plus, HoughCircleDetection[#, 14, 18, 10, .3]],
ImageSize -> ImageDimensions[#]] &[markschulze]

Radii: {16,15,17,14,14}

The method appears to work quite specifically, though 13 is included here.


Let us see the results for the four images already used above:

4/17/2016 10:13 PM

How to find circular objects in an image? - Mathematica Stack Exchange

7 of 8

file:///F:/alex/backup/personal/research/Computer Vision/Find Handrawn...

Show[ImageApply[Plus, HoughCircleDetection[Import["http://tinyurl.com/aw74tvc"], 30, 50]],


]

ImageSize -> 200

Radii: {39,33}

Here we find two more or less concentric hits.


Show[ImageApply[Plus, HoughCircleDetection[Import["http://tinyurl.com/aycppg4"], 20, 30,
15]],

ImageSize -> 200

Radii: {22}

Oblique views are a matter of luck, of course.


Show[ImageApply[Plus, HoughCircleDetection[Import["http://tinyurl.com/9vnfrko"], 20, 40]],
]

ImageSize -> 200

Radii: {24,24,24,23,24,24,22,24,24,22,22,24,23,24,22,22,24}

While the No-U-turn sign is missed, the stop sign is included...


Show[ImageApply[Plus, HoughCircleDetection[Import["http://tinyurl.com/bak4uzx"], 20, 60]],
]

ImageSize -> 200

Radii: {54,38}

4/17/2016 10:13 PM

How to find circular objects in an image? - Mathematica Stack Exchange

8 of 8

file:///F:/alex/backup/personal/research/Computer Vision/Find Handrawn...

For the No-parking sign again the inner and outer circle is found.
For real life applications like road sign detection, for reasons of robustness feature
combination is always being recommended.
edited Oct 26 '13 at 22:30
halirutan
38.7k
3

79

answered Oct 22 '13 at 19:07


168

UDB
911

Very nice. Perhaps a link to a good explanation of the Circular Hough Transform may help future readers belisarius
Oct 22 '13 at 20:15
Thanks, have added some references, and also have added some more or less didactic example. Sorry for a wrong
Floor call inside ListConvolve for kernel alignmend, this was replaced by a Ceiling now, so all resulting
images were replaced as well (I noticed a strange shift, this is now gone). UDB Oct 23 '13 at 14:26

4/17/2016 10:13 PM