Reputation: 1
I have an image, were few crossing lines produce four polygons. I want to measure area of each polygon. In my script I am trying to create contours and, probably, uses the wrong methods. I appreciate any advice ...
source image
import cv2
import numpy as np
import time
# define range of color in HSV
lower_red = np.array([150,135,160])
upper_red = np.array([180,250,200])
white_line = np.array([255,255,255])
red_line = np.array([0,0,255])
im = cv2.imread('laser.jpg')
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
cv2.imshow('imgray', im)
ret,thresh = cv2.threshold(imgray,127,255,0)
cv2.imshow('thresh', thresh)
# Remove some small noise if any.
dilate = cv2.dilate(thresh,None)
erode = cv2.erode(dilate,None)
cv2.imshow('erode', erode)
_, contours, hierarchy = cv2.findContours(erode,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
##for contour in contours:
## if (cv2.contourArea(contour) > 50):
## print contours
im2 = np.zeros((500,500,3), np.uint8)
cv2.drawContours(im2,contours,0,(125,125,0),1)
cv2.imshow('contours',im2)
k = cv2.waitKey(0)
if k == 27: # wait for ESC key to exit
cv2.destroyAllWindows()
elif k == ord('s'): # wait for 's' key to save and exit
cv2.imwrite('messigray.png',im2)
cv2.destroyAllWindows()
Upvotes: 0
Views: 5568
Reputation: 294
For extracting the contours using your current code, you could do the following:
_,contours,heirarchy=cv2.findContours(erode,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
im2 = np.zeros((480,640,3), np.uint8)
cv2.drawContours(im2,contours,-1,(125,125,0),1)
(using RETR_EXTERNAL will provide you with the boundaries of the outside part only, if there are any individual parts made inside those will be excluded so just use RETR_TREE which will provide proper heirarchy so you know you are looking at the inside boundary). you have created empty array im2 of wrong size 500,500 since doing that will exclude some part of the image(will give error when drawing contours outside this). These are minor mistakes.
And now for the main part which was wrong is cv2.drawContours(im2,contours,0,(125,125,0),1)
here you are giving array of arrays of the contours in the image and telling it to draw only the first contour(by the 0th element); So what you should do is either draw/process contours one by one using the contour number(1 or 2 or 3 or 4 or... instead of the 0) or first select the contour then draw it like this:
cnt=contour[4]
cv2.drawContours(im2,[cnt],0,(125,125,0),1)
or just draw all of the contours by supplying (-1) instead of (0) like i have shown earlier.
If you want to select some contours and draw them you could just do something like this:
cnt=[contour[2],contour[5],contour[9]]
cv2.drawContours(im2,cnt,-1,(125,125,0),1)
Upvotes: 1