6

Webカメラからのopencvビデオストリームを、highguiが提供できるよりも複雑なGUIに統合したかっただけです。ボタンをいくつか追加するだけで派手なものはありませんが、それほど些細なことではないことが証明されています。GUIの設計を開始できる基本的な例が見つかりません。このコードを新しいopencvインターフェースに変換しようとしましたが、結果はかなり悪くなりました。私はopencv、numpy、GUIデザインの初心者です。ある時間はビデオをストリーミングしますが、ほとんどの場合、それはただそこにぶら下がっています。以前のバージョンではpil画像形式を使用していましたが、現在はnumpy配列を使用しているため、元のコードではpil関数「imageData」を使用していたため、私の1つの間違いはwx.BitmapFromBuffer(col、row、img)にあると思います。私がしているように、numpy配列を直接渡します。助けて」 color_channels_pic

これは私のコード変換です。

import wx
import cv2

class MyFrame(wx.Frame):
   def __init__(self, parent):
       wx.Frame.__init__(self, parent)
       self.displayPanel = wx.Panel(self)
       self.displayPanel.SetSize(wx.Size(800,640))

       self.cam = cv2.VideoCapture(1)
       self.cam.set(3, 640)
       self.cam.set(4, 480)
       ret, img = self.cam.read()

       cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
       row, col, x = img.shape
       self.SetSize((col,row))
       self.bmp = wx.BitmapFromBuffer(col, row, img)
       self.displayPanel.Bind(wx.EVT_PAINT, self.onPaint)

       self.playTimer = wx.Timer(self)
       self.Bind(wx.EVT_TIMER, self.onNextFrame)

       self.playTimer.Start(1000/15)

    def onPaint(self, evt):
        if self.bmp:
            dc = wx.BufferedPaintDC(self.displayPanel)
            self.PrepareDC(dc)
            dc.DrawBitmap(self.bmp, 0, 0, True)
        evt.Skip()

    def onNextFrame(self, evt):
        ret, img = self.cam.read()
        if ret == True:
            cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            self.bmp.CopyFromBuffer(img)
            self.displayPanel.Refresh()
        evt.Skip()

if __name__=="__main__":
    app = wx.App()
    MyFrame(None).Show()
    app.MainLoop()
4

3 に答える 3

12

次のサンプルコードはOSXで問題なく動作しますが、プラットフォーム間でwxに小さな驚きがありました。これはほぼ同じコードですが、違いは、からの結果が再割り当てされ、 (重要な部分である)cvtColorのサブクラスが追加されたことです。wx.Panel

import wx
import cv, cv2

class ShowCapture(wx.Panel):
    def __init__(self, parent, capture, fps=15):
        wx.Panel.__init__(self, parent)

        self.capture = capture
        ret, frame = self.capture.read()

        height, width = frame.shape[:2]
        parent.SetSize((width, height))
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

        self.bmp = wx.BitmapFromBuffer(width, height, frame)

        self.timer = wx.Timer(self)
        self.timer.Start(1000./fps)

        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_TIMER, self.NextFrame)


    def OnPaint(self, evt):
        dc = wx.BufferedPaintDC(self)
        dc.DrawBitmap(self.bmp, 0, 0)

    def NextFrame(self, event):
        ret, frame = self.capture.read()
        if ret:
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            self.bmp.CopyFromBuffer(frame)
            self.Refresh()


capture = cv2.VideoCapture(0)
capture.set(cv.CV_CAP_PROP_FRAME_WIDTH, 320)
capture.set(cv.CV_CAP_PROP_FRAME_HEIGHT, 240)

app = wx.App()
frame = wx.Frame(None)
cap = ShowCapture(frame, capture)
frame.Show()
app.MainLoop()
于 2013-02-11T18:02:15.943 に答える
0

キャプチャした画像を表示するには、パネルのサイズを設定する必要があります。私はあなたのコードを使用し、「

self.SetSize(width,height)

大丈夫です

于 2018-03-06T02:33:52.810 に答える
0

以下の行にコメントを追加する必要があります

#self.PrepareDC(dc)

それは私のために働いた。

于 2020-06-19T09:25:23.913 に答える