本文共 3570 字,大约阅读时间需要 11 分钟。
1:import cv2import 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()
输出:
2:边界框/最小矩形区域和最小闭圆的轮廓
import cv2import 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()
输出:
3:凸轮廓和Douglas-Peucker算法
输入:
import cv2import 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()
输出:
4:直线和圆检测
输入:
import cv2import numpy as npimg = cv2.imread('1234.png')gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)edges = cv2.Canny(gray,50,120)minLineLength = 20maxLineGap = 5lines = 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()
输出:
5:圆检测
输入:
import cv2import 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()
输出:
备注:
前面有提到过检测任何种形状的方法,特别是approxPloyDP函数来检测,该函数提供多边形的近似,所以如果你的图像有多边形,在结合cv2.findContours函数和cv2.approxPloyDP函数,就可以相当准确的检测出来