Dealing with contours and bounding rectangle in OpenCV 2.4 - python 2.7 -
i working opencv , python , dealing structural analysis , shape descriptors. have found blog: http://opencvpython.blogspot.it/2012/06/contours-2-brotherhood.html that's helpful , have tried black , white image drawing bounding rectangle , works. image extract, example, yellow color , on draw bounding rectangle. problem black , white image not uniform has noise , code doesn't recognize whole shape.



and code:
import numpy np import cv2 im = cv2.imread('shot.bmp') hsv_img = cv2.cvtcolor(im, cv2.color_bgr2hsv) color_min = np.array([20, 80, 80],np.uint8) color_max = np.array([40, 255, 255],np.uint8) frame_threshed = cv2.inrange(hsv_img, color_min, color_max) imgray = frame_threshed ret,thresh = cv2.threshold(frame_threshed,127,255,0) contours, hierarchy = cv2.findcontours(thresh,cv2.retr_tree,cv2.chain_approx_simple) cnt=contours[0] x,y,w,h = cv2.boundingrect(cnt) cv2.rectangle(im,(x,y),(x+w,y+h),(0,255,0),2) cv2.imshow("show",im) cv2.waitkey() cv2.destroyallwindows()
since original image noisy, simple fix remove of noise using cv2.medianblur() remove small noise areas in original image, , leave 1 contour. first few lines of code this:
im = cv2.imread('shot.bmp') im = cv2.medianblur(im,5) # 5 small kernel size hsv_img = cv2.cvtcolor(im, cv2.color_bgr2hsv) however, method not robust because must manually specify kernel size, , line cnt=contours[0] in code assumes contour of interest firs in list of contours, true if there 1 contour. more robust method assume interested in largest contour, allow compensate moderate noise.
to this, add lines:
# find index of largest contour areas = [cv2.contourarea(c) c in contours] max_index = np.argmax(areas) cnt=contours[max_index] after line:
contours, hierarchy = cv2.findcontours(thresh,cv2.retr_tree,cv2.chain_approx_simple) resulting in code:
import numpy np import cv2 im = cv2.imread('shot.bmp') hsv_img = cv2.cvtcolor(im, cv2.color_bgr2hsv) color_min = np.array([20, 80, 80],np.uint8) color_max = np.array([40, 255, 255],np.uint8) frame_threshed = cv2.inrange(hsv_img, color_min, color_max) imgray = frame_threshed ret,thresh = cv2.threshold(frame_threshed,127,255,0) contours, hierarchy = cv2.findcontours(thresh,cv2.retr_tree,cv2.chain_approx_simple) # find index of largest contour areas = [cv2.contourarea(c) c in contours] max_index = np.argmax(areas) cnt=contours[max_index] x,y,w,h = cv2.boundingrect(cnt) cv2.rectangle(im,(x,y),(x+w,y+h),(0,255,0),2) cv2.imshow("show",im) cv2.waitkey() cv2.destroyallwindows() both of these methods give result correct bounding box:

n.b.
of opencv 3.x findcontours() method returns 3 results (as can seen here), additional return value should caught like:
_, contours, hierarchy = cv2.findcontours(thresh,cv2.retr_tree,cv2.chain_approx_simple)
Comments
Post a Comment