OpenCV: как нарисовать только первый кадр видеофайла, а затем продолжить показ всего видео - PullRequest
1 голос
/ 16 мая 2019

Я использую opencv-библиотеку в python. Я открыл существующий видеофайл и написал небольшой скрипт, который позволяет рисовать прямоугольник в любом месте видео. Проблема в том, что я хочу нарисовать этот прямоугольник в первом кадре видео, а затем оставить его там, чтобы отметить интересующую меня область.

Я использую cv2.imshow(winname, frame), чтобы показать мое видео. Поскольку это запускает / показывает видео с очень высокой частотой кадров в секунду (и я не хочу это менять, поскольку мое видео довольно длинное), когда я начинаю рисовать прямоугольник, многие кадры уже были показаны.

Поскольку я думаю, что это может быть полезно, вот мой код: импорт cv2

#mouse callback function#
def draw_rectangle(event, x, y, flags, param):

    global pt1, pt2, topLeft_clicked, bottomRight_clicked

    #mouse click
    if event == cv2.EVENT_LBUTTONDOWN:
        #reset
        if topLeft_clicked and bottomRight_clicked:
            topLeft_clicked = False
            bottomRight_clicked = False
            pt1 = (0,0)
            pt2 = (0,0)
        #get coordinates of top left corner
        if not topLeft_clicked:
            pt1 = (x,y)
            topLeft_clicked = True
        #get coordinates of bottom right corner
        elif not bottomRight_clicked:
            pt2 = (x,y)
            bottomRight_clicked = True

#start actual program 

#initially we haven't drawn anything
pt1 = (0,0)
pt2 = (0,0)
topLeft_clicked = False
bottomRight_clicked = False

#capture video
cap = cv2.VideoCapture('Path to video')
cv2.namedWindow(winname='myName')
cv2.setMouseCallback('myName', draw_rectangle)

firstFrame = True
while True: 
    ret, frame = cap.read()
    gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    while ret and firstFrame: 
        cv2.imshow('myName', gray_frame)

        if topLeft_clicked: 
            cv2.circle(gray_frame, center=pt1, radius=5, color=(255,0,0), thickness=-1)

        if topLeft_clicked and bottomRight_clicked: 
            cv2.rectangle(gray_frame, pt1, pt2, (255,0,0), 2)
            firstFrame = False

    cv2.imshow('Estimate_Velocity', gray_frame)

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

cap.release()
cv2.destroyAllWindows()

Ответы [ 2 ]

0 голосов
/ 17 мая 2019

Я немного поэкспериментировал и нашел следующее решение моей проблемы:

import cv2

#mouse callback function#
def draw_rectangle(event, x, y, flags, param):

    global pt1, pt2, topLeft_clicked, bottomRight_clicked

    #mouse click
    if event == cv2.EVENT_LBUTTONDOWN:
        #reset
        if topLeft_clicked and bottomRight_clicked:
            topLeft_clicked = False
            bottomRight_clicked = False
            pt1 = (0,0)
            pt2 = (0,0)
        #get coordinates of top left corner
        if not topLeft_clicked:
            pt1 = (x,y)
            topLeft_clicked = True
        #get coordinates of bottom right corner
        elif not bottomRight_clicked:
            pt2 = (x,y)
            bottomRight_clicked = True

#start actual program 

#initially we haven't drawn anything
pt1 = (0,0)
pt2 = (0,0)
topLeft_clicked = False
bottomRight_clicked = False

#capture video
cap = cv2.VideoCapture('Video path')
cv2.namedWindow(winname='myName')
cv2.setMouseCallback('myName', draw_rectangle)

firstFrame = True
while True: 
    ret, frame = cap.read()
    gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    while firstFrame: 
        cv2.imshow('myName', gray_frame)

        if topLeft_clicked: 
            cv2.circle(gray_frame, center=pt1, radius=5, color=(255,0,0), thickness=-1)

        if topLeft_clicked and bottomRight_clicked: 
            cv2.rectangle(gray_frame, pt1, pt2, (255,0,0), 2)

        if cv2.waitKey(1) &0xFF == ord('c'):
            firstFrame = False
            break

    if topLeft_clicked and bottomRight_clicked: 
        cv2.rectangle(gray_frame, pt1, pt2, (255,0,0), 2)

    cv2.imshow('myName', gray_frame)

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

cap.release()
cv2.destroyAllWindows()
0 голосов
/ 17 мая 2019

Я еще не проверял это, но вы можете изменить ваше while условие разрыва цикла:

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

на

if (topLeft_clicked and bottomRight_clicked):
    if cv2.waitKey(1)  &0xFF == ord('q'):
        break
else:
     # change 1 to 0
     cv2.waitKey(0)

Вам нужно будет нажать клавишу послеВы рисуете коробку.

...