简体   繁体   English

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

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

I'm using Python3 and OpenCV (4.1.0) to realize a script that:我正在使用 Python3 和 OpenCV (4.1.0) 来实现一个脚本:

  • displays the contents of the webcam;显示网络摄像头的内容;
  • records the coordinates of mouse clicks over video;记录鼠标点击视频的坐标;
  • after pressing a certain button ('p' in my example), draws a polyline between the points identified by previous mouse clicks;按下某个按钮(在我的示例中为“p”)后,在先前鼠标点击确定的点之间绘制一条折线;

So far, I'm trying:到目前为止,我正在尝试:

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])

It kinda works, but after pressing 'p' it doesn't draw the polyline over the video.它有点工作,但按“p”后,它不会在视频上绘制折线。 Any suggestions?有什么建议?

There are 2 problems with your code:您的代码有两个问题:

  1. cv2.polylines() accepts a list of arrays. cv2.polylines()接受数组列表。 so here:所以在这里:

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

    Replace np.int32(np.array(points)) with [np.int32(points)] to fix the exception.np.int32(np.array(points))替换为[np.int32(points)]以修复异常。 (you also don't need to use np.array() here) (你也不需要在这里使用np.array()

  2. After you draw the polygon on the frame, you call cv2.show() , but almost immediately after, you show the next frame without the polygon on it, so you don't have time to see the polygon.在帧上绘制多边形后,您调用cv2.show() ,但几乎立即之后,您将显示没有多边形的下一帧,因此您没有时间查看多边形。 to fix it you need to draw the polygon again for each frame.要修复它,您需要为每一帧再次绘制多边形。 and to do that, you need to save it until you press p again (to show another polygon).为此,您需要保存它,直到再次按p (以显示另一个多边形)。

This will work:这将起作用:

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