반응형



컨투어 검출하는 방법과 컨투어 특성을 사용하는 방법을 다룹니다. 






사용하는 OpenCV 버전에 따라 findContours 함수의 사용 방법이 다음처럼 차이가 있습니다. 




OpenCV 4.x

contours, hierarchy = cv.findContours(img_binary, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)


OpenCV 3.x

_, contours, hierarchy = cv.findContours(img_binary, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)




Contour Features

영역 크기



import cv2 as cv


img_color = cv.imread('test.png')
img_gray = cv.cvtColor(img_color, cv.COLOR_BGR2GRAY)
ret, img_binary = cv.threshold(img_gray, 127, 255, 0)
contours, hierarchy = cv.findContours(img_binary, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)


for cnt in contours:
   cv.drawContours(img_color, [cnt], 0, (255, 0, 0), 3)  # blue

cv.imshow("result", img_color)

cv.waitKey(0)



for cnt in contours:

   area = cv.contourArea(cnt)

   print(area)


cv.imshow("result", img_color)

cv.waitKey(0)



근사화



 



import cv2 as cv
import numpy as np


img_color = cv.imread('square.png')
img_gray = cv.cvtColor(img_color, cv.COLOR_BGR2GRAY)
ret, img_binary = cv.threshold(img_gray, 127, 255, 0)
contours, hierarchy = cv.findContours(img_binary, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)


for cnt in contours:
   cv.drawContours(img_color, [cnt], 0, (255, 0, 0), 3)  # blue

cv.imshow("result", img_color)

cv.waitKey(0)


for cnt in contours:

   epsilon = 0.02 * cv.arcLength(cnt, True)
   approx = cv.approxPolyDP(cnt, epsilon, True)
   print( len(approx))

   cv.drawContours(img_color,[approx],0,(0,255,255),5)


cv.imshow("result", img_color)

cv.waitKey(0)




무게 중심




import cv2 as cv


img_color = cv.imread('test.png')
img_gray = cv.cvtColor(img_color, cv.COLOR_BGR2GRAY)
ret, img_binary = cv.threshold(img_gray, 127, 255, 0)
contours, hierarchy = cv.findContours(img_binary, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)


for cnt in contours:
   cv.drawContours(img_color, [cnt], 0, (255, 0, 0), 3)  # blue

cv.imshow("result", img_color)

cv.waitKey(0)




for cnt in contours:

   M = cv.moments(cnt)

   cx = int(M['m10']/M['m00'])
   cy = int(M['m01']/M['m00'])

   cv.circle(img_color, (cx, cy), 10, (0,0,255), -1)

cv.imshow("result", img_color)

cv.waitKey(0)



..


..


경계 사각형 (Bounding Rectangle)




import cv2 as cv
import numpy as np


img_color = cv.imread('test.png')
img_gray = cv.cvtColor(img_color, cv.COLOR_BGR2GRAY)
ret, img_binary = cv.threshold(img_gray, 127, 255, 0)
contours, hierarchy = cv.findContours(img_binary, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)


for cnt in contours:
   cv.drawContours(img_color, [cnt], 0, (255, 0, 0), 3)  # blue

cv.imshow("result", img_color)

cv.waitKey(0)


for cnt in contours:

   x, y, w, h = cv.boundingRect(cnt)
   cv.rectangle(img_color, (x, y), (x + w, y + h), (0, 255, 0), 2)


cv.imshow("result", img_color)

cv.waitKey(0)



for cnt in contours:

   rect = cv.minAreaRect(cnt)
   box = cv.boxPoints(rect)
   box = np.int0(box)
   cv.drawContours(img_color,[box],0,(0,0,255),2)


cv.imshow("result", img_color)

cv.waitKey(0)




Convex Hull




import cv2 as cv
import numpy as np


img_color = cv.imread('hand.png')
img_gray = cv.cvtColor(img_color, cv.COLOR_BGR2GRAY)
ret, img_binary = cv.threshold(img_gray, 127, 255, 0)
contours, hierarchy = cv.findContours(img_binary, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)


for cnt in contours:
   cv.drawContours(img_color, [cnt], 0, (255, 0, 0), 3)  # blue

cv.imshow("result", img_color)

cv.waitKey(0)




for cnt in contours:

   hull = cv.convexHull(cnt)
   cv.drawContours(img_color, [hull], 0, (255, 0, 255), 5)


cv.imshow("result", img_color)

cv.waitKey(0)



Convexity Defects




import cv2 as cv
import numpy as np


img_color = cv.imread('hand.png')
img_gray = cv.cvtColor(img_color, cv.COLOR_BGR2GRAY)
ret, img_binary = cv.threshold(img_gray, 127, 255, 0)
contours, hierarchy = cv.findContours(img_binary, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)


for cnt in contours:
   cv.drawContours(img_color, [cnt], 0, (255, 0, 0), 3)  # blue

cv.imshow("result", img_color)

cv.waitKey(0)


for cnt in contours:

   hull = cv.convexHull(cnt)
   cv.drawContours(img_color, [hull], 0, (255, 0, 255), 5)


cv.imshow("result", img_color)

cv.waitKey(0)


for cnt in contours:
   hull = cv.convexHull(cnt, returnPoints = False)
   defects = cv.convexityDefects(cnt, hull)

   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])

       print(d)


       if d > 500:
           cv.line(img_color, start, end, [0, 255, 0], 5)
           cv.circle(img_color, far, 5, [0,0,255], -1)

       cv.imshow("result", img_color)
       cv.waitKey(0)





테스트에 사용한 이미지입니다.




반응형

문제 발생시 지나치지 마시고 댓글 남겨주시면 가능한 빨리 답장드립니다.


제가 쓴 책도 한번 검토해보세요 ^^

+ Recent posts