7

My image is here:

my photo is here.

i'm looking for a better solution or algorithm to detect the ellipse part (dish) in this photo and mask it in an other photo in Opencv. could you please give me some advice or solution. and my code is :

 circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1.2, 1, param1=128, minRadius=200, maxRadius=600)
    # draw detected circles on image
    circles = circles.tolist()
    for cir in circles:
        for x, y, r in cir:
            x, y, r = int(x), int(y), int(r)
            cv2.circle(img, (x, y), r, (0, 255, 0), 4)

    # show the output image
    cv2.imshow("output", cv2.resize(img, (500, 500)))
Jeru Luke
  • 20,118
  • 13
  • 80
  • 87
Mohammad Mostafavi
  • 337
  • 1
  • 3
  • 13
  • 1
    You don't need ellipse detection here (btw, not available in OpenCV). You're probably good with a simple threshold on bright values, and keeping the biggest connected component. Also, please show what you've tried – Miki Feb 13 '17 at 14:10
  • A simple color segmentation may work as well. – ZdaR Feb 13 '17 at 14:11
  • I'm adding the special part of the code, that is connected to my question, would you take a look it plz. – Mohammad Mostafavi Feb 13 '17 at 15:01

2 Answers2

9

There is an alternative for it in skimage made by Xie, Yonghong, and Qiang Ji and published as...

“A new efficient ellipse detection method.” Pattern Recognition, 2002. Proceedings. 16th International Conference on. Vol. 2. IEEE, 2002.

Their Ellipse detection code is relatively slow and the example takes about 70 seconds; compared to website claimed "28 seconds".

If you have conda or pip: "name" install scikit-image and give it a shot...

Their code can be found here or as copy/pasted below:

import matplotlib.pyplot as plt

from skimage import data, color, img_as_ubyte
from skimage.feature import canny
from skimage.transform import hough_ellipse
from skimage.draw import ellipse_perimeter

# Load picture, convert to grayscale and detect edges
image_rgb = data.coffee()[0:220, 160:420]
image_gray = color.rgb2gray(image_rgb)
edges = canny(image_gray, sigma=2.0,
              low_threshold=0.55, high_threshold=0.8)

# Perform a Hough Transform
# The accuracy corresponds to the bin size of a major axis.
# The value is chosen in order to get a single high accumulator.
# The threshold eliminates low accumulators
result = hough_ellipse(edges, accuracy=20, threshold=250,
                       min_size=100, max_size=120)
result.sort(order='accumulator')

# Estimated parameters for the ellipse
best = list(result[-1])
yc, xc, a, b = [int(round(x)) for x in best[1:5]]
orientation = best[5]

# Draw the ellipse on the original image
cy, cx = ellipse_perimeter(yc, xc, a, b, orientation)
image_rgb[cy, cx] = (0, 0, 255)
# Draw the edge (white) and the resulting ellipse (red)
edges = color.gray2rgb(img_as_ubyte(edges))
edges[cy, cx] = (250, 0, 0)

fig2, (ax1, ax2) = plt.subplots(ncols=2, nrows=1, figsize=(8, 4), sharex=True,
                                sharey=True,
                                subplot_kw={'adjustable':'box'})

ax1.set_title('Original picture')
ax1.imshow(image_rgb)

ax2.set_title('Edge (white) and result (red)')
ax2.imshow(edges)

plt.show()
Jon
  • 2,280
  • 2
  • 25
  • 33
ZF007
  • 3,708
  • 8
  • 29
  • 48
  • If your using Matplotlib version < 2.2.2 then use : subplot_kw={'adjustable':'box-forced'}). – ZF007 May 31 '21 at 07:33
7

APPROACH 1:

As suggested by Miki, I was able to detect the ellipse in the given image using contour properties (in this I used the area property).

CODE:

#--- First obtain the threshold using the greyscale image ---
ret,th = cv2.threshold(gray,127,255, 0)

#--- Find all the contours in the binary image ---
_, contours,hierarchy = cv2.findContours(th,2,1)
cnt = contours
big_contour = []
max = 0
for i in cnt:
   area = cv2.contourArea(i) #--- find the contour having biggest area ---
    if(area > max):
        max = area
        big_contour = i 

final = cv2.drawContours(img, big_contour, -1, (0,255,0), 3)
cv2.imshow('final', final)

This is what I obtained:

enter image description here

APPROACH 2:

You can also use the approach suggested by you in this case. Hough detection of ellipse/circle.

You have to pre-process the image. I performed adaptive threshold and obtained this:

enter image description here

Now you can perform Hough circle detection on this image.

Hope it is not a mouthful!! :D

Jeru Luke
  • 20,118
  • 13
  • 80
  • 87
  • thanks dear for help me, but my problem is, i can't use contour Area method i'm trying to do it with HoughCircles transform , but my problem is i can't draw ellipse around my dish would you help me how can i do it with this algorithm ? thanks in advance – Mohammad Mostafavi Feb 13 '17 at 16:33
  • You can try detecting circle using Hough transform on the second image I posted. Give it a try – Jeru Luke Feb 13 '17 at 16:34
  • 4
    A little hint: HoughCircles doesn't detect ellipses... just circles ;) @Moh – Miki Feb 13 '17 at 16:41
  • 2
    No, you can't fill the hough accumulator well if the points are not on a circumference... only ellipses with the two axis very similar. And approximating an ellipse with a circle is most of the time a bad approximation – Miki Feb 13 '17 at 16:45