希望有能力的朋友还是拿C++做。
本节讨论查找、绘制图像轮廓,轮廓的面积,周长,多边形逼近,多边形凸包,轮廓的外接矩形
具有相同颜色或灰度的连续点的曲线,轮廓是形状分析和物体的检测和识别中很有用
import cv2
import numpy as np
cat = cv2.imread('cat.jpeg')
img = cv2.cvtColor(cat, cv2.COLOR_BGR2GRAY)
#二值化,有两个返回值,阈值,结果
ret, binary = cv2.threshold(img, 150, 255, cv2.THRESH_BINARY)
cv2.imshow('img', img)
# cv2.imshow('img2', binary)
contours, hierarchy = cv2.findContours(binary, mode = cv2.RETR_TREE, method=cv2.CHAIN_APPROX_SIMPLE)
print(contours)
cv2.waitKey(0)
cv2.destroyAllWindows()
import cv2
import numpy as np
cat = cv2.imread('cat.jpeg')
img = cv2.cvtColor(cat, cv2.COLOR_BGR2GRAY)
#二值化,有两个返回值,阈值,结果
ret, binary = cv2.threshold(img, 150, 255, cv2.THRESH_BINARY)
cat_cp = cat.copy()
contours, hierarchy = cv2.findContours(binary, mode = cv2.RETR_TREE, method=cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(cat_cp, contours, -1, (0, 0, 255), 2)
cv2.imshow('cat', cat)
cv2.imshow('contours', cat_cp)
cv2.waitKey(0)
cv2.destroyAllWindows()
单位为像素,再找到轮廓后,会有很多细小的轮廓,可以通过轮廓面积进行过滤
import cv2
import numpy as np
cat = cv2.imread('cat.jpeg')
img = cv2.cvtColor(cat, cv2.COLOR_BGR2GRAY)
#二值化,有两个返回值,阈值,结果
ret, binary = cv2.threshold(img, 150, 255, cv2.THRESH_BINARY)
cat_cp = cat.copy()
contours, hierarchby = cv2.findContours(binary, mode = cv2.RETR_TREE, method=cv2.CHAIN_APPROX_SIMPLE)
#一个轮廓的面积
area = cv2.contourArea(contours[0])
print(area)
#一个轮廓周长
perimeter = cv2.arcLength(contours[1], closed=True)
print(perimeter)
findContours后的轮廓信息contours可能过于复杂不平花,可以用approxPolyDP函数对该多边形曲线近似,这就是轮廓的多边形逼近。
import cv2
import numpy as np
hand = cv2.imread('hand.jpg')
img = cv2.cvtColor(hand, cv2.COLOR_BGR2GRAY)
#二值化,有两个返回值,阈值,结果
ret, binary = cv2.threshold(img, 150, 255, cv2.THRESH_BINARY)
#hand_cp = img.copy()
hand_cp2 = img.copy()
contours, hierarchy = cv2.findContours(binary, mode = cv2.RETR_TREE, method=cv2.CHAIN_APPROX_SIMPLE)
#cv2.drawContours(hand_cp, contours, -1, (0, 0, 255), 2)
#cv2.imshow('cat', hand)
#cv2.imshow('contours', hand_cp)
print(len(contours))
#使用多边形逼近,近似模拟手的轮廓
#阈值给20,阈值越大,逼近效果越粗糙
approx = cv2.approxPolyDP(contours[0], 20, closed=True)
#本质还是一个轮廓数据
cv2.drawContours(hand_cp2, [approx], 0, (0, 0, 255), 2)
cv2.imshow('moni', hand_cp)
cv2.waitKey(0)
cv2.destroyAllWindows()
多边形逼近是高度近似,凸包和多边形逼近很像,只不过它是物体最外层的凸多边形,凸包是指完全包含所有轮廓,并且仅由轮廓上的点构成的多边形。
import cv2
import numpy as np
hand = cv2.imread('hand.jpg')
img = cv2.cvtColor(hand, cv2.COLOR_BGR2GRAY)
#二值化
ret, binary = cv2.threshold(img, 150, 255, cv2.THRESH_BINARY)
hand_cp2 = img.copy()
contours, hierarchy = cv2.findContours(binary, mode = cv2.RETR_TREE, method=cv2.CHAIN_APPROX_SIMPLE)
#计算凸包
hull = cv2.convexHull(contours[0])
cv2.namedWindow('moni', cv2.WINDOW_NORMAL)
cv2.resizeWindow('moni', 640, 480)
cv2.drawContours(hand_cp2, [hull], 0, (0, 0, 255), 2)
cv2.imshow('moni', hand_cp2)
cv2.waitKey(0)
cv2.destroyAllWindows()
import cv2
import numpy as np
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.resizeWindow('img', 640, 480)
hand = cv2.imread('hand.jpg')
img = cv2.cvtColor(hand, cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(img, 150, 255, cv2.THRESH_BINARY)
hand_cp2 = img.copy()
contours, hierarchy = cv2.findContours(binary, mode = cv2.RETR_TREE, method=cv2.CHAIN_APPROX_SIMPLE)
# rect是一个rotated 的矩形,包含起始坐标(x,y),长宽,旋转角度
# 最小外接矩形
rect = cv2.minAreaRect(contours[540])
print(rect)
# 最大外接矩形,方方正正,返回四个点x,y w,h
x,y,w,h = cv2.boundingRect(contours[540])
cv2.rectangle(hand_cp2, (x,y), (x+w, y+h), (0,0,255), 2)
#画出矩形,画旋转矩形有用的
#帮我们计算出旋转矩形的4个坐标点
#坐标为整数
box = cv2.boxPoints(rect)
#四舍五入,再取整
box = np.round(box).astype('int')
cv2.drawContours(hand_cp2, [box], 0, (255,0,0), 2)
cv2.imshow('img', hand_cp2)
cv2.waitKey(0)
cv2.destroyAllWindows()