Just a little trial to explore cv2.convexityDefects() on a cluster of mouse chromosomes:
The cluster consists in five touching mouse chromosomes. The aim is to use cv2 to display the contour of the particle, its convex hull, and to see what it is possible to do with convexityDefects function implemented in OpenCv 2.4.2 which provides now the big advantage of handling numpy array. The python script used is largely inspired from abid rahman's blog:
# -*- coding: utf-8 -*-
"""
Created on Wed Jul 4 14:43:42 2012
@author: jean-pat
"""
import cv2
import numpy as np
import os
import pylab as plb
print cv2.__version__
user=os.path.expanduser("~")
workdir=os.path.join(user,"QFISH","JPPAnimal","JPP52","11","DAPI","particles")
file="part25.png"
complete_path=os.path.join(workdir,file)
img = cv2.imread(complete_path)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,gray = cv2.threshold(gray,1,255,0)
print ret
gray2 = gray.copy()
mask = np.zeros(gray.shape,np.uint8)
contours, hier = cv2.findContours(gray,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
print hier
cv2.drawContours(img,contours,0,(0,255,0),1)
cnt = contours[0]
hull = cv2.convexHull(cnt,returnPoints = False)
#print hull
approx = cv2.approxPolyDP(cnt,0.05*cv2.arcLength(cnt,True),True)
print 'approx',approx
print 'contours',type(cnt), cnt.dtype, len(contours)
defects = cv2.convexityDefects(cnt,hull)
print defects
for i in range(defects.shape[0]):
s,e,f,d = defects[i,0]
start = tuple(cnt[s][0])
end = tuple(cnt[e][0])
far = tuple(cnt[f][0])
cv2.line(img,start,end,[255,0,0],1)
cv2.circle(img,far,5,[0,0,255],1)
plb.imshow(img)
plb.show()
The result is :
Strangely, some convexity defects (blue circles) of the particle contour (green curve) are very close to the particle convex hull (red curve). Four defects are detected on the contour where the chromosomes touch each other as waited. Those contact regions correspond to "neck" on the contour curve, and only one side of the neck is detected.
At first sight, there is nine false positive points, four well detected points and four non detected points (the other side of the "necks").
From the script, the content of the defect variable is:
The convexity defect is a list of vectors of the form:
so it should be possible to filter the points too close to the convex hull.
Strangely, some convexity defects (blue circles) of the particle contour (green curve) are very close to the particle convex hull (red curve). Four defects are detected on the contour where the chromosomes touch each other as waited. Those contact regions correspond to "neck" on the contour curve, and only one side of the neck is detected.
At first sight, there is nine false positive points, four well detected points and four non detected points (the other side of the "necks").
From the script, the content of the defect variable is:
[[[ 214 216 215 689]]
[[ 216 218 217 114]]
[[ 0 30 19 2444]]
[[ 30 32 31 234]]
[[ 32 34 33 201]]
[[ 34 38 37 278]]
[[ 38 71 56 5658]]
[[ 72 78 73 114]]
[[ 78 94 87 3133]]
[[ 96 98 97 114]]
[[ 98 106 101 297]]
[[ 106 120 111 364]]
[[ 121 212 179 12452]]]
[[ 216 218 217 114]]
[[ 0 30 19 2444]]
[[ 30 32 31 234]]
[[ 32 34 33 201]]
[[ 34 38 37 278]]
[[ 38 71 56 5658]]
[[ 72 78 73 114]]
[[ 78 94 87 3133]]
[[ 96 98 97 114]]
[[ 98 106 101 297]]
[[ 106 120 111 364]]
[[ 121 212 179 12452]]]
(start_index, end_index, farthest_pt_index, fixpt_depth)
so it should be possible to filter the points too close to the convex hull.
1 comment:
when I use convexityDefects, it get the error: AttributeError: 'module' object has no attribute 'convexityDefects'
do you know something about this??
I'm using opencv 2.4.6 on python 2.7 in ubuntu 12.04
Post a Comment