繁体   English   中英

Python,使用鼠标点击在网络摄像头视频上绘制多边形以检测点

[英]Python, drawing a polygon over webcam video using mouse clicks to detect points

我正在使用 Python3 和 OpenCV (4.1.0) 来实现一个脚本:

  • 显示网络摄像头的内容;
  • 记录鼠标点击视频的坐标;
  • 按下某个按钮(在我的示例中为“p”)后,在先前鼠标点击确定的点之间绘制一条折线;

到目前为止,我正在尝试:

import numpy as np
import cv2


def main():
    cap = cv2.VideoCapture("files/long_video.mp4")  # Open video file

    points = []
    while (cap.isOpened()):
        ret, frame = cap.read()  # read a frame
        try:
            cv2.imshow('Frame', frame)
        except:
            print('EOF')
            break

        cv2.setMouseCallback('Frame', left_click_detect, points)


        # Abort and exit with 'Q'
        key = cv2.waitKey(25)
        if (key == ord('q')):
            break
        elif (key== ord('p')): # HERE, IT SHOULD DRAW POLYLINE OVER VIDEO!!!
            pts_array = np.array([[x, y] for (x, y) in points], np.int0)
            frame = cv2.polylines(frame, np.int32(np.array(points)), False, (255, 0, 0), thickness=5)
            points = []

        cv2.imshow('Frame', frame)


    cap.release()  # release video file
    cv2.destroyAllWindows()  # close all openCV windows


def left_click(event, x, y, flags, points):
    if (event == cv2.EVENT_LBUTTONDOWN):
        print(f"\tClick on {x}, {y}")
        points.append([x,y])

它有点工作,但按“p”后,它不会在视频上绘制折线。 有什么建议?

您的代码有两个问题:

  1. cv2.polylines()接受数组列表。 所以在这里:

    frame = cv2.polylines(frame, np.int32(np.array(points)), False, (255, 0, 0), thickness=5)

    np.int32(np.array(points))替换为[np.int32(points)]以修复异常。 (你也不需要在这里使用np.array()

  2. 在帧上绘制多边形后,您调用cv2.show() ,但几乎立即之后,您将显示没有多边形的下一帧,因此您没有时间查看多边形。 要修复它,您需要为每一帧再次绘制多边形。 为此,您需要保存它,直到再次按p (以显示另一个多边形)。

这将起作用:

import numpy as np
import cv2


def main():
    cap = cv2.VideoCapture("files/long_video.mp4")  # Open video file

    polygon = []
    points = []
    while (cap.isOpened()):
        ret, frame = cap.read()  # read a frame
        if not ret:
            print('EOF')
            break

        frame = cv2.polylines(frame, polygon, False, (255, 0, 0), thickness=5)

        cv2.imshow('Frame', frame)
        # Abort and exit with 'Q'
        key = cv2.waitKey(25)
        if (key == ord('q')):
            break
        elif (key== ord('p')): 
            polygon = [np.int32(points)]
            points = []

        cv2.setMouseCallback('Frame', left_click_detect, points)


    cap.release()  # release video file
    cv2.destroyAllWindows()  # close all openCV windows


def left_click_detect(event, x, y, flags, points):
    if (event == cv2.EVENT_LBUTTONDOWN):
        print(f"\tClick on {x}, {y}")
        points.append([x,y])
        print(points)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM