admin 管理员组

文章数量: 1184232

import cv2
import numpy as np
import time
# 定义HSV阈值范围
h_min = 36
h_max = 98
s_min = 88
s_max = 255
v_min = 76
v_max = 157
lower = np.array([h_min, s_min, v_min])
upper = np.array([h_max, s_max, v_max])
# 打开摄像头
cap = cv2.VideoCapture(0,cv2.CAP_V4L2)
if not cap.isOpened():
    cap = cv2.VideoCapture(0)
    raise RuntimeError('not open')
# 设置较低分辨率(如 640x480)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
cap.set(cv2.CAP_PROP_FPS, 15)  # 限制帧率
cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)  # 减少缓冲区大小
while True:
    ret, frame = cap.read()
    if not ret:
        print("摄像头读取失败,尝试重新初始化...")
        cap.release()
        time.sleep(1)
        cap = cv2.VideoCapture(0, cv2.CAP_V4L2)
        continue
        # 图像预处理
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(hsv, lower, upper)
    # mask = cv2.bilateralFilter(mask, d=5, sigmaColor=50, sigmaSpace=50)
    kernel = (5, 5) if frame.shape[1] < 1000 else (10, 10)
    kernel_combined = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, kernel)
    mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel_combined, iterations=2)
    mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel_combined, iterations=2)
    # binary = cv2.adaptiveThreshold(mask, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 15, 2)
    edges = cv2.Canny(mask, 50, 150)
    # 将处理之后的掩码应用在原始图像上
    result = cv2.bitwise_and(frame, frame, mask=mask)
    # 在图像x轴中心画一条线
    frame_center_x = frame.shape[1] // 2
    cv2.line(result, (frame_center_x, 0), (frame_center_x, frame.shape[0]), (0, 255, 0), 2)
    # 边缘检测
    contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    green_cx = None
    for i, cnt in enumerate(contours):
        if hierarchy[0][i][3] == -1:
            inner_contours = [c for j, c in enumerate(contours) if hierarchy[0][j][3] == i]
            if inner_contours:
                M_outer = cv2.moments(cnt)
                if len(max(inner_contours, key=cv2.contourArea)) >= 5:
                    M_inner = cv2.moments(max(inner_contours, key=cv2.contourArea))
                    if M_outer['m00'] > 0 and M_inner['m00'] > 0:
                        cx_outer = int(M_outer["m10"] / M_outer["m00"])
                        cy_outer = int(M_outer["m01"] / M_outer["m00"])
                        cx_inner = int(M_inner["m10"] / M_inner["m00"])
                        cy_inner = int(M_inner["m01"] / M_inner["m00"])
                        distance = np.sqrt((cx_outer - cx_inner) ** 2 + (cy_outer - cy_inner) ** 2)
                        if distance < 5:
                            # 外沿圆以及圆心用蓝色绘制
                            cv2.circle(result, (cx_outer, cy_outer), 5, (255, 0, 0), -1)
                            outer_ellipse = cv2.fitEllipse(cnt)
                            cv2.ellipse(result, outer_ellipse, (255, 0, 0), 2)
                            # 内沿圆以及圆心用绿色绘制
                            inner_ellipse = cv2.fitEllipse(max(inner_contours, key=cv2.contourArea))
                            cv2.ellipse(result, inner_ellipse, (0, 255, 0), 2)
                            cv2.circle(result, (cx_inner, cy_inner), 5, (0, 255, 0), -1)
                            green_cx = cx_inner
    if green_cx is not None:
        # 计算圆心偏移量(像素)
        pixel_offset = green_cx - frame_center_x
        # 找到外沿椭圆
        outer_contour = max(contours, key=cv2.contourArea)
        if len(outer_contour) >= 5:
            outer_ellipse = cv2.fitEllipse(outer_contour)
            (_, _), (outer_a, outer_b), _ = outer_ellipse
            # 计算像素与实际长度的比例
            outer_avg_axis_pixel = (outer_a + outer_b) / 2
            outer_avg_axis_actual = (12 + 12) / 2  # 外沿实际直径平均值
            scale = outer_avg_axis_actual / outer_avg_axis_pixel
            # 计算实际偏移量(mm)
            actual_offset = pixel_offset * scale
            # 显示实际偏移量
            text = f"Actual Offset: {actual_offset:.2f} mm"
            cv2.putText(result, text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
            # 显示
    cv2.imshow('Color  Segmentation', result)
    key = cv2.waitKey(1)
    if key == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()
v_

本文标签: 及圆心用 编程 偏移量