opencv-python 4.9.2. 轮廓特征

科技资讯 投稿 11600 0 评论

opencv-python 4.9.2. 轮廓特征

从这一刻起,你可以提取有用的数据,如面积,质心等。质心由关系给出,
$$ C_{x}=\frac{M_{10}}{M_{00}} $$和 $$ C_{y}=\frac{M_{01}}{M_{00}} $$。
这可以按如下方式完成:

import cv2 as cv

img = cv.imread(r'C:\Users\yuyalong\Pictures\Saved Pictures\rectangle.jpg'

imgray = cv.cvtColor(img, cv.COLOR_BGR2GRAY
ret, thresh = cv.threshold(imgray, 127, 255, 0

# 获取轮廓点
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE
print(99, len(contours

# 找到最内层的元素,这里是2是因为图像总共有三层
cnt = contours[2]

# 标记选中的区域
res1 = cv.drawContours(img, cnt, -1, (0, 255, 0, 3

# 计算矩
M = cv.moments(cnt

# 计算质心
cx = int(M['m10'] / M['m00']
cy = int(M['m01'] / M['m00']

# 画出质心
cv.circle(img, (cx, cy, 5, (255, 0, 0, -1

cv.imshow('img', img

cv.waitKey(0

轮廓面积

import cv2 as cv

img = cv.imread(r'C:\Users\yuyalong\Pictures\Saved Pictures\rectangle.jpg'

imgray = cv.cvtColor(img, cv.COLOR_BGR2GRAY
ret, thresh = cv.threshold(imgray, 127, 255, 0

# 获取轮廓点
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE
print(99, len(contours

# 找到最内层的元素,这里是2是因为图像总共有三层
cnt = contours[2]

# 标记选中的区域
res1 = cv.drawContours(img, cnt, -1, (0, 255, 0, 3

# 计算矩
M = cv.moments(cnt

# 计算轮廓面积
area = cv.contourArea(cnt
print(111, area, M['m00']

轮廓周长

import cv2 as cv

img = cv.imread(r'C:\Users\yuyalong\Pictures\Saved Pictures\rectangle.jpg'

imgray = cv.cvtColor(img, cv.COLOR_BGR2GRAY
ret, thresh = cv.threshold(imgray, 127, 255, 0

# 获取轮廓点
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE
print(99, len(contours

# 找到最内层的元素,这里是2是因为图像总共有三层
cnt = contours[2]

# 标记选中的区域
res1 = cv.drawContours(img, cnt, -1, (0, 255, 0, 3

# 计算轮廓周长
perimeter = cv.arcLength(cnt, True
print(222, perimeter

轮廓近似

epsilon = 0.01 * cv.arcLength(cnt, True
approx = cv.approxPolyDP(cnt, epsilon, True
import cv2 as cv

img = cv.imread(r'C:\Users\yuyalong\Pictures\Saved Pictures\rectangle1.jpg'

imgray = cv.cvtColor(img, cv.COLOR_BGR2GRAY
ret, thresh = cv.threshold(imgray, 127, 255, 0

# 获取轮廓点
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE
print(99, len(contours

# 找到最内层的元素,这里是2是因为图像总共有三层
cnt = contours[2]

# 计算轮廓近似 epsilon=弧长的5%的近似曲线
epsilon = 0.05 * cv.arcLength(cnt, True
approx = cv.approxPolyDP(cnt, epsilon, True

# 绘制轮廓近似
res3 = cv.drawContours(img, [approx], -1, (0, 0, 255, 3

cv.imshow('img', img

cv.waitKey(0

下边第一幅图是 epsilon=弧长的5%的近似曲线,第二幅图是 epsilon=弧长的1%的近似曲线

凸包

hull = cv.convexHull(points[, hull[, clockwise[, returnPoints]]
参数详情:

    points:是我们传入的轮廓。
  • hull:是输出,通常我们忽略它。
  • clocwise:方向标志。如果为True,则输出凸包顺时针方向。否则,它逆时针方向。
  • reurnPoints:默认为True。然后它返回凸包点的坐标。如果为False,则返回与凸包点对应的轮廓点的索引。
import cv2 as cv

img = cv.imread(r'C:\Users\yuyalong\Pictures\Saved Pictures\rectangle1.jpg'

imgray = cv.cvtColor(img, cv.COLOR_BGR2GRAY
ret, thresh = cv.threshold(imgray, 127, 255, 0

# 获取轮廓点
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE
print(99, len(contours

# 找到最内层的元素,这里是2是因为图像总共有三层
cnt = contours[2]

# 凸包
hull = cv.convexHull(cnt

# 绘制凸包
res4 = cv.drawContours(img, [hull], -1, (0, 0, 0, 3

cv.imshow('img', img

cv.waitKey(0

检查凸性

k = cv.isContourConvex(cnt

边界矩形

a.直边矩形

它是一个直的矩形,它不考虑对象的旋转。因此,边界矩形的面积不是最小的。它由函数cv.boundingRect(找到。
设(x,y为矩形的左上角坐标,(w,h为宽度和高度。

x,y,w,h = cv.boundingRect(cnt
cv.rectangle(img,(x,y,(x+w,y+h,(0,255,0,2
import cv2 as cv

img = cv.imread(r'C:\Users\yuyalong\Pictures\Saved Pictures\rectangle1.jpg'

imgray = cv.cvtColor(img, cv.COLOR_BGR2GRAY
ret, thresh = cv.threshold(imgray, 127, 255, 0

# 获取轮廓点
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE
print(99, len(contours

# 找到最内层的元素,这里是2是因为图像总共有三层
cnt = contours[2]

# 直边矩形
x, y, w, h = cv.boundingRect(cnt
cv.rectangle(img, (x, y, (x + w, y + h, (0, 255, 0, 2

cv.imshow('img', img

cv.waitKey(0
b.旋转矩形
rect = cv.minAreaRect(cnt
box = cv.boxPoints(rect
box = np.int0(box
cv.drawContours(img,[box],0,(0,0,255,2
import cv2 as cv
import numpy as np

img = cv.imread(r'C:\Users\yuyalong\Pictures\Saved Pictures\rectangle1.jpg'

imgray = cv.cvtColor(img, cv.COLOR_BGR2GRAY
ret, thresh = cv.threshold(imgray, 127, 255, 0

# 获取轮廓点
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE
print(99, len(contours

# 找到最内层的元素,这里是2是因为图像总共有三层
cnt = contours[2]

# 旋转矩形
rect = cv.minAreaRect(cnt
box = cv.boxPoints(rect
box = np.int0(box
cv.drawContours(img, [box], 0, (0, 0, 255, 2

cv.imshow('img', img

cv.waitKey(0

最小外接圈

(x,y,radius = cv.minEnclosingCircle(cnt
center = (int(x,int(y
radius = int(radius
cv.circle(img,center,radius,(0,255,0,2
import cv2 as cv
import numpy as np

img = cv.imread(r'C:\Users\yuyalong\Pictures\Saved Pictures\rectangle1.jpg'

imgray = cv.cvtColor(img, cv.COLOR_BGR2GRAY
ret, thresh = cv.threshold(imgray, 127, 255, 0

# 获取轮廓点
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE
print(99, len(contours

# 找到最内层的元素,这里是2是因为图像总共有三层
cnt = contours[2]

# 最小外接圆
(x, y, radius = cv.minEnclosingCircle(cnt
center = (int(x, int(y
radius = int(radius
cv.circle(img, center, radius, (0, 255, 0, 2

cv.imshow('img', img

cv.waitKey(0

椭圆拟合

ellipse = cv.fitEllipse(cnt
cv.ellipse(img, ellipse, (0, 255, 0, 2
import cv2 as cv
import numpy as np

img = cv.imread(r'C:\Users\yuyalong\Pictures\Saved Pictures\rectangle1.jpg'

imgray = cv.cvtColor(img, cv.COLOR_BGR2GRAY
ret, thresh = cv.threshold(imgray, 127, 255, 0

# 获取轮廓点
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE
print(99, len(contours

# 找到最内层的元素,这里是2是因为图像总共有三层
cnt = contours[2]

# 拟合椭圆
ellipse = cv.fitEllipse(cnt
cv.ellipse(img, ellipse, (0, 255, 0, 2

cv.imshow('img', img

cv.waitKey(0

拟合一条线

rows,cols = img.shape[:2]
[vx,vy,x,y] = cv.fitLine(cnt, cv.DIST_L2,0,0.01,0.01
lefty = int((-x*vy/vx + y
righty = int(((cols-x*vy/vx+y
cv.line(img,(cols-1,righty,(0,lefty,(0,255,0,2
import cv2 as cv
import numpy as np

img = cv.imread(r'C:\Users\yuyalong\Pictures\Saved Pictures\rectangle1.jpg'

imgray = cv.cvtColor(img, cv.COLOR_BGR2GRAY
ret, thresh = cv.threshold(imgray, 127, 255, 0

# 获取轮廓点
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE
print(99, len(contours

# 找到最内层的元素,这里是2是因为图像总共有三层
cnt = contours[2]

# 拟合一条线
rows, cols = img.shape[:2]
[vx, vy, x, y] = cv.fitLine(cnt, cv.DIST_L2, 0, 0.01, 0.01
lefty = int((-x * vy / vx + y
righty = int(((cols - x * vy / vx + y
cv.line(img, (cols - 1, righty, (0, lefty, (0, 255, 0, 2

cv.imshow('img', img

cv.waitKey(0

上边完整代码

点击查看代码
import cv2 as cv
import numpy as np

img = cv.imread(r'C:\Users\yuyalong\Pictures\Saved Pictures\rectangle1.jpg'

imgray = cv.cvtColor(img, cv.COLOR_BGR2GRAY
ret, thresh = cv.threshold(imgray, 127, 255, 0

# 获取轮廓点
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE
print(99, len(contours

# 找到最内层的元素,这里是2是因为图像总共有三层
cnt = contours[2]

# 标记选中的区域
# res1 = cv.drawContours(img, cnt, -1, (0, 255, 0, 3

# 计算矩
M = cv.moments(cnt

# 计算质心
cx = int(M['m10'] / M['m00']
cy = int(M['m01'] / M['m00']

# 画出质心
cv.circle(img, (cx, cy, 5, (255, 0, 0, -1

# 计算轮廓面积
area = cv.contourArea(cnt
print(111, area, M['m00']

# 计算轮廓周长
perimeter = cv.arcLength(cnt, True
print(222, perimeter

# 计算轮廓近似 epsilon=弧长的5%的近似曲线
epsilon = 0.01 * cv.arcLength(cnt, True
approx = cv.approxPolyDP(cnt, epsilon, True
res3 = cv.drawContours(img, [approx], -1, (0, 0, 255, 3

# 凸包
hull = cv.convexHull(cnt
res4 = cv.drawContours(img, [hull], -1, (0, 0, 0, 3

# 检查凸性
k = cv.isContourConvex(cnt
print(333, k

# 直边矩形
x, y, w, h = cv.boundingRect(cnt
cv.rectangle(img, (x, y, (x + w, y + h, (0, 255, 0, 2

# 旋转矩形
rect = cv.minAreaRect(cnt
box = cv.boxPoints(rect
box = np.int0(box
cv.drawContours(img, [box], 0, (0, 0, 255, 2

# 最小外接圆
(x, y, radius = cv.minEnclosingCircle(cnt
center = (int(x, int(y
radius = int(radius
cv.circle(img, center, radius, (0, 255, 0, 2

# 拟合椭圆
ellipse = cv.fitEllipse(cnt
cv.ellipse(img, ellipse, (0, 255, 0, 2

# 拟合一条线
rows, cols = img.shape[:2]
[vx, vy, x, y] = cv.fitLine(cnt, cv.DIST_L2, 0, 0.01, 0.01
lefty = int((-x * vy / vx + y
righty = int(((cols - x * vy / vx + y
cv.line(img, (cols - 1, righty, (0, lefty, (0, 255, 0, 2

cv.imshow('img', img

cv.waitKey(0

编程笔记 » opencv-python 4.9.2. 轮廓特征

赞同 (63) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽