Identify whether image is a circle #276
Replies: 9 comments 2 replies
-
Can we see input examples? |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
The last one is tricky. Is it supposed to not match because the hexagon is outside of the circle? |
Beta Was this translation helpful? Give feedback.
-
You're right, the docs for Here's a circle detector for your logos: #!/usr/bin/ruby
require 'vips'
image = Vips::Image.new_from_file(ARGV[0])
# we need a one-band image of just the edges for circle detection
edges = image.colourspace(:b_w).flatten.canny(precision: :integer)
# search for circles roughly the size of the image, so radius of half the
# diameter of the largest circle
radius_target = [image.width, image.height].min / 2
radius_margin = 20
detect = edges.hough_circle(min_radius: radius_target - radius_margin,
max_radius: radius_target + radius_margin)
# look for the (x, y) with the peak, then at that point, find the radius
strength, opts = detect.max(x: true, y: true)
x = opts["x"]
y = opts["y"]
bands = detect.getpoint(x, y)
radius_detected = bands.each_with_index.max[1] + radius_target - radius_margin
puts "strength = #{strength}, x = #{x}, y = #{y}, radius = #{radius_detected}" For this PNG I see:
But for this one: I see:
That's just picking the strongest circle, so a strong circle off centre could hide a weak centred circle. You'd probably want to crop the hough output before searching for a peak. You could blur or rank filter as well to reduce noise. |
Beta Was this translation helpful? Give feedback.
-
... I meant to say, you need to edge-detect before hough transforms, and canny is probably the best one. Photographic images will need some noise filtering too (threshold, median, smooth, etc.). Hough output will often also need some filtering, perhaps a rank filter to find local peaks, or morphology to remove isolated peaks. Your PNG logos are very clean, of course, so you can skip most of this extra processing. |
Beta Was this translation helpful? Give feedback.
-
Wow, thank you. This is extremely helpful. It seems like the strength variable is related to the size of the image and/or radius, correct? So if I do something like |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
I ran the code on different sizes of the same image (the blue globe icon attached above) and got these results: ruby circle.rb globe.png
=> strength = 559.0, x = 100, y = 100, radius = 89 ruby circle.rb globe100px.png
=> strength = 262.0, x = 50, y = 50, radius = 45 ruby circle.rb globe500px.png
=> strength = 209.0, x = 256, y = 256, radius = 231 As you can see the strength value for the first, original, image is significantly higher. It seems like they all pertain to the same circle though. (central and with a radius just under half the width) Any idea why that might be the case? |
Beta Was this translation helpful? Give feedback.
-
I'd guess because the circles don't quite line up. libvips is using a fast int approximation of a circle for the hough transform, and perhaps the logo is using something different. You could try doing a slight gaussblur after canny and again after hough_circle. Your detected strengths will drop, but the result should be more stable. |
Beta Was this translation helpful? Give feedback.
-
For a web app I'm building, I'm trying to figure out whether a given logo image has the shape of a circle.
I've come up with two different strategies, but I'm stuck moving forward with both.
The first strategy is to use hough circle transform to detect all circles in the image. If there's a circle that's roughly the size of the whole image, that probably means the image is indeed of a circular logo.
Here's how far I've got so far:
I'm not sure what values to use for
scale
,min_radius
, andmax_radius
. I think I can somehow use them to get only big circles that are around the image size. The.write_to_memory.unpack('I_*')
part I get from #138 where @jcupitt explains it returns a matrix of "votes" for each pixel.Any pointers on how to move forward from here?
The second strategy I came up with is applying a circular mask. And then comparing that to the original image. If the images remain identical, that means the part 'outside' the circular mask are unused and there's a high likelihood the image is a circle (or has a lot of whitespace).
I'm not sure how to approach this, although I did find VIPS::Mask.
Curious to hear your ideas and whether there's any relevant documentation I can read?
Beta Was this translation helpful? Give feedback.
All reactions