honey
honey

Reputation: 89

Error in ellipses using Opencv python

I have an input image and would like to draw ellipses on all contours that are found. I'm using python-opencv and getting the following error. Can anyone help me with this? I do know to draw the ellipse, but unsure about how to draw over every detected objects in a image. I am new to this area, hence please excuse me for silly question.

OpenCV Error: Incorrect size of input array (There should be at least 5 points to fit the ellipse) in cv::fitEllipse, file 
C:\bld\opencv_1498171314629\work\opencv-3.2.0\modules\imgproc\src\shapedescr.cpp, line 358
Traceback (most recent call last):
File "D:/project/test.py", line 41, in <module>
ellipse = cv2.fitEllipse(contours[0])
cv2.error: C:\bld\opencv_1498171314629\work\opencv- 
3.2.0\modules\imgproc\src\shapedescr.cpp:358: error: (-201) There should be 
at least 5 points to fit the ellipse in function cv::fitEllipse

Upvotes: 1

Views: 7808

Answers (2)

MK 62665
MK 62665

Reputation: 123

I do not know how your input image is and so this might or might not work. When you use cv2.RETR_EXTERNAL in the find contours function, it only returns the external contours. Instead, use 'cv2.RETR_TREE'.

This retrieves all of the contours and reconstructs a full hierarchy of nested contours. Refer here for documentation. Your code should change as follows.

im2, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

Hope this helps. If it does not work, it would be great if you could upload your input image so that we can work on it!

Also, as for putting an ellipse on every contour found, like api55 mentioned, you are trying fit ellipse only on the first contour. Hope his answer helps you on that. If you want to put an ellipse on the largest contour, you can sort the found contours based on their area and then fit ellipses on the largest contour or on contours bigger than a certain size.

Upvotes: 1

api55
api55

Reputation: 11420

With ellipse=cv2.fitEllipse(contours[0])you are fitting only the first contour, which has less than 5 points... you should iterate through all the contours and draw only the ones with more than 5 points...

Try something like this:

import numpy as np
import cv2

image=cv2.imread("cell.jpg")

grey=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) 
grey_hist=cv2.calcHist([grey],[0],None,[256],[0,256])
eq=cv2.equalizeHist(grey)
blurredA1=cv2.blur(eq,(3,3))

(T,thresh)=cv2.threshold(blurredA1,190,255,cv2.THRESH_BINARY)
im2, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)

if len(contours) != 0:
  for i in range(len(contours)):
    if len(contours[i]) >= 5:
      cv2.drawContours(thresh,contours,-1,(150,10,255),3)
      ellipse=cv2.fitEllipse(contours[0])
    else:
      # optional to "delete" the small contours
      cv2.drawContours(thresh,contours,-1,(0,0,0),-1)

cv2.imshow("Perfectlyfittedellipses",thresh)
cv2.waitKey(0)

As you can see I iterate all of the contours and check if it is bigger than 5. Also, I added something to cloud all the contours that are not big enough.

Upvotes: 3

Related Questions