contactbibliophile
contactbibliophile

Reputation: 31

OpenCV Contour Detection in color

I'm trying to detect the optic disc in an image of the back of the eye using OpenCV and findContour, then fitEllipse, but my program isn't detecting the optic disc at all. How do I fix this? Code and images are below

import cv2
import numpy as np
from sklearn.linear_model import LinearRegression
import math
from decimal import Decimal


def find_elongation(image):
  img = cv2.imread(image,0)
  ret,thresh = cv2.threshold(img,127,255,0)
  contour,hierarchy = cv2.findContours(thresh, 1, 2)
  contours = []
  for i in range(len(contour)):
    if len(contour[i])>=5:
      contours.append(contour[i])
  cnt = contours[0]
  k = cv2.isContourConvex(cnt)
  ellipse = cv2.fitEllipse(cnt)
  im = cv2.ellipse(img,ellipse,(0,255,0),2)
  (x,y),(ma,Ma),angle = cv2.fitEllipse(cnt)
  return Ma/ma

print(find_elongation('eye.png'))
print(find_elongation('eye2.png'))
print(find_elongation('eye3.png'))

Image (one of them): enter image description here

I'm trying to get the brightly colored circle in the middle: enter image description here

Thanks for the help!

Upvotes: 2

Views: 1657

Answers (1)

David Serrano
David Serrano

Reputation: 313

I have developed a piece of code to implement what you have asked. It mainly uses de Value channel of the HSV color space followed by some morphological operations.

import cv2
import numpy as np
import matplotlib.pyplot as plt

# Read the image
img = cv2.imread('so.png')

# Transform the image to HSV color-space and keep only the value channel
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h,s,v = cv2.split(hsv)

# Threshold the iamge with the 95% of the brightest possible pixels
maxVal = np.max(v)
per = 0.95
_, th = cv2.threshold(v, maxVal*per, 255, cv2.THRESH_BINARY)

# Erode the image and find the connected components
th = cv2.erode(th, np.ones((2,2), np.uint8))
n, conComp, stats, centroids = cv2.connectedComponentsWithStats(th)

# Obtain the sizes of the connectedComponents skipping the background
sizes = stats[1:,-1]

# Obtain the number of the connectedComponent with biggest size
nComp = np.argmax(sizes) + 1

# Isolate the connectedComponent and apply closing
out = np.zeros((img.shape[0], img.shape[1]), np.uint8)
out[conComp==nComp] = 1
out = cv2.morphologyEx(out, cv2.MORPH_CLOSE, np.ones((10,10)))

# Apply gradient to mask to obtain the border of the ellipse
out = cv2.morphologyEx(out, cv2.MORPH_GRADIENT, np.ones((2,2)))

# Join the border of the ellipse with the image to display it
img[out==1] = (0,0,0)

plt.imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))
plt.show()

I attach the output I have obtained with the picture you posted:

Picture

Upvotes: 1

Related Questions