美文网首页
OpenCV-Python学习(十五):轮廓

OpenCV-Python学习(十五):轮廓

作者: 星光下的胖子 | 来源:发表于2020-06-27 22:41 被阅读0次

...待更新...
目录:

  • 1.轮廓查找与绘制
  • 2.面积,周长,重心
  • 3.轮廓近似: approxPolyDP()
  • 4.凸包和凸性检测: convexHull()、isContourConvex()
  • 5.边界检测: 边界矩形、最小(面积)矩形、最小外切圆以及椭圆拟合、直线拟合
  • 6.轮廓性质
  • 7.对象掩码mask
  • 8.形状匹配: matchShapes()

1.轮廓查找与绘制

print("===1.轮廓查找与绘制: findContours()、drawContours()===")
import cv2

img = cv2.imread("image/14.jpg")
# img = cv2.imread("image/26.jpg")
# cv2.imshow("img", img)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# cv2.imshow("gray", gray)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
cv2.imshow("thresh", thresh)

# 查找轮廓
# findContours(image, mode, method, contours=None, hierarchy=None, offset=None)
# image:输入图像(二值化图像)
# mode:轮廓检索方式
# method:轮廓近似方法
contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
print(len(contours[0]))
cv2.imshow("thresh2", thresh)

# 绘制轮廓:直接对原图进行操作
# drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None)
# contourIdx 轮廓的索引(当设置为-1时,绘制所有轮廓)
img_contour = cv2.drawContours(img, contours, -1, (0, 255, 0), 2)

cv2.imshow("img", img)
cv2.imshow("img_contour", img)

cv2.waitKey(0)
cv2.destroyAllWindows()

2.面积,周长,重心

print("===2.面积,周长,重心===")
import cv2

# gray = cv2.imread("image/14.jpg", 0)
gray = cv2.imread("image/26.jpg", 0)
ret, binary = cv2.threshold(gray, 127, 255, 0)
contours, _ = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
print(len(contours))
print(contours)

# 重心
# moments(array, binaryImage=None)
M = cv2.moments(contours[0])  # 矩
print(M)
cx = int(M['m10'] / M['m00'])
cy = int(M['m01'] / M['m00'])
print("重心:", cx, cy)

# 面积
# contourArea(contour, oriented=None)
area = cv2.contourArea(contours[0])
print("面积:", area)

# 周长
# arcLength(curve, closed)
perimeter = cv2.arcLength(contours[0], True)
print("周长:", perimeter)

cv2.imshow("gray", gray)

cv2.waitKey(0)
cv2.destroyAllWindows()

3.轮廓近似: approxPolyDP()

print("===3.轮廓近似: approxPolyDP()===")
import cv2

img = cv2.imread("image/26.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

# 查找轮廓
contours, _ = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 轮廓近似:
# approxPolyDP(curve, epsilon, closed, approxCurve=None)
# epsilon指定逼近精度的参数。这是原始曲线与其近似值之间的最大距离。
epsilon = 60
approx = cv2.approxPolyDP(contours[0], epsilon, True)

# 绘制轮廓:直接对原图进行操作
cv2.drawContours(img, [approx], -1, (0, 0, 255), 3)

cv2.imshow("img", img)
cv2.imshow("img_contour", img)

cv2.waitKey(0)
cv2.destroyAllWindows()

4.凸包和凸性检测: convexHull()、isContourConvex()

print("===4.凸包和凸性检测: convexHull()、isContourConvex()===")
import cv2

# 函数 cv2.convexHull() 可以用来检测一个曲线是否具有凸性缺陷,并能纠正缺陷
# 函数 cv2.isContourConvex() 可以可以用来检测一个曲线是不是凸的。它只能返回 True 或 False。
# img = cv2.imread("image/14.jpg")
# img = cv2.imread("image/26.jpg")
img = cv2.imread("image/15.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray, 127, 255, 0 | 8)

# 查找轮廓
contours, _ = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

hull = cv2.convexHull(contours[0])
print(cv2.isContourConvex(contours[0]), cv2.isContourConvex(hull))

# 绘制轮廓
cv2.drawContours(img, [hull], -1, (0, 0, 255), 2)

cv2.imshow("img", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

5.边界检测: 边界矩形、最小(面积)矩形、最小外切圆以及椭圆拟合、直线拟合

print("===5.边界检测: 边界矩形、最小(面积)矩形、最小外切圆以及椭圆拟合、直线拟合===")
import cv2
import numpy

# 边界矩形 boundingRect(array)
# 最小(面积)矩形 minAreaRect(points)
# 最小外切圆 minEnclosingCircle(points)
img = cv2.imread("image/16.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY)

# 查找轮廓
contours, _ = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 1)边界矩形
x, y, w, h = cv2.boundingRect(contours[0])
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)

# 2)最小面积矩形
rect = cv2.minAreaRect(contours[0])
# print(rect)
# print(type(rect))  # <class 'tuple'>
box = cv2.boxPoints(rect)
# print(box)  # <class 'numpy.ndarray'>
# print(type(box))
box = numpy.int0(box)
# print(box)  # <class 'numpy.ndarray'>
# 绘制轮廓
cv2.drawContours(img, [box], -1, (255, 0, 0), 2)

# 3)最小外切圆 minEnclosingCircle(points)
(x, y), radius = cv2.minEnclosingCircle(contours[0])
cv2.circle(img, (int(x), int(y)), int(radius), (0, 0, 255), 2)

# 4)椭圆拟合
# fitEllipse(points)
ellipse = cv2.fitEllipse(contours[0])
print(ellipse)
cv2.ellipse(img, ellipse, (255, 0, 0), 2)

# 5)直线拟合
# fitLine(points, distType, param, reps, aeps, line=None)
# points 待输入点集(一般为二维数组或vector点集)
# distType 距离类型
# param 距离参数
# reps 径向的精度参数
# aeps 角度精度参数
h, w, _ = img.shape
[vx, vy, x, y] = cv2.fitLine(contours[0], cv2.DIST_L2, 0, 0.01, 0.01)
lefty = int(y - x * (vy / vx))
righty = int(y + (w - x) * (vy / vx))
cv2.line(img, (0, lefty), (w-1, righty), (0, 0, 255), 2)

cv2.imshow("img", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

6.轮廓性质

print("===6.轮廓性质===")
import cv2
import numpy

img = cv2.imread("image/16.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)

# 查找轮廓
contours, _ = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 边界矩形
x, y, w, h = cv2.boundingRect(contours[0])
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
# 最小面积矩形
rect = cv2.minAreaRect(contours[0])
box = cv2.boxPoints(rect)
box = numpy.int0(box)
cv2.drawContours(img, [box], -1, (0, 255, 0), 2)
# 最小外切圆
(x, y), radius = cv2.minEnclosingCircle(contours[0])
cv2.circle(img, (int(x), int(y)), int(radius), (255, 0, 0), 2)

# 绘制轮廓
cv2.drawContours(img, contours, -1, (255, 255, 0), 2)

# 1.边界矩形的宽高比
aspect_ratio = float(w) / h
print("边界矩形的宽高比:", aspect_ratio)
# 2.轮廓面积与边界矩形面积的比
area = cv2.contourArea(contours[0])
rect_area = w * h
extent = float(area) / rect_area
print("轮廓面积与边界矩形面积的比:", extent)
# 3.轮廓面积和土包面积的比
hull = cv2.convexHull(contours[0])  # 凸包和凸性检测
area = cv2.contourArea(contours[0])
hull_area = cv2.contourArea(hull)
solidity = float(area) / hull_area
print("轮廓面积和凸包面积的比:", solidity)
# 4.与轮廓面积相等的圆的直径
area = cv2.contourArea(contours[0])
equi_diameter = numpy.sqrt(4 * area / numpy.pi)
print("与轮廓面积相等的圆的直径:", equi_diameter)
# 5.对象的方向
ellipse = cv2.fitEllipse(contours[0])
print(ellipse)
print("对象的方向angle:", ellipse[2])
cv2.ellipse(img, ellipse, (0, 255, 255), 2)

cv2.imshow("img", img)

cv2.waitKey(0)
cv2.destroyAllWindows()

7.对象掩码mask

print("===7.对象掩码mask===")
import cv2
import numpy

img = cv2.imread("image/16.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray, 0, 255, 0 | 8)

contours, _ = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

mask = numpy.zeros(img.shape, numpy.uint8)
cv2.drawContours(mask, contours, -1, (255, 255, 0), -1)

pixelpoints = numpy.transpose(numpy.nonzero(mask))
print(pixelpoints)

cv2.imshow("img", img)
cv2.imshow("mask", mask)

cv2.waitKey(0)
cv2.destroyAllWindows()

8.形状匹配: matchShapes()

print("===8.形状匹配: matchShapes()===")
import cv2

img1 = cv2.imread("image/16.jpg")
# img2 = cv2.imread("image/16.jpg")
img2 = cv2.imread("image/17.jpg")

gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
ret, binary1 = cv2.threshold(gray1, 0, 255, 0 | 8)
contours1, _ = cv2.findContours(binary1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
ret, binary2 = cv2.threshold(gray2, 0, 255, 0 | 8)
contours2, _ = cv2.findContours(binary2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

ret = cv2.matchShapes(contours1[0], contours2[0], cv2.CONTOURS_MATCH_I2, 0.0)
print(ret)

cv2.imshow("img1", img1)
cv2.imshow("img2", img2)

cv2.waitKey(0)
cv2.destroyAllWindows()

相关文章

网友评论

      本文标题:OpenCV-Python学习(十五):轮廓

      本文链接:https://www.haomeiwen.com/subject/glsdfktx.html