PDA

View Full Version : OpenCV integration



sfabel
1st February 2008, 23:16
Hi Forum,

I've been looking around on the net for this, but haven't found a satisfying solution yet. I capturing frames using my S-Video input under Linux. This works already and it works well using the OpenCV Highgui interface, their drawing functions, etc.

I would now like to integrate what I have done so far with Qt, because of various reasons: the program gets bigger and bigger, I need network support, and would like to add a more sophisticated GUI to, for example, interactively adjust threshold values, or save video files for offline use (preferably using ffmpeg).

I would have to add that I am new to Qt, but not to OpenCV or C++ programming. I have downloaded and compiled the latest version of Qt at the time of this writing (4.3.3) and successfully compiled some sample programs.

Now here are my questions:


is there someone out there working with both OpenCV and Qt 4.x already?
How can I display the captured frames in a Qt application?
Are there any recommendations as to which drawing functions should be used (e.g. which are faster?)


Thank you guys in advance for any help or pointers.

Cheers,
Stephan

wysota
2nd February 2008, 00:04
2. How can I display the captured frames in a Qt application?
3. Are there any recommendations as to which drawing functions should be used (e.g. which are faster?)


Ok, these two I am able to answer. Basically you have two choices - either using or not using OpenGL. The first approach requires you to use QGLWidget and to display images by binding them as textures (using bindTexture()) and using those textures on a rectangle (preferably square one) which you display in the GL widget. With the other approach you will be displaying images on a QLabel object using QLabel::setPixmap(). The GL approach will be much faster but requires more coding.

Oh... one more thing, just to make my post complete. Since Qt 4.4 you will be able to use Phonon which is the KDE4 multimedia framework adopted for Qt that will use a platform dependent backend - GStreamer in case of Linux/Unix (or xine when using KDE4 and the GPLed version of Qt), MediaPlayer in case of Windows (I think), etc.

sfabel
3rd February 2008, 09:47
Hi,

thanks for your answers. I tried the Pixmap method and got it to work. If you want, you could look it over and suggest a better way but for now this works for me. I was able to develop a simple test program which would display the captured image from a video source such as a camera and the user can choose from several modes of operation: Normal feedthrough of video, the same with a sobel operator applied (in X and Y direction) and with a Hough transform.

To convert the IplImage* to a QImage (and then to a QPixmap to be displayed in a QLabel), I did (roughly) this:



// the individual channels for the IplImage
tchannel0 = cvCreateImage(frame_size, IPL_DEPTH_8U, 1);
tchannel1 = cvCreateImage(frame_size, IPL_DEPTH_8U, 1);
tchannel2 = cvCreateImage(frame_size, IPL_DEPTH_8U, 1);
tchannel3 = cvCreateImage(frame_size, IPL_DEPTH_8U, 1);

// set all elements in tchannel0 (alpha channel) to 255
cvSet(tchannel0,cvScalarAll(255),0);

// with cframe being the captured frame (3 channel RGB)
// and dframe the frame to be displayed
cvSplit(cframe, tchannel1, tchannel2, tchannel3, NULL);
cvMerge(tchannel1, tchannel2, tchannel3, tchannel0, dframe);

// point to the image data stored in the IplImage*
const unsigned char * data = (unsigned char *)(dframe->imageData);

// read other parameters in local variables
int width = ocv_image->width;
int height = ocv_image->height;
int bytesPerLine = ocv_image->widthStep;

// imageframe is my QLabel object
qimage = QImage( data, width, height, bytesPerLine, QImage::Format_RGB32 );
ui.imageframe->setPixmap(pixmap->fromImage(qimage, 0));


This is just the general outline, of course and distributed throughout my code. Basically the problem is that OpenCV per se does not support an alpha channel, however it seems that Qt needs one. So I created a "fake" alpha channel and inserted it into a IplImage with 4 instead of 3 layers.

BTW: I think I found a bug in the documentation. In the format description, the QImage::Format_RGB32 is described as 0xffRRGGBB. However, it is 0xRRGGBBff. Or am I mistaken? But the above works! :)

Hope that this is of use for some other people out there.

Cheers,
Stephan

fullmetalcoder
3rd February 2008, 10:01
BTW: I think I found a bug in the documentation. In the format description, the QImage::Format_RGB32 is described as 0xffRRGGBB. However, it is 0xRRGGBBff. Or am I mistaken? But the above works! :)
I expect it depends on the endianness (http://en.wikipedia.org/wiki/Endianness) of your system...

sfabel
4th February 2008, 06:27
If it depended on the endianess of my system, it would be 0xBBGGRRff instead of 0xffRRGGBB, wouldn't it?

But since only the position of the alpha channel is changed I don't think it has anything to do with it.

Cheers,
Stephan

pherthyl
4th February 2008, 18:50
Hi Stephan,

I'm currently putting together a small project for a computer vision grad class I'm taking. Eventually it will be a head tracker, but right now it's just the general capturing framework that I will use. I did some benchmarking on different approaches to copying opencv data to a QImage, and ended up with the code posted here: http://www.qtcentre.org/forum/p-qimage-data-via-ffmpeg-post61293/postcount7.html

I've also put together a simple framework for capturing and frame processing that you might find useful. I've attached the code for it. Just run qmake and make. Should work for most supported cameras.

It's multithreaded, so the capture thread spins getting frames as fast as possible and putting them into a buffer. Then the processing thread grabs frames out of that buffer and does whatever processing you want to do on the IplImage. Then the result gets loaded into a structure and passed through a chain of filters, ending with the widget that will contain the Image in the Qt GUI. Right now I do no processing and have no filters written yet, but the framework should work well for most computer vision tasks. I used a similar architecture for our eye tracking system and it works very well.

The display of the image uses a custom widget that paints it on the paintevent. I couldn't use OGL because my laptop video drivers are crap and it won't run. It should be about as fast as it can go without OGL though. Using Qt::WA_OpaquePaintEvent and Qt::WA_PaintOnScreen gives a nice speedup over the defaults.

nooky59
21st February 2008, 10:13
Hi,

Thanks for your code sample.

Just a question, is there any particular reason for not using the cvcam library bundled with opencv ? I have made a quick review of the code and I have noticed that you didn't used methods from cvcam.h

Your feedback on it could be very instructive.

pherthyl
21st February 2008, 18:30
I don't really have a good answer for you. I didn't use cvCam just because I haven't used it before, it seems to have less documentation (it's not even mentioned on the OpenCV wiki as far as I can tell), and highgui functions can do similar things.

However, if you are trying to build a real application that needs robust and full featured camera access, then I would advise against both highgui and cvcam. They are both more or less hacks that give you basic camera access but have all sorts of problems once you start using them for anything serious. For example, although highgui claims to be able to set things like camera resolution, framerate, and colour balance, in reality it doesn't actually work for most cameras.

If you have a good machine vision camera, use their provided SDK. It will always be miles better than the functions in opencv. Otherwise the way to go is to use the V4L api in Linux and the DirectX SDK in Windows. For example I have an Asus EeePC and the built in camera doesn't work properly with OpenCv at all, while it works fine in linux video apps and Windows video apps that don't use OpenCV.

nooky59
22nd February 2008, 22:53
Thanks for your answer. Requirements for the projects are minimal for the moment so I don't think I need to deal with DirectShow or specific webcam driver.

For the eeePC, perhaps you should try with cvcam. I have tested succesfully with my logitech cam but this evening, I'm searching more informations on the benefits of cvcam against highgui and I've read this on a french forum :


else I know I was using capturefromcam (highgui.h) before with a logitech webcam and it was working like a charm, but when I switched to a wireless webcam and a video acquisition card, capturefromcam didn't worked anymore so I've used cvcam with the callback function and it work perfectly, so I think it support all webcams as long as drivers are installed

Perhaps it is worth a try ? Let me know if you get it working with eeePC both on Windows and Linux.

Here is a quick code sample :



#include <QtGui>
#include "mywidget.h"
#include "cvcam.h"
#include "cxcore.h"
#include "cxtypes.h"

void callback(IplImage* frame);

MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
{
int ncams = cvcamGetCamerasCount();
cvcamSetProperty(0, CVCAM_PROP_ENABLE, CVCAMTRUE);
cvcamSetProperty(0, CVCAM_PROP_RENDER, CVCAMTRUE);

cvcamWindow myWin = (cvcamWindow) winId();
cvcamSetProperty(0, CVCAM_PROP_WINDOW, &myWin);

int width = 640;
int height = 480;
cvcamSetProperty(0, CVCAM_RNDWIDTH, &width);
cvcamSetProperty(0, CVCAM_RNDHEIGHT, &height);

cvcamSetProperty(0, CVCAM_PROP_CALLBACK, callback);

cvcamInit();
cvcamStart();
}



void callback(IplImage* frame)
{
// Do what you want with IplImage
}


I haven't bundled the termination code but you will found it in the RTF doc bundled with OpenCV. As there is some mistakes in the first code sample from the doc, I think the above code should help you (even if the remaining of the RTF is useful to understand and perhaps a litte more accurate ;o))

patrik08
3rd June 2008, 22:47
I put this QImage IplImageToQImage here on this thread if people like to search...
I tested on QT4.4 and run ok....

from QPainter p(&gd); forward is only a date print...
I write & copy this piece to a label :
Animated Portable Network Graphics APNG , which run on Firefox 3 or opera...
http://www.qt-apps.org/content/show.php/Apng+Video+Frame+Label?content=82221





#ifdef OPCAMENABLE

#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <ctype.h>

static QImage IplImageToQImage(const IplImage *iplImage, uchar **data , bool mirroRimage = true )
{
uchar *qImageBuffer = NULL;
int width = iplImage->width;

/*
* Note here that OpenCV image is stored so that each lined is 32-bits aligned thus
* explaining the necessity to "skip" the few last bytes of each line of OpenCV image buffer.
*/
int widthStep = iplImage->widthStep;
int height = iplImage->height;

switch (iplImage->depth)
{
case IPL_DEPTH_8U:
if (iplImage->nChannels == 1)
{
/* OpenCV image is stored with one byte grey pixel. We convert it to an 8 bit depth QImage. */
qImageBuffer = (uchar *)malloc(width * height * sizeof(uchar));
uchar *QImagePtr = qImageBuffer;
const uchar *iplImagePtr = (const uchar *)iplImage->imageData;
for (int y = 0; y < height; ++y)
{
// Copy line by line
memcpy(QImagePtr, iplImagePtr, width);
QImagePtr += width;
iplImagePtr += widthStep;
}
}
else if (iplImage->nChannels == 3)
{
/* OpenCV image is stored with 3 byte color pixels (3 channels). We convert it to a 32 bit depth QImage. */
qImageBuffer = (uchar *)malloc(width * height * 4 * sizeof(uchar));
uchar *QImagePtr = qImageBuffer;
const uchar *iplImagePtr = (const uchar *)iplImage->imageData;

for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
{
// We cannot help but copy manually.
QImagePtr[0] = iplImagePtr[0];
QImagePtr[1] = iplImagePtr[1];
QImagePtr[2] = iplImagePtr[2];
QImagePtr[3] = 0;

QImagePtr += 4;
iplImagePtr += 3;
}
iplImagePtr += widthStep - 3 * width;
}
}
else
qDebug("IplImageToQImage: image format is not supported : depth=8U and %d channels\n", iplImage->nChannels);

break;

case IPL_DEPTH_16U:
if (iplImage->nChannels == 1)
{
/* OpenCV image is stored with 2 bytes grey pixel. We convert it to an 8 bit depth QImage. */
qImageBuffer = (uchar *)malloc(width * height * sizeof(uchar));
uchar *QImagePtr = qImageBuffer;
const uint16_t *iplImagePtr = (const uint16_t *)iplImage->imageData;

for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
*QImagePtr++ = ((*iplImagePtr++) >> 8); // We take only the highest part of the 16 bit value. It is similar to dividing by 256.
iplImagePtr += widthStep / sizeof(uint16_t) - width;
}
}
else
qDebug("IplImageToQImage: image format is not supported : depth=16U and %d channels\n", iplImage->nChannels);

break;

case IPL_DEPTH_32F:
if (iplImage->nChannels == 1)
{
/* OpenCV image is stored with float (4 bytes) grey pixel. We convert it to an 8 bit depth QImage. */
qImageBuffer = (uchar *)malloc(width * height * sizeof(uchar));
uchar *QImagePtr = qImageBuffer;
const float *iplImagePtr = (const float *)iplImage->imageData;

for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
*QImagePtr++ = (uchar)(255 * ((*iplImagePtr++)));
iplImagePtr += widthStep / sizeof(float) - width;
}
}
else
qDebug("IplImageToQImage: image format is not supported : depth=32F and %d channels\n", iplImage->nChannels);

break;

case IPL_DEPTH_64F:
if (iplImage->nChannels == 1)
{
/* OpenCV image is stored with double (8 bytes) grey pixel. We convert it to an 8 bit depth QImage. */
qImageBuffer = (uchar *) malloc(width * height * sizeof(uchar));
uchar *QImagePtr = qImageBuffer;
const double *iplImagePtr = (const double *) iplImage->imageData;

for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
*QImagePtr++ = (uchar)(255 * ((*iplImagePtr++)));
iplImagePtr += widthStep / sizeof(double) - width;
}
}
else
qDebug("IplImageToQImage: image format is not supported : depth=64F and %d channels\n", iplImage->nChannels);

break;

default:
qDebug("IplImageToQImage: image format is not supported : depth=%d and %d channels\n", iplImage->depth, iplImage->nChannels);
}

QImage *qImage;
if (iplImage->nChannels == 1)
{
QVector<QRgb> colorTable;
for (int i = 0; i < 256; i++)
colorTable.push_back(qRgb(i, i, i));

qImage = new QImage(qImageBuffer, width, height, QImage::Format_Indexed8);
qImage->setColorTable(colorTable);
}
else
qImage = new QImage(qImageBuffer, width, height, QImage::Format_RGB32);
QImage gd0 = qImage->mirrored(false,mirroRimage);
*data = qImageBuffer;
QColor textColor = Qt::black;
QColor fillrectcolor = Qt::red;
QColor shapepicture = Qt::white;
QImage gd = gd0.scaledToWidth(350);
QDateTime now = QDateTime::currentDateTime ();
QString selectionText = now.toString("dd.MM.yyyy hh:mm:ss");
QPainter p(&gd);
p.setRenderHint(QPainter::Antialiasing, true);

QFontMetrics fm( qApp->font() );
int stringWidth = fm.width(selectionText);
int stringHeight = fm.ascent();
const int sx = gd.width() - stringWidth - 5;
QPen pen;
pen.setStyle( Qt::SolidLine );
pen.setWidth( 2 );
pen.setColor( textColor );
p.setPen( pen);
p.drawText(QPointF(sx - 1 ,gd.height() - 2 - stringHeight - 1),selectionText);
pen.setColor( fillrectcolor );
p.setPen( pen);
p.drawText(QPointF(sx,gd.height() - 2 - stringHeight),selectionText);

return gd;
}



#endif

patelmiteshn
18th March 2009, 00:43
Hello Forum,

I'm new to both QT and OpenCV. I've written couple of program in OpenCV and works well and done the same with QT so botht the tools are working well.

I'm trying to integrate the code posted by "pherthyl" to stream the video data caputured by the webcam in opencv. The application is really well written (for me as I can understand it). When i try and build it says that cannot find "opencv/highgui.h"

I've installed opencv in /opt/opencv and all the files are viz. highgui.h, cxcore.h, cv.h are located in /opt/opencv/include/opencv.

I tried and compile the project by changing the path of highgui.h in capturethread.h from opencv/highgui.h to opt/opencv/include/opencv/highgui.h but still it gives the same error that it couldn't locate the files.

Is there any specific changes that I need to make in the MAKEFILE which will specify the location of these files and link it.

Thanks in advance.

Regards,
Mitesh

kosirm
8th July 2009, 14:20
Hi Stephan,

I'm currently putting together a small project for a computer vision grad class I'm taking. Eventually it will be a head tracker, but right now it's just the general capturing framework that I will use. I did some benchmarking on different approaches to copying opencv data to a QImage, and ended up with the code posted here: http://www.qtcentre.org/forum/p-qimage-data-via-ffmpeg-post61293/postcount7.html

I've also put together a simple framework for capturing and frame processing that you might find useful. I've attached the code for it. Just run qmake and make. Should work for most supported cameras.

It's multithreaded, so the capture thread spins getting frames as fast as possible and putting them into a buffer. Then the processing thread grabs frames out of that buffer and does whatever processing you want to do on the IplImage. Then the result gets loaded into a structure and passed through a chain of filters, ending with the widget that will contain the Image in the Qt GUI. Right now I do no processing and have no filters written yet, but the framework should work well for most computer vision tasks. I used a similar architecture for our eye tracking system and it works very well.

The display of the image uses a custom widget that paints it on the paintevent. I couldn't use OGL because my laptop video drivers are crap and it won't run. It should be about as fast as it can go without OGL though. Using Qt::WA_OpaquePaintEvent and Qt::WA_PaintOnScreen gives a nice speedup over the defaults.


Thanks for code!
I'm running example and capture frame size isn't changing, it seems to me that cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 640); does nothing. Or have I missed something?

if(size == Size640) {
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 640);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 480);
qDebug() << "Setting 640x480:CV_CAP_PROP_FRAME_WIDTH:" << cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
qDebug() << "Setting 640x480CV_CAP_PROP_FRAME_HEIGHT:" << cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

}

returns:
Setting 640x480:CV_CAP_PROP_FRAME_WIDTH: 320
Setting 640x480CV_CAP_PROP_FRAME_HEIGHT: 240

Any ideas how could I change frame width/height?
Best regards,
Milan

pherthyl
10th July 2009, 01:00
Thanks for code!
I'm running example and capture frame size isn't changing, it seems to me that cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 640); does nothing. Or have I missed something?

if(size == Size640) {
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 640);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 480);
qDebug() << "Setting 640x480:CV_CAP_PROP_FRAME_WIDTH:" << cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
qDebug() << "Setting 640x480CV_CAP_PROP_FRAME_HEIGHT:" << cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

}

returns:
Setting 640x480:CV_CAP_PROP_FRAME_WIDTH: 320
Setting 640x480CV_CAP_PROP_FRAME_HEIGHT: 240

Any ideas how could I change frame width/height?
Best regards,
Milan

No. This is what I was talking about when I said the highgui functions suck :)

On some cameras those functions will work, but on most they won't. If you want to control camera properties like capture size and others you'll have to use another image acquisition library or try cvcam as someone else suggested. I never had much luck with it. It'll do basic capture, but that's it.

kosirm
11th July 2009, 13:37
thanks...

best regards, Milan

switch
6th August 2009, 21:57
Sorry to re-awaken an old topic but i am having some difficulties converting an opencv Monochrome image into a Qimage. The image is a result of calling the opencv function
void cvInRangeS( const CvArr* src, CvScalar lower, CvScalar upper, CvArr* dst );

When i pass this image to the function IplImageToQImage it does convert the image into qimage however the image is 8 times smaller and duplicated. The results can be seen below

Opencv Image
http://i701.photobucket.com/albums/ww17/robokinetic/monoOpenCv.png

Convertion to Qimage results
http://i701.photobucket.com/albums/ww17/robokinetic/QimageMono.png


Does anybody know why this has happened? And any ideas how to correct the error?

pherthyl
6th August 2009, 23:38
Not sure why you're getting that. Have you tried looking at the dst image before you convert it to a QImage (using the highgui showimg function)? Make sure the dst image is the correct bit depth (8u or 8s).

eumesmo
16th November 2009, 10:04
Hello pherthyl,


Thanks for the framework, it's very good, but I found a problem running in my hardware. I tested the framework in a Hp notebook, with the webcam and with a external camera and worked fine. When a tried the framework in another notebook (a LG note) with the integrate webcam, a get an deadlock every time I stop and try a play again.

The console output: (this problem in this notebook occurs every time, it's not a random problem...)


Listing capture properties...
CV_CAP_PROP_FRAME_WIDTH
CV_CAP_PROP_FRAME_HEIGHT
CV_CAP_PROP__FPS 0
CV_CAP_PROP_FOURCC 0
CV_CAP_PROP_BRIGHTNESS 0
CV_CAP_PROP_CONTRAST 0
CV_CAP_PROP_SATURATION 0
CV_CAP_PROP_HUE 0
Done
Setting 640x480 1
Attempting to set frame rate...
Error: 0
Starting to track
About to start the capture thread
Started the capture thread
Stop capture requested.
Waiting on capture start...
Listing capture properties...
CV_CAP_PROP_FRAME_WIDTH
CV_CAP_PROP_FRAME_HEIGHT
CV_CAP_PROP__FPS 0
CV_CAP_PROP_FOURCC 0
CV_CAP_PROP_BRIGHTNESS 0
CV_CAP_PROP_CONTRAST 0
CV_CAP_PROP_SATURATION 0
CV_CAP_PROP_HUE 0
Done
Setting 640x480 1
Attempting to set frame rate...
Error: 0
Starting to track
About to start the capture thread
Started the capture thread
QMutex::lock Deadlock detected in thread 3916



Well, another test that I did, it's to start a HeadTracker object when a button is pressed in the main window. Well, it works fine until I request a re-size. After a re-size the program crashes and close.


It's just a report, but any help it's very welcome, I will have a better lock in the code to see if I can improve anything, because I think is a very good framework and really fast as well :)

cheers!

mounte
15th December 2009, 10:14
I know this thread is quite old, but still it is a very good wrapper to get images from webcam or whatnot.

If for some reason you dont need some fancy 32 bit format you could change the updatePixmap function to only use one memcpy like this:


QTime t;
t.start();
//qDebug() << "Copying data";
bool start = false;
// check if the frame dimensions have changed
if(frame->width != imageWidth || frame->height != imageHeight) {
if(imageData) {
delete[] imageData;
}
start = true;
imageWidth = frame->width;
imageHeight = frame->height;
emit(frameSizeChanged(imageWidth, imageHeight));
imageData = new unsigned char[3*imageWidth*imageHeight];
}

int pixels = imageWidth * imageHeight;
uchar* src = (uchar*)(frame->imageData);

memcpy(imageData, src, pixels*3);
if(!start) {
++frames;
time += t.elapsed();
}


Then you have to change the paintEvent method to create the tImg with RGB888 format like this:

QImage tImg(imageData, imageWidth, imageHeight, QImage::Format_RGB888);

You might run into problem of RGB <--> BGR conversion, just modify the painter.drawImage call to

painter.drawImage(QPoint(0,0), tImg.rgbSwapped());

umanga
15th April 2010, 10:03
Seems the archive is corrupted.Could you please send me this ? my email is

umanga dot pdn at gmail dot com

thanks

josiahbryan
1st July 2010, 18:47
I thought the archive was corrupted too - but its actually double-gzipped, then tarred. So to open the archive, I had to gunzip qtopencv.tar.gz, then "cat qtopencv.tar | gunzip > qtopencv2.tar", then I could do "tar xvf qtopencv.tar" to extract the files. To save everyone that work, I posted a zipped version of the archive at: http://www.jdbryanphotography.com/downloads/qtopencv.zip. Cheers!

szworker
22nd September 2010, 08:06
Can we do like this? Mine is very simple. It works ( I think ) can you guys help check this?


IplImage * img = cvLoadImage( "C:\\Users\\Pictures\\dodo19.jpg");
cvCvtColor(img,img,CV_BGR2RGB);
m_i = QImage((unsigned char *)img->imageDataOrigin,img->width,img->height,QImage::Format_RGB888);
imageLabel->setPixmap(QPixmap::fromImage(m_i,0));

The picture looks good in the Qt Dialog. Please check if doing like this does really work fine.

srsr
22nd September 2010, 09:22
If it can help here is a code-snippet for a custom Qt plug-in using OpenCV. I use "neutral" unsigned char* between Qt and OpenCV. On return unsigned char* converted to QImage is displayed in a custom Widget. This PlugIn is used reall-time on video stream ( on PC.. sorry).


// code
#include <QtGui>
#include <math.h>
#include <stdlib.h>
#include "OpenCVwarpFilter.h"
//
#include "cv.h"
#include "cxcore.h"

#pragma message("automatic link to OpenCV libs")
#pragma comment(lib,"cv210.lib")
#pragma comment(lib,"cxcore210.lib")

struct OpenCVStruct
{
int iWidth;
int iHeight;
IplImage *m_pImg; // OpenCV Images
IplImage *m_pOutputImg;
CvMat *m_pMapMatrix; // OpenCV Matrix
CvPoint2D32f src_quad[4];
CvPoint2D32f dst_quad[4];
};

QString OpenCVwarpFilterPlugin::filterName() const
{
return "piWarp_OpenCV";
}


unsigned long OpenCVwarpFilterPlugin::filterParamsSize() const
{
return sizeof(OpenCVStruct);
}

void OpenCVwarpFilterPlugin::filterInit(void* piParams)
{
OpenCVStruct* pOpenCV = (OpenCVStruct*)piParams;
pOpenCV->m_pImg = NULL;
pOpenCV->m_pOutputImg = NULL;
pOpenCV->m_pMapMatrix = NULL;
pOpenCV->iWidth = 0;
pOpenCV->iHeight = 0;
}

void OpenCVwarpFilterPlugin::filterClose(void* piParams)
{
OpenCVStruct* pOpenCV = (OpenCVStruct*)piParams;
if (pOpenCV->m_pImg != NULL)
{
cvReleaseImage(&pOpenCV->m_pImg);
cvReleaseImage(&pOpenCV->m_pOutputImg);
cvReleaseMat(&pOpenCV->m_pMapMatrix);
}
}

void OpenCVwarpFilterPlugin::setOperation(unsigned char *destintation,unsigned char *source,
long width,long height,long dest_pitch,long src_pitch,long Bpp,void* piParams)
{
OpenCVStruct* pOpenCV = (OpenCVStruct*)piParams;
if (! pOpenCV)
return;



if ((pOpenCV->m_pImg == NULL) || (pOpenCV->iWidth != width) || (pOpenCV->iHeight != height))
{
if (pOpenCV->m_pImg != NULL)
{
cvReleaseImage(&pOpenCV->m_pImg);
cvReleaseImage(&pOpenCV->m_pOutputImg);
cvReleaseMat(&pOpenCV->m_pMapMatrix);
}
pOpenCV->m_pImg = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U, 3);
pOpenCV->m_pOutputImg = cvCreateImage(cvGetSize(pOpenCV->m_pImg), 8, 3 );

pOpenCV->src_quad[0].x = 150; pOpenCV->src_quad[0].y = 150;
pOpenCV->src_quad[1].x = 0; pOpenCV->src_quad[1].y = (float)height;
pOpenCV->src_quad[2].x = (float)width; pOpenCV->src_quad[2].y = 0;
pOpenCV->src_quad[3].x = (float)width; pOpenCV->src_quad[3].y = (float)height;

pOpenCV->dst_quad[0].x = 0; pOpenCV->dst_quad[0].y = 0;
pOpenCV->dst_quad[1].x = 0; pOpenCV->dst_quad[1].y = (float)height;
pOpenCV->dst_quad[2].x = (float)width; pOpenCV->dst_quad[2].y = 0;
pOpenCV->dst_quad[3].x = (float)width; pOpenCV->dst_quad[3].y = (float)height;

pOpenCV->m_pMapMatrix = cvCreateMat(3,3,CV_32FC1);
}
pOpenCV->iWidth = width;
pOpenCV->iHeight = height;

cvWarpPerspectiveQMatrix(pOpenCV->src_quad, pOpenCV->dst_quad, pOpenCV->m_pMapMatrix);

memcpy(pOpenCV->m_pImg->imageData,source,pOpenCV->m_pImg->imageSize);
cvWarpPerspective(pOpenCV->m_pImg, pOpenCV->m_pOutputImg, pOpenCV->m_pMapMatrix, CV_WARP_FILL_OUTLIERS, cvScalarAll(1));
memcpy(destintation,pOpenCV->m_pOutputImg->imageData,pOpenCV->m_pOutputImg->imageSize);
}

Q_EXPORT_PLUGIN2(FilterInterface, OpenCVwarpFilterPlugin)

// Header
#ifndef EXTRAFILTERSPLUGIN_H
#define EXTRAFILTERSPLUGIN_H

#include <QObject>
#include <QString>
#include "interfaceImageFilter.h"

class OpenCVwarpFilterPlugin : public QObject, public FilterInterface
{
Q_OBJECT
Q_INTERFACES(FilterInterface)

public:
QString filterName() const;
unsigned long filterParamsSize() const;
void filterInit(void* piParams);
void filterClose(void* piParams);
void setOperation(unsigned char *dest,unsigned char *src,
long width,long height,long dest_pitch,long src_pitch,long Bpp,void* piParams);

};

#endif

xairoy
25th November 2010, 13:23
Hallo,
I have downloaded the zip file and tried to run. First i downloaded the OpenCV2.0.1 and copied the opencv folder in the Project folder (i.e qtopencv/opencv) then i made the vcproj out of it as I am using Visual Studio 2005.
when I run the project, i get am linker error : cannot open input file cv.lib

I didn't find any cv.lib in the entire OpenCv2.0.1 that I downloaded.
I shalle be grateful if u tell me how can I run ur program.

Can u please tell me whether I can record the video stream that I shall be getting from the Camera. I went through the code and i find the slot startRecording in the headtracker.cpp empty.
Thanks.
Roy



Hi Stephan,

I'm currently putting together a small project for a computer vision grad class I'm taking. Eventually it will be a head tracker, but right now it's just the general capturing framework that I will use. I did some benchmarking on different approaches to copying opencv data to a QImage, and ended up with the code posted here: http://www.qtcentre.org/forum/p-qimage-data-via-ffmpeg-post61293/postcount7.html

I've also put together a simple framework for capturing and frame processing that you might find useful. I've attached the code for it. Just run qmake and make. Should work for most supported cameras.

It's multithreaded, so the capture thread spins getting frames as fast as possible and putting them into a buffer. Then the processing thread grabs frames out of that buffer and does whatever processing you want to do on the IplImage. Then the result gets loaded into a structure and passed through a chain of filters, ending with the widget that will contain the Image in the Qt GUI. Right now I do no processing and have no filters written yet, but the framework should work well for most computer vision tasks. I used a similar architecture for our eye tracking system and it works very well.

The display of the image uses a custom widget that paints it on the paintevent. I couldn't use OGL because my laptop video drivers are crap and it won't run. It should be about as fast as it can go without OGL though. Using Qt::WA_OpaquePaintEvent and Qt::WA_PaintOnScreen gives a nice speedup over the defaults.

lizyaz
14th January 2011, 18:30
Maybe this isn't the right forum for asking but I'm interesting in s-video capture with openCV and can't find anything, could you tell me how to do that or where to look for?

xairoy
15th January 2011, 10:26
Hi,
I didn't understand what do u mean by s-video? If u mean caprute video using a wecam with openCV, there r nice examples in the net. Just search with Capturing video with Wecam in OpenCv. U will find good threads.
Cheers,
Roy

pavanbarot
13th April 2011, 07:53
Hi josiahbryan,

Thanks For Sharing an Awesome Example. i have little problem with this application can u please help me.
i got following output:

640 is false
320 is true

Listing capture properties...

CV_CAP_PROP_FRAME_WIDTH 0
CV_CAP_PROP_FRAME_HEIGHT 0

CV_CAP_PROP_FPS 0
CV_CAP_PROP_FOURCC 4.29497e+09

CV_CAP_PROP_BRIGHTNESS 0
CV_CAP_PROP_CONTRAST 0

CV_CAP_PROP_SATURATION 0
CV_CAP_PROP_HUE 0

Done

Settings 320x240: 0
Attempting to set frame rate...

Error: 0
Starting to track

About to start the capture thread

Started the capture thread

E: Imagebuffer received a null image

E: Imagebuffer received a null image

E: Imagebuffer received a null image

Hi josiahbryan,

Thanks For Sharing an Awesome Example. i have little problem with this application can u please help me.
i got following output:

640 is false
320 is true

Listing capture properties...

CV_CAP_PROP_FRAME_WIDTH 0
CV_CAP_PROP_FRAME_HEIGHT 0

CV_CAP_PROP_FPS 0
CV_CAP_PROP_FOURCC 4.29497e+09

CV_CAP_PROP_BRIGHTNESS 0
CV_CAP_PROP_CONTRAST 0

CV_CAP_PROP_SATURATION 0
CV_CAP_PROP_HUE 0

Done

Settings 320x240: 0
Attempting to set frame rate...

Error: 0
Starting to track

About to start the capture thread

Started the capture thread

E: Imagebuffer received a null image

E: Imagebuffer received a null image

E: Imagebuffer received a null image

xenko
22nd July 2011, 18:52
Hi:

I know this thread is a bit old, but I would like to point out a library for computer vision we are developing, which integrates Qt with OpenCV, as well as other third-party libraries such as IPP:

QVision (http://qvision.sourceforge.net/)

core_st
26th July 2011, 18:24
I'm trying to compile program and Qt Creator after succsesful compile show error after running:
QtOpenCV: ../QtOpenCV/main.cpp:13: int main(int, char**): Assertion `camera' failed.
The program has unexpectedly finished.

core_st
29th July 2011, 13:13
Can anyone help? pls

grzesiek
29th July 2011, 13:48
And what ,,camera'' is ?

Please show some code.

G.

core_st
29th July 2011, 15:16
CvCapture * camera = cvCreateCameraCapture(-1);
assert(camera);
IplImage * image=cvQueryFrame(camera);
assert(image);

printf("Image depth=%i\n", image->depth);
printf("Image nChannels=%i\n", image->nChannels);

QApplication app(argc, argv);
MyCameraWindow *mainWin = new MyCameraWindow(camera);
mainWin->setWindowTitle("OpenCV --> QtImage");
mainWin->show();
int retval = app.exec();

cvReleaseCapture(&camera);

it's main function. I get error on assert(camera)

stampede
29th July 2011, 15:17
Do you have working camera ?

core_st
29th July 2011, 18:30
I have integrated camera in notebook and also try usb A4 webcamera, Both work fine in skype and cheese. Maybe i need write some settings about cameras in some config files?

stampede
29th July 2011, 19:03
No, if you have 2 working cameras, then opencv should popup a simple selection widget.
Try with cvCreateCameraCapture(0); or cvCaptureFromCAM(-1 or 0)

core_st
29th July 2011, 19:49
At peresent moment i have only integrated webcam. I was trying to check program with another webcam(i set cvCreateCameraCapture(1) according to the number of connected webcam - dev/video1), but every time i had the same error:
QtOpenCV: main.cpp:13: int main(int, char**): Assertion `camera' failed.

stampede
29th July 2011, 21:18
Not 1, cameras are indexed from 0, first camera in the system has index 0.
---
OpenCV comes with examples, try to see if they work for you.

core_st
29th July 2011, 21:29
I try run program with both variants: with index 0 and with index 1 (integrated camera - 0, usb-camera - 1) - but with both - same error

stampede
29th July 2011, 21:54
Have you tried the second method (cvCaptureFromCAM) ? What about OpenCV samples ?

core_st
29th July 2011, 22:41
OpenCv samples without assert() method works fine. I tried both methods with different params. I think opencv can't find any camera in system. So maybe i need to edit some config files?

stampede
29th July 2011, 22:47
I've never need to edit any config files to get OpenCV working, and I don't think there are any. It should work ok if you can use those cameras in other programs (like VirtualDub, Skype etc). Maybe try updating the drivers for those devices.

core_st
29th July 2011, 23:16
i'll try to update drivers and rebuild opencv

Added after 19 minutes:

I think i find some problem. When i was trying to install camdrivers - for acer crystal eye - i can't, because in compiling i take error - http://www.linuxtv.org/ driver don't know my linux-distro - Linux Mint,based od ubuntu. so maybe without this driver opecv can't find cameras...

S3dr1ck
13th August 2011, 21:29
Although this is pretty old I have some suggestions for using OpenCV with Qt. First of all get rid of this old c style code you are using.

Since OpenCV2 there's a new interface for c++ code. You should use cv::Mat and Videocapture and so on. You can use the cv::Mat constructor like cv::Mat(IplImage) for direct converion. The new Interface is fully compatible.

This will not solve your problems for sure, but it's a good start to get an up to date and clean code base first before trying to fix things.

Always use cmake for building OpenCV from source. This saves you a lot of trouble.

If your OpenCV Setup ist correct, check out my Tutorial on this and tell me what you think please, cuz it's my first.

I explain how to setup a Qt Project with OpenCV 2.3 in Mac OSX, Unix and Windows.

I don't use any cvNamedWindow or QLabel for output of the frames because it sucks and it's slow.

Instead I use a custom Widget which inherits from QtGLWidget. It renders the OpenCV Output using OpenGL 2D-Texture Mapping and handles dynamic resizing in the GUI and everything.

Check it out here (http://br1ckb0x.fancy-bits.net/blog/?p=736) and don't forget to post any problems or suggestions. I hope it will help you guys.

core_st
11th September 2011, 23:11
Can you post some working code with qt and opencv2 ?

core_st
12th September 2011, 21:53
I installed Gentoo for my laptop, install qt, opencv. trying to run this (http://qt-apps.org/content/show.php/Qt+Opencv+webcam+viewer?content=89995) program and get "assertion failed". Again...Check my camera:


core@localhost ~ $ v4l-info

### v4l2 device info [/dev/video0] ###
general info
VIDIOC_QUERYCAP
driver : "uvcvideo"
card : "CNF7017"
bus_info : "usb-0000:00:1a.7-6"
version : 1.1.0
capabilities : 0x4000001 [VIDEO_CAPTURE,STREAMING]

standards

inputs
VIDIOC_ENUMINPUT(0)
index : 0
name : "Camera 1"
type : CAMERA
audioset : 0
tuner : 0
std : 0x0 []
status : 0x0 []

video capture
VIDIOC_ENUM_FMT(0,VIDEO_CAPTURE)
index : 0
type : VIDEO_CAPTURE
flags : 0
description : "YUV 4:2:2 (YUYV)"
pixelformat : 0x56595559 [YUYV]
VIDIOC_G_FMT(VIDEO_CAPTURE)
type : VIDEO_CAPTURE
fmt.pix.width : 640
fmt.pix.height : 480
fmt.pix.pixelformat : 0x56595559 [YUYV]
fmt.pix.field : NONE
fmt.pix.bytesperline : 1280
fmt.pix.sizeimage : 614400
fmt.pix.colorspace : SRGB
fmt.pix.priv : 0

controls
VIDIOC_QUERYCTRL(BASE+0)
id : 9963776
type : INTEGER
name : "Brightness"
minimum : -64
maximum : 64
step : 1
default_value : 0
flags : 0
VIDIOC_QUERYCTRL(BASE+1)
id : 9963777
type : INTEGER
name : "Contrast"
minimum : 0
maximum : 95
step : 1
default_value : 0
flags : 0
VIDIOC_QUERYCTRL(BASE+2)
id : 9963778
type : INTEGER
name : "Saturation"
minimum : 0
maximum : 128
step : 1
default_value : 75
flags : 0
VIDIOC_QUERYCTRL(BASE+3)
id : 9963779
type : INTEGER
name : "Hue"
minimum : -40
maximum : 40
step : 1
default_value : 4
flags : 0

So what's wrong?

thaihoangluu
29th December 2011, 02:56
how to display multi camera opencv in QLabel QT.
Plz help :)

diepa9k39
24th January 2013, 12:12
I edit QtOpenCV project example.I built on PC and for KIT ARM is OK.When I copy file to KIT,telnet to KIT and run with the same error.


[root@FriendlyARM /myApp]# chmod a+rwx QtOpenCV
[root@FriendlyARM /myApp]# ./QtOpenCV -qws
QtOpenCV: main.cpp:13: int main(int, char**): Assertion `camera' failed.
Aborted

======================================
main.cpp


#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <stdio.h>
#include <assert.h>
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include "QOpenCVWidget.h"
#include "MyCameraWindow.h"

int main(int argc, char **argv) {
CvCapture * camera = cvCaptureFromCAM(-1);
assert(camera);
IplImage * image=cvQueryFrame(camera);
assert(image);

printf("Image depth=%i\n", image->depth);
printf("Image nChannels=%i\n", image->nChannels);

QApplication app(argc, argv);
MyCameraWindow *mainWin = new MyCameraWindow(camera);
mainWin->setWindowTitle("OpenCV --> QtImage");
mainWin->show();
int retval = app.exec();

cvReleaseCapture(&camera);

return retval;
}



==================================================
Can everybody help me run App use Opencv on KIT ARM
Thanks

I too try cvCreateCameraCapture() function but same this error!

diepa9k39
28th January 2013, 04:15
Anybody help?

wysota
28th January 2013, 05:19
What exactly do you expect us to do? Your program fails on some OpenCV call.