python - How to close contour over outline rather than edge - OpenCV -


tl;dr: how measure area enclosed contour rather contour line itself

i want find outline of object in below image , have code works cases. original image

thresholding , adpative thresholding not work reliably ligthing changes. use canny edge detection , check area ensure found proper contour. however, once in while, when there gap cannot closed morphological closing, shape correct area of contour line instead of whole object.

canny contour output

what use convexhull, returns contour around object. however, in case object curves inwards along top , convexhull isn't approximation area anymore.

contour after convex hull

i tried using approxpolydp area gets returned of contour line rather object.

how can approxpolydp return similar closed contour around object, convexhull function does?

code illustrating using above picture:

import cv2 img = cv2.imread('img_0.jpg',0) cv2.imshow('original', img)  edges = cv2.canny(img,50,150)  cv2.imshow('canny', edges)  contours, hierarchy = cv2.findcontours(edges,cv2.cv.cv_retr_external,cv2.cv.cv_chain_approx_none)  cnt = contours[1] #i have function simplicity here hand  m = cv2.moments(cnt)  print('area = %f \t' %m['m00'], end="")  cnthull = cv2.convexhull(cnt, returnpoints=true) cntpoly=cv2.approxpolydp(cnt, epsilon=1, closed=true) mhull = cv2.moments(cnthull) mpoly = cv2.moments(cntpoly) print('area after convec hull = %f \t area after apporxpoly = %f \n' %(mhull['m00'], mpoly['m00']), end="")  x, y =img.shape size = (w, h, channels) = (x, y, 1) canvas = np.zeros(size, np.uint8) cv2.drawcontours(canvas, cnt, -1, 255) cv2.imshow('contour', canvas)  canvas = np.zeros(size, np.uint8) cv2.drawcontours(canvas, cnthull, -1, 255) cv2.imshow('hull', canvas)  canvas = np.zeros(size, np.uint8) cv2.drawcontours(canvas, cntpoly, -1, 255) cv2.imshow('poly', canvas) 

the output code

area = 24.500000    area after convec hull = 3960.500000     area after apporxpoly = 29.500000  

here's promising ppt geosensor.net discusses several algorithms. recommendation use swing arm method limited radius.

another un-tested, off wall idea have scan across image row , column (more directions increase accuracy) , color in regions between line intersections:

          _______          /-------\         /---------\ --------+---------+------ (fill between 2 intersections)              |         |         | --------+---------------- (no fill between single intersection)          \           ------- 

the maximum error decrease number of line directions scanned increases (more 90 , 45 degrees). getting final area simple pixel count.


Comments

Popular posts from this blog

toolbar - How to add link to user registration inside toobar in admin joomla 3 custom component -

linux - disk space limitation when creating war file -

How to provide Authorization & Authentication using Asp.net, C#? -