Mostrar una corriente de cámaras en PyQt4 usando la cámara de captura OpenCV
Pregunta
Estoy usando este script Python para mostrar mi cámara web:
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()
Se está trabajando bastante bien, pero me gustaría establecer esta pantalla dentro de mi aplicación Qt.
¿Cómo puedo usar la imagen IplImage
OpenCV en un VideoWidget
Qt?
Solución
He utilizado el código de abajo para convertir un objet Iplimage a un QImage. Me llevó algún tiempo para obtener los formatos adecuados. Iplimage es un formato de 3 canales con orden de los canales BGR mientras QImage utiliza orden de los canales 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)
Otros consejos
Parece que hay que unir el código C ++ en Python:
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;
}
Éste trabajó para mí. Yo trabajo en Linux con Python 2.6.5:
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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow