import cv2
import numpy as np

def detect_parallelograms(image):
    # 预处理图像
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    _, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

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

    parallelograms = []
    for contour in contours:
        # 近似轮廓
        epsilon = 0.02 * cv2.arcLength(contour, True)
        approx = cv2.approxPolyDP(contour, epsilon, True)

        # 判断是否为四边形
        if len(approx) == 4:
            # 计算面积
            area = cv2.contourArea(approx)
            if area > 1000:  # 设置面积过滤阈值
                parallelograms.append(approx)

    return parallelograms

def detect_red_laser(image):
    # 将图像转换为HSV颜色空间
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

    # 定义红色范围
    lower_red = np.array([0, 100, 100])
    upper_red = np.array([10, 255, 255])
    lower_red2 = np.array([160, 100, 100])
    upper_red2 = np.array([179, 255, 255])

    # 创建红色掩膜
    mask1 = cv2.inRange(hsv, lower_red, upper_red)
    mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
    mask = cv2.bitwise_or(mask1, mask2)

    # 查找红色激光点
    contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    laser_points = []
    for contour in contours:
        # 计算轮廓的中心点
        M = cv2.moments(contour)
        cX = int(M['m10'] / M['m00'])
        cY = int(M['m01'] / M['m00'])
        laser_points.append((cX, cY))

    return laser_points

def get_coordinates(parallelogram):
    # 获取四个顶点的坐标
    vertices = []
    for vertex in parallelogram:
        x, y = vertex[0]
        vertices.append((x, y))

    # 计算中心点坐标
    center_x = int((vertices[0][0] + vertices[2][0]) / 2)
    center_y = int((vertices[0][1] + vertices[2][1]) / 2)
    center = (center_x, center_y)

    return vertices, center

def main():
    cap = cv2.VideoCapture(0)

    while True:
        ret, frame = cap.read()

        parallelograms = detect_parallelograms(frame)
        laser_points = detect_red_laser(frame)

        for parallelogram in parallelograms:
            vertices, center = get_coordinates(parallelogram)

            # 绘制四边形
            cv2.drawContours(frame, [parallelogram], 0, (0, 255, 0), 2)

            # 在图像上标记顶点和中心点
            for vertex in vertices:
                cv2.circle(frame, vertex, 4, (0, 0, 255), -1)
            cv2.circle(frame, center, 4, (255, 0, 0), -1)

            # 打印坐标到控制台
            x1, y1 = vertices[0]
            x2, y2 = vertices[1]
            x3, y3 = vertices[2]
            x4, y4 = vertices[3]
            xc, yc = center
            print('Vertex 1: ({}, {})'.format(x1, y1))
            print('Vertex 2: ({}, {})'.format(x2, y2))
            print('Vertex 3: ({}, {})'.format(x3, y3))
            print('Vertex 4: ({}, {})'.format(x4, y4))
            print('Center: ({}, {})'.format(xc, yc))
            print()

        # 在图像上标记红色激光点
        for laser_point in laser_points:
            cv2.circle(frame, laser_point, 4, (0, 255, 255), -1)

        # 显示图像
        cv2.imshow('Parallelogram Detection', frame)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    cap.release()
    cv2.destroyAllWindows()
    
if __name__ == '__main__':
    main()
OpenCV实时检测平行四边形和红色激光点

原文地址: https://www.cveoy.top/t/topic/fxIg 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录