OpenCV及k210实现形状检测并计算面积比

Python + OpenCV

详细代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import cv2
import numpy as np

# 打开摄像头
cap = cv2.VideoCapture(0) # cv2.imread("path/to/image.jpg")
rectangle_area = 0
circle_area = 0
line_length = 0

while True:
# 读取摄像头的帧
ret, frame = cap.read()
if not ret:
print("Failed to read frame from the camera.")
break

# 将帧转换为灰度图像
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

# 对图像进行边缘检测
edges = cv2.Canny(gray, 200, 400)

# 进行轮廓检测
contours, hierarchy = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 只检测外轮廓;水平、垂直端点

# 遍历每个轮廓并找到矩形和圆形
for contour in contours:
# 计算轮廓的面积
area = cv2.contourArea(contour)

# 如果轮廓面积小于设定阈值,则忽略
if area < 100:
continue

# 使用近似多边形方法对轮廓进行逼近
approx = cv2.approxPolyDP(contour, 0.04 * cv2.arcLength(contour, True), True)

# 如果逼近后的多边形有四个顶点,则认为是矩形
if len(approx) == 4:
# 绘制矩形轮廓
cv2.drawContours(frame, [approx], 0, (0, 255, 0), 2)
cv2.putText(frame, f"Rectangle Area: {area}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
rectangle_area = area

# 如果逼近后的多边形有三个顶点,则认为是三角形
elif len(approx) == 3:
# 绘制三角形轮廓
cv2.drawContours(frame, [approx], 0, (255, 0, 0), 2)
# 计算三角形的面积
triangle_area = cv2.contourArea(contour)
cv2.putText(frame, f"Triangle Area: {triangle_area}", (10, 70), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)

# 如果逼近后的多边形有更多的顶点(大致为圆形)
elif len(approx) > 6:
# 计算轮廓的最小外接圆
(x, y), radius = cv2.minEnclosingCircle(contour)

# 绘制圆形轮廓
cv2.circle(frame, (int(x), int(y)), int(radius), (0, 0, 255), 2)

# 计算圆形的面积
circle_area = int(np.pi * radius * radius)
cv2.putText(frame, f"Circle Area: {circle_area}", (10, 110), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
all_area = rectangle_area / circle_area
cv2.putText(frame, f"Area: {all_area}", (10, 150), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)

# 如果逼近后的多边形有两个顶点,则认为是直线
elif len(approx) == 2:
x1, y1 = approx[0][0]
x2, y2 = approx[1][0]
# 计算直线的长度
line_length = np.sqrt((x2 - x1)**2 + (y2 - y1)**2)
cv2.line(frame, (x1, y1), (x2, y2), (0, 0, 255), 2)
cv2.putText(frame, f"Line Length: {line_length}", (10, 190), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)

# 显示结果帧
cv2.imshow("Shapes", frame)

# 按下 'q' 键退出循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break

# 释放摄像头和销毁窗口
cap.release()
cv2.destroyAllWindows()

实现效果

实现效果1.png

k210

详细代码

screenshots-计算图形面积比.png

实现效果

实现效果2.jpg

识别特定颜色并框出

查看代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import cv2
import numpy as np


def red_identify(img):

# 灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 转换为HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# 二值化处理
lower_apple = np.array([0, 100, 100])
higher_apple = np.array([10, 200, 200])

mask = cv2.inRange(hsv, lower_apple, higher_apple)

# 膨胀操作
kernel = np.ones([5, 5], dtype=np.uint8)
dilate = cv2.dilate(mask, kernel, iterations=1)

# 画出轮廓
cnts, hierarchy = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

# 判断是否有轮廓
if len(cnts) == 0:

# 没有即显示原图
cv2.imshow("red_identify", img)
return

max_cnt = max(cnts, key=cv2.contourArea)
cv2.drawContours(img, max_cnt, -1, (0, 0, 255), 2)

# 最大外接矩形
(x, y, w, h) = cv2.boundingRect(max_cnt)
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 3)

cv2.imshow("red_identify", img)


if __name__ == "__main__":

# 打开摄像头
cap = cv2.VideoCapture(0)

# 设置摄像头参数,3和4为像素大小,5为帧率
cap.set(3, 256)
cap.set(4, 256)
cap.set(5, 60)

while True:

# 循环读取每一帧
flag, frame = cap.read()

# 读取失败
if not flag:
print("Camera error!")
break

# 调用颜色识别
red_identify(frame)

# 若没有按下q键,则每10毫秒显示一帧(OxFF为"q"的ASCII码)
if cv2.waitKey(10) & 0xFF == ord('q'):
break

cap.release()
cv2.destroyAllWindows()