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

Python,使用鼠标单击在网络摄像头视频上绘制多边形以检测点,python,opencv,Python,Opencv,我正在使用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 = []

我正在使用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”后,它不会在视频上绘制多段线。
有什么建议吗?

您的代码有两个问题:

  • cv2.polylines()
    接受数组列表。因此,这里:

    frame=cv2.多段线(frame,np.int32(np.array(points)),False,(255,0,0),厚度=5)

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

  • 在帧上绘制多边形后,可以调用
    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)