opencv3 轮廓检测

1:

import cv2 import numpy as npimg = np.zeros((200, 200), dtype=np.uint8) img[50:150, 50:150] = 255ret, thresh = cv2.threshold(img, 127, 255, 0) image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) color = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) img = cv2.drawContours(color, contours, -1, (0,255,0), 2) cv2.imshow("contours", color) cv2.waitKey() cv2.destroyAllWindows()

输出:
opencv3 轮廓检测
文章图片



2:边界框/最小矩形区域和最小闭圆的轮廓
import cv2 import numpy as np# img = cv2.pyrDown(cv2.imread("hammer.jpg", cv2.IMREAD_UNCHANGED)) img = cv2.pyrDown(cv2.imread("123.png", cv2.IMREAD_UNCHANGED))ret, thresh = cv2.threshold(cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY) , 127, 255, cv2.THRESH_BINARY) image, contours, hier = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)for c in contours: # find bounding box coordinates x,y,w,h = cv2.boundingRect(c) cv2.rectangle(img, (x,y), (x+w, y+h), (0, 255, 0), 2)# find minimum area rect = cv2.minAreaRect(c) # calculate coordinates of the minimum area rectangle box = cv2.boxPoints(rect) # normalize coordinates to integers box = np.int0(box) # draw contours cv2.drawContours(img, [box], 0, (0,0, 255), 3)# calculate center and radius of minimum enclosing circle (x,y),radius = cv2.minEnclosingCircle(c) # cast to integers center = (int(x),int(y)) radius = int(radius) # draw the circle img = cv2.circle(img,center,radius,(0,255,0),2)cv2.drawContours(img, contours, -1, (255, 0, 0), 1) cv2.imshow("contours", img)cv2.waitKey() cv2.destroyAllWindows()

输出:
opencv3 轮廓检测
文章图片



3:凸轮廓和Douglas-Peucker算法
输入:
import cv2 import numpy as np# img = cv2.pyrDown(cv2.imread("hammer.jpg", cv2.IMREAD_UNCHANGED)) img = cv2.pyrDown(cv2.imread("123.png", cv2.IMREAD_UNCHANGED))ret, thresh = cv2.threshold(cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY) , 127, 255, cv2.THRESH_BINARY) black = cv2.cvtColor(np.zeros((img.shape[1], img.shape[0]), dtype=np.uint8), cv2.COLOR_GRAY2BGR)image, contours, hier = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)for cnt in contours: epsilon = 0.01 * cv2.arcLength(cnt,True) approx = cv2.approxPolyDP(cnt,epsilon,True) hull = cv2.convexHull(cnt) cv2.drawContours(black, [cnt], -1, (0, 255, 0), 2) cv2.drawContours(black, [approx], -1, (255, 255, 0), 2) cv2.drawContours(black, [hull], -1, (0, 0, 255), 2)cv2.imshow("hull", black) cv2.waitKey() cv2.destroyAllWindows()

输出:
opencv3 轮廓检测
文章图片



4:直线和圆检测
输入:
import cv2 import numpy as npimg = cv2.imread('1234.png') gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) edges = cv2.Canny(gray,50,120) minLineLength = 20 maxLineGap = 5 lines = cv2.HoughLinesP(edges,1,np.pi/180,20,minLineLength,maxLineGap) for x1,y1,x2,y2 in lines[0]: cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)cv2.imshow("edges", edges) cv2.imshow("lines", img) cv2.waitKey() cv2.destroyAllWindows()

输出:
opencv3 轮廓检测
文章图片

5:圆检测
【opencv3 轮廓检测】输入:
import cv2 import numpy as npplanets = cv2.imread('water_coins.jpg') gray_img = cv2.cvtColor(planets, cv2.COLOR_BGR2GRAY) img = cv2.medianBlur(gray_img, 5) cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,120, param1=100,param2=30,minRadius=0,maxRadius=0)circles = np.uint16(np.around(circles))for i in circles[0,:]: # draw the outer circle cv2.circle(planets,(i[0],i[1]),i[2],(0,255,0),2) # draw the center of the circle cv2.circle(planets,(i[0],i[1]),2,(0,0,255),3)cv2.imwrite("planets_circles.jpg", planets) cv2.imshow("HoughCirlces", planets) cv2.waitKey() cv2.destroyAllWindows()

输出:
opencv3 轮廓检测
文章图片


备注:
前面有提到过检测任何种形状的方法,特别是approxPloyDP函数来检测,该函数提供多边形的近似,所以如果你的图像有多边形,在结合cv2.findContours函数和cv2.approxPloyDP函数,就可以相当准确的检测出来




    推荐阅读