graduation-design/abandon_code/contour_line.py
2024-03-30 15:52:26 +08:00

123 lines
4.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from time import sleep
import cv2
import numpy as np
from orbbec_camera.OrbbecCamera import OrbbecCamera
# 图像预处理
def img_Threshold(src_gauss):
imgHSV = cv2.cvtColor(src_gauss, cv2.COLOR_BGR2HSV)
# cv2.imshow("imgHSV", imgHSV)
# # 三通道分割
h, s, v = cv2.split(imgHSV)
# 检测差值
hs_diff = cv2.absdiff(h, s)
# cv2.imshow("hs_diff", hs_diff)
sv_diff = cv2.absdiff(s, v)
# cv2.imshow("sv_diff", sv_diff)
hv_diff = cv2.absdiff(h, v)
# cv2.imshow("hv_diff", hv_diff)
v1 = np.mean(hs_diff) # 取每个通道的均值
v2 = np.mean(sv_diff)
v3 = np.mean(hv_diff)
v_max = (v1 if v1 > v2 else v2) if (v1 if v1 > v2 else v2) > v3 else v3 # 比较均值得到最大值
print(v_max, v3)
if v_max > 8:
if abs(v_max - v1) < 0.01:
gray = hs_diff.copy()
elif abs(v_max - v2) < 0.01:
gray = sv_diff.copy()
elif abs(v_max - v3) < 0.01:
gray = hv_diff.copy()
return gray
# 图像开运算和闭运算(形态学处理)
def img_dila_eros(src_img):
# 3. 膨胀和腐蚀操作的核函数
element1 = cv2.getStructuringElement(cv2.MORPH_RECT, (4, 3))
element2 = cv2.getStructuringElement(cv2.MORPH_RECT, (4, 3))
element3 = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
# 4. 膨胀一次,让轮廓突出
src_img = cv2.dilate(src_img, element2)
# 5. 腐蚀一次,去掉细节,如表格线等。注意这里去掉的是竖直的线
src_img = cv2.erode(src_img, element1)
# 6. 再次膨胀,让轮廓明显一些
# src_img = cv2.dilate(src_img, element2)
src_img = cv2.morphologyEx(src_img, cv2.MORPH_OPEN, element3) # 开运算去掉噪点
return src_img
# 定位和角度测量
def getContours(src, img):
# 查找轮廓cv2.RETR_ExTERNAL=获取外部轮廓点, CHAIN_APPROX_NONE = 得到所有的像素点,CHAIN_APPROX_SIMPLE=得到轮廓的四个点
contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 循环轮廓,判断每一个形状
for cnt in contours:
# 获取轮廓面积
area = cv2.contourArea(cnt)
print("轮廓像素面积:", area) # 打印所有轮廓面积
# 当面积大于20000代表有形状存在
if area < 20000:
pass
# print("轮廓像素面积:", area) # 打印符合条件轮廓面积
# 计算所有轮廓的周长,便于做多边形拟合
# 多边形拟合,获取每个形状的边
approx = cv2.approxPolyDP(cnt, 0.02 * cv2.arcLength(cnt, True), True) # 拟合的多边形的边数
print("approx:", len(approx))
objCor = len(approx) # 轮廓的边长
rect = cv2.minAreaRect(approx) # 最小外接矩形
box = cv2.boxPoints(rect) # boxPoints返回四个点顺序右下→左下→左上→右上
box = np.int0(box)
center = rect[0] # 中心坐标
center_array = np.array(center)
int_center = center_array.astype(int)
angle = rect[2] # 旋转角度
# 画出边界
if objCor > 4:
cv2.circle(src, (int(rect[0][0]), int(rect[0][1])), int(rect[1][0] / 2), (255, 255, 255), 5)
else:
cv2.drawContours(src, [box], 0, (255, 255, 255), 3) # 画出多边形形状
cv2.circle(src, (int(rect[0][0]), int(rect[0][1])), 3, (255, 255, 255), 5)
# 画中心,写角度
cv2.putText(src, "center:" + str(int_center), (10, 20), cv2.FONT_HERSHEY_COMPLEX, 0.5, (0, 0, 255), 1)
if objCor <= 4:
cv2.putText(src, "angle:" + str(round(angle)), (10, 40), cv2.FONT_HERSHEY_COMPLEX, 0.5, (0, 0, 255), 1)
else:
cv2.putText(src, "angle:" + "0", (10, 40), cv2.FONT_HERSHEY_COMPLEX, 0.5, (0, 0, 255), 1)
if __name__ == "__main__":
# 初始化摄像头
camera = OrbbecCamera('HW', True, image_width=640)
camera.run()
while True:
# 读取图片
image = camera.get_color_image()
if image is not None:
# 高斯滤波
gauss = cv2.GaussianBlur(image, (15, 15), 3)
# cv2.imshow("gauss", gauss)
# 图像预处理
gray = img_Threshold(gauss)
# 高斯滤波
gray = cv2.GaussianBlur(gray, (15, 15), 3)
# cv2.imshow("gray", gray)
# 自适应阈值二值化
binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 11, 2)
# 图像形态学处理
binary = img_dila_eros(binary)
cv2.imshow("binary", binary)
# 获取轮廓 计算中心点坐标,尺寸;形状识别,颜色识别。
getContours(image, binary)
cv2.imshow("image", image)
sleep(1)
key = cv2.waitKey(1)
if key == ord('q'):
camera.stop()
break