Запуск opencv в потоке, невозможно запустить второй раз - PullRequest
0 голосов
/ 20 марта 2020

Когда я пытаюсь запустить openv c в потоке, он работает один раз, но после того, как я вызову его второй раз, он не запустится снова. Код застрял, когда он достигает функции cv2 в этом случае cv2.imshow () (но после cv2.VideoCapture ()). Если я вызываю функцию start_videofeed () сразу после получения сигнала сокета, он работает правильно, но я хотел бы, чтобы sock.recvfrom () продолжал получать другие команды.

Этот код является лишь небольшим примером моего сценария, но я много пробовал и также искал в Интернете, но не смог найти ответа, только другие с похожими проблемами.

Я использую последний пакет opencv- python, с python3 .8 на manjaro.

Надеюсь, кто-нибудь знает ответ, как решить эту проблему.

Заранее спасибо.

import socket
from threading import Thread
import cv2


class VideoFeed():
    def __init__(self):
        self.url = 0
        self.window_name = "Video"


    def run(self):
        sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
        sock.bind( ('',54666) )

        while True:
            d, addr = sock.recvfrom( 1024 )
            payload = d.decode()
            if payload == "show_video":
                self.start_video()
            if payload == "exit":
                break

    def start_video(self):
        vs = Thread(target=self.start_videofeed)
        vs.start()



    def start_videofeed(self): 
        cap = cv2.VideoCapture(self.url) 
        if (cap.isOpened()== False):  
          print("Error opening video file")
        print("Starting videofeed") 
        while True:
            ret, self.frame = cap.read() 
            cv2.imshow(self.window_name, self.frame)
            key = cv2.waitKey(10)

            if key == 27 or key == ord('q'):
                break
            if cv2.getWindowProperty(self.window_name, cv2.WND_PROP_VISIBLE) < 1:        
                break


        cv2.destroyAllWindows()
        cap.release()
        print("Video release and Destroy")
        return



vf = VideoFeed()
vf.run()

Редактировать:

Я наконец нашел ответ. Кажется, что невозможно запустить видео из потока или во второй раз, поэтому я установил логическое значение в потоке сокета, чтобы запустить видео подачу из основной программы.

class VideoFeed():
    def __init__(self):
        self.url = "http://192.168.178.103:8081"
        self.window_name = "Video"
        self.start_video = False

    def run(self):
        Thread(target=self.start_socket).start()

        while True:
            if self.start_video:
                self.start_videofeed()
                self.start_video = False



    def start_socket(self):
        sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
        sock.bind( ('',54666) )

        while True:
            d, addr = sock.recvfrom( 1024 )
            payload = d.decode()
            if payload == "show_video":
                self.start_video = True
            if payload == "exit":
                break


    def start_videofeed(self): 
        cap = cv2.VideoCapture(self.url) 
        if (cap.isOpened()== False):  
          print("Error opening video file")
        print("Starting videofeed") 
        while True:
            ret, self.frame = cap.read() 
            cv2.imshow(self.window_name, self.frame)
            key = cv2.waitKey(10)

            if key == 27 or key == ord('q'):
                break
            if cv2.getWindowProperty(self.window_name, cv2.WND_PROP_VISIBLE) < 1:        
                break


        cv2.destroyAllWindows()
        cap.release()
        print("Video release and Destroy")
        return

...