代码之家  ›  专栏  ›  技术社区  ›  Natim

使用OpenCV Camera Capture在PyQt4中显示网络摄像头流

  •  5
  • Natim  · 技术社区  · 14 年前

    我使用这个Python脚本来显示我的网络摄像头:

    from opencv.cv import *  
    from opencv.highgui import *  
    
    import sys
    
    cvNamedWindow("w1", CV_WINDOW_AUTOSIZE)
    camera_index = 0
    capture = cvCreateCameraCapture(camera_index)
    
    def repeat():
        global capture #declare as globals since we are assigning to them now
        global camera_index
        frame = cvQueryFrame(capture)
        cvShowImage("w1", frame)
        c = cvWaitKey(10)
    
        if c == "q":
            sys.exit(0)
    
    if __name__ == "__main__":
        while True:
            repeat()
    

    我怎么用这个 IplImage 将OpenCV图像转换为Qt VideoWidget ?

    3 回复  |  直到 8 年前
        1
  •  2
  •   William Dias    12 年前

    我用下面的代码把一个Iplimage对象转换成一个QImage。我花了一些时间才弄到正确的格式。Iplimage是3通道格式,具有BGR通道顺序,而QImage使用RGB通道顺序。

    camcapture = cv.CaptureFromCAM(0)       
    cv.SetCaptureProperty(camcapture,cv.CV_CAP_PROP_FRAME_WIDTH, 1280)
    cv.SetCaptureProperty(camcapture,cv.CV_CAP_PROP_FRAME_HEIGHT, 720);
    
    frame = cv.QueryFrame(camcapture)
    image = QImage(frame.tostring(), frame.width, frame.height, QImage.Format_RGB888).rgbSwapped()
    pixmap = QPixmap.fromImage(image)
    
        2
  •  3
  •   Natim    14 年前

    看起来我们需要在Python中绑定这个C++代码:

    QImage& cvxCopyIplImage(const IplImage *pIplImage, QImage &qImage)
    {
            if(!CV_IS_IMAGE(pIplImage)) return qImage;
    
            int w = pIplImage->width;
            int h = pIplImage->height;
    
    
            if(qImage.width() != w || qImage.height() != h)
            {
                    qImage = QImage(w, h, QImage::Format_RGB32);
            }
    
            int x, y;
            for(x = 0; x < pIplImage->width; ++x)
            {
                    for(y = 0; y < pIplImage->height; ++y)
                    {
                            CvScalar color = cvGet2D(pIplImage, y, x);
    
                            if(pIplImage->nChannels == 1)
                            {
                                    int v = color.val[0];
    
                                    qImage.setPixel(x, y, qRgb(v,v,v));
                            }
                            else
                            {
                                    int r = color.val[2];
                                    int g = color.val[1];
                                    int b = color.val[0];
    
                                    qImage.setPixel(x, y, qRgb(r,g,b));
                            }
                    }
            }
    
            if(pIplImage->origin != IPL_ORIGIN_TL)
            {
                    qImage = qImage.mirrored(false, true);
            }
    
            return qImage;
    }
    
        3
  •  0
  •   Tim Cooper    13 年前

    这个对我有用。我使用Python 2.6.5在Linux上工作:

    import base64
    import Image
    import time
    import urllib2
    import cv
    
    # Basic HTTP Authentication...
    url = 'http://192.168.0.11:82/Videostream.cgi'
    ww = 'Username:Password'
    encodedstring = base64.encodestring(ww)[:-1]
    auth = "Basic %s" % encodedstring
    req = urllib2.Request(url,None, {"Authorization": auth })
    handle = urllib2.urlopen(req)
    
    def read_stream():
        buf = ''
        b = handle.readlines(45)
        for a in b:
            if a.startswith('Content-Length'):
                readlen = str(a).split()[1]
        b1 = handle.read(int(readlen)+4)
        return b1
    
    def test():
        pass
    
    def write_stream():
        imgc = read_stream()
        cv_img = cv.CreateImageHeader((640,480), cv.IPL_DEPTH_8U, 3)
        buf = Image.fromstring('RGB',(640,480),imgc[2:], 'jpeg', 'RGB', None)
        cv.SetData(cv_img, buf.tostring(), (640*3))
        return cv_img
    
    
    fps = 10.0
    
    if __name__ == "__main__":
        while True:
            frame = write_stream()
            cv.ShowImage('Camera', frame)
            k = cv.WaitKey(10)
            time.sleep(int(1.0/fps))
            if k == 0x10001b: # ESC
                cv.DestroyWindow("Camera")
                print 'ESC pressed. Exiting ...'
                break