2

Pythonスクリプトは、ソケットからpng画像を読み込み、遅いビデオのようにOpenCVで表示しようとします。server.pyとWorker.pyの2つのクラスがあります。Server.pyは、ソケットから生のpngを受け取り、それをキューに入れます。独自のスレッドで、ワーカーはpngをデキューして表示します。最初の画像のみが正しく表示されます。ShowImageとWaitKeyが呼び出されても、他の画像は表示されません(つまり、最初の画像が残ります)。

スレッドモデルは正しいですか?サーバーソケットスレッドがOpenCVスレッドの表示を妨げているようです。サーバーソケットをバックグラウンドスレッドに配置する方法はありますか?バックグラウンドスレッドからShowWIndowとWaitKeyを呼び出すのは正しいですか?MacでのPythonまたはOpenCVスレッドについてはよくわかりません。コメントや提案をいただければ幸いです。

server.py:

#! /usr/bin/env python
import sys
import SocketServer
import socket
import subprocess
import time
import cv
import Worker
import ShowImage

HOST = 'andrew-rosenblums-macbook-pro.local'
PORT = 3001
FRAME_SIZE = 144*192
data = ''
worker = Worker.Worker()

class SingleTCPHandler(SocketServer.BaseRequestHandler):
    imagesSaved = 0

    "One instance per connection.  Override handle(self) to customize action."
    def handle(self):
        # self.request is the client connection
        print "connection received.."
        while True:
            #print "calling rcv"
            messageLength = self.request.recv(6)  # Read 6 ascii char image size
            cv.WaitKey(30)
            if (len(messageLength) > 0):
                print "messageLength=" + messageLength
                iLength = int(messageLength)
                message = ''
                while (iLength > 0):
                    if (iLength > 1024):
                        chunk = self.request.recv(1024)
                    else:
                        chunk = self.request.recv(iLength)
                    iLength -= len(chunk)
                    message += chunk
                print "rcvd imsg of len=" + str(len(message))
                worker.write(message)

                if (SingleTCPHandler.imagesSaved == 0):
                    SingleTCPHandler.imagesSaved += 1

        print "closing stream"
        self.request.close()
        print "done receiving"

    def finish(self):
        print "finish called"

class SimpleServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    # Ctrl-C will cleanly kill all spawned threads
    daemon_threads = True
    # much faster rebinding
    allow_reuse_address = True

    def __init__(self, server_address, RequestHandlerClass):
        SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass)

if __name__ == "__main__":
    server = SimpleServer((HOST, PORT), SingleTCPHandler)
    # terminate with Ctrl-C
    try:
        print "waiting for connections..."
        server.serve_forever()
    except KeyboardInterrupt:
        sys.exit(0)

Worker.py

#! /usr/bin/env python
import time
from threading import Thread
from Queue import Queue
import sys
import cv
import cv2
import numpy as np
import Image
from cStringIO import StringIO

class Worker(Thread):

    count = 0

    def __init__(self):
        Thread.__init__(self)

        self.cvImage = None
        cv.NamedWindow('display')
        cv.MoveWindow('display', 10, 10)

        self.queue = Queue()
        self.writer = None
        # Daemon threads won't prevent process from exiting
        self.setDaemon(True)

        # Start ourselves automatically
        self.start()
        print "Worker started"

    def run(self):
        writer = None
        while 1:
            frame = None

            try:
                #frame = self.queue.get(block=False)
                frame = self.queue.get()
                print "display izeof rawImage=" + str(len(frame))

               #convert to mat
                pilImage = Image.open(StringIO(frame));#.convert("RGB");

                bgrImage = np.array(pilImage)

                cvBgrImage = cv.fromarray(bgrImage)
                self.cvImage = cv.CreateImage(cv.GetSize(cvBgrImage),8,3)
                cv.CvtColor(cvBgrImage, self.cvImage, cv.CV_BGR2RGB)

                #show it
                cv.ShowImage('display', self.cvImage)
                cv.WaitKey(30)
                self.cvImage = None
            except:
                frame = None

        print "done with thread"

    # Requests from main thread
    def write(self, frame):
        self.queue.put(frame)

    def stop(self):
        self.queue.put(None)
4

1 に答える 1

3

答えは簡単です。OpenCVShowImageWaitKeyあり、メインスレッドに存在する必要があります。これはGUIスレッドだと思います。ServerSocketsは独自のスレッドにプッシュされました。これはPythonでは驚くほど簡単です。

必要なのは次のようなものだけです。

UDPThread = Thread(target = UDPServer.run)
s.start(UPDThread)
于 2012-07-26T13:40:53.380 に答える