QT和OpenCV 显示视频 http://zllxsha.blog.163.com/blog/static/50555091201011892029213/
来源:互联网 发布:mac osx应用程序开发 编辑:程序博客网 时间:2024/06/02 03:47
【存档】QT和OpenCV 显示视频 (存着)
2010-12-08 21:20:29| 分类:默认分类 | 标签:|字号大中小订阅
Qt开发的程序一般都要借助qmake生成makefile文件。因此为了加入opencv库就要修改.pro文件,下面是Linux下该文件的配置。(增加的部分)
Opencv中通过摄像头捕捉到的每帧图像的数据结构是IplImage类型的,要把它显示到Qt窗口中就需要把它转化为QImage类型的图像。
于是你可以下面的代码(部分)测试一下:摄像头获取每一帧IplImage*类型的图像,转化为QImage类型的图像,用update()发出一个paintEvent(QPaintEvent*)事件,如此不断更新图像。(IplImageToQImage中的mini和maxi默认初始化为0)
INCLUDEPATH+= . /usr/local/include/opencv
LIBS+= /usr/local/lib/libcv.so \
/usr/local/lib/libcvaux.so \
/usr/local/lib/libcxcore.so \
/usr/local/lib/libhighgui.so \
/usr/local/lib/libml.so
LIBS+= /usr/local/lib/libcv.so \
/usr/local/lib/libcvaux.so \
/usr/local/lib/libcxcore.so \
/usr/local/lib/libhighgui.so \
/usr/local/lib/libml.so
Opencv中通过摄像头捕捉到的每帧图像的数据结构是IplImage类型的,要把它显示到Qt窗口中就需要把它转化为QImage类型的图像。
#include<QVector>
#include<cstring>
QImage MyThread::IplImageToQImage(const IplImage* iplImage,double mini,double maxi)
...{
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 ", 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 *);
const unsignedint *iplImagePtr= (const unsignedint *)iplImage->imageData;
for (int y= 0; y< height; y++)
...{
for (int x= 0; x< width; x++)
...{
// We take only the highest part of the 16 bit value. It is
//similar to dividing by 256.
*QImagePtr++= ((*iplImagePtr++)>> 8);
}
iplImagePtr+= widthStep/sizeof(unsignedint)-width;
}
}
else
...{
qDebug("IplImageToQImage: image format is not supported : depth=16U and %d channels ", 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= (constfloat *) iplImage->imageData;
for(int y= 0; y< height; y++)
...{
for(int x= 0; x< width; x++)
...{
uchar p;
float pf = 255* ((*iplImagePtr++)- mini) / (maxi - mini);
if(pf < 0) p= 0;
else if(pf> 255) p= 255;
else p = (uchar) pf;
*QImagePtr++= p;
}
iplImagePtr+= widthStep/sizeof(float)-width;
}
}
else
...{
qDebug("IplImageToQImage: image format is not supported : depth=32F and %d channels ", 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= (constdouble *) iplImage->imageData;
for(int y= 0; y< height; y++)
...{
for(int x= 0; x< width; x++)
...{
uchar p;
double pf = 255* ((*iplImagePtr++)- mini) / (maxi - mini);
if(pf < 0) p= 0;
else if(pf> 255) p= 255;
else p = (uchar) pf;
*QImagePtr++= p;
}
iplImagePtr+= widthStep/sizeof(double)-width;
}
}
else
...{
qDebug("IplImageToQImage: image format is not supported : depth=64F and %d channels ", iplImage->nChannels);
}
break;
default:
qDebug("IplImageToQImage: image format is not supported : depth=%d and %d channels ", iplImage->depth, iplImage->nChannels);
}
QImage qImage;
QVector<QRgb> vcolorTable;
if(iplImage->nChannels== 1)
...{
// We should check who is going to destroy this allocation.
QRgb*colorTable= new QRgb[256];
for(int i= 0; i< 256; i++)
...{
colorTable[i]= qRgb(i, i, i);
vcolorTable[i]= colorTable[i];
}
qImage= QImage(qImageBuffer, width, height, QImage::Format_Indexed8).copy();
qImage.setColorTable(vcolorTable);
}
else
...{
qImage= QImage(qImageBuffer, width, height, QImage::Format_RGB32).copy();
}
free(qImageBuffer);
return qImage;
}
#include<cstring>
QImage MyThread::IplImageToQImage(const IplImage* iplImage,double mini,double maxi)
...{
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 ", 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 *);
const unsignedint *iplImagePtr= (const unsignedint *)iplImage->imageData;
for (int y= 0; y< height; y++)
...{
for (int x= 0; x< width; x++)
...{
// We take only the highest part of the 16 bit value. It is
//similar to dividing by 256.
*QImagePtr++= ((*iplImagePtr++)>> 8);
}
iplImagePtr+= widthStep/sizeof(unsignedint)-width;
}
}
else
...{
qDebug("IplImageToQImage: image format is not supported : depth=16U and %d channels ", 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= (constfloat *) iplImage->imageData;
for(int y= 0; y< height; y++)
...{
for(int x= 0; x< width; x++)
...{
uchar p;
float pf = 255* ((*iplImagePtr++)- mini) / (maxi - mini);
if(pf < 0) p= 0;
else if(pf> 255) p= 255;
else p = (uchar) pf;
*QImagePtr++= p;
}
iplImagePtr+= widthStep/sizeof(float)-width;
}
}
else
...{
qDebug("IplImageToQImage: image format is not supported : depth=32F and %d channels ", 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= (constdouble *) iplImage->imageData;
for(int y= 0; y< height; y++)
...{
for(int x= 0; x< width; x++)
...{
uchar p;
double pf = 255* ((*iplImagePtr++)- mini) / (maxi - mini);
if(pf < 0) p= 0;
else if(pf> 255) p= 255;
else p = (uchar) pf;
*QImagePtr++= p;
}
iplImagePtr+= widthStep/sizeof(double)-width;
}
}
else
...{
qDebug("IplImageToQImage: image format is not supported : depth=64F and %d channels ", iplImage->nChannels);
}
break;
default:
qDebug("IplImageToQImage: image format is not supported : depth=%d and %d channels ", iplImage->depth, iplImage->nChannels);
}
QImage qImage;
QVector<QRgb> vcolorTable;
if(iplImage->nChannels== 1)
...{
// We should check who is going to destroy this allocation.
QRgb*colorTable= new QRgb[256];
for(int i= 0; i< 256; i++)
...{
colorTable[i]= qRgb(i, i, i);
vcolorTable[i]= colorTable[i];
}
qImage= QImage(qImageBuffer, width, height, QImage::Format_Indexed8).copy();
qImage.setColorTable(vcolorTable);
}
else
...{
qImage= QImage(qImageBuffer, width, height, QImage::Format_RGB32).copy();
}
free(qImageBuffer);
return qImage;
}
于是你可以下面的代码(部分)测试一下:摄像头获取每一帧IplImage*类型的图像,转化为QImage类型的图像,用update()发出一个paintEvent(QPaintEvent*)事件,如此不断更新图像。(IplImageToQImage中的mini和maxi默认初始化为0)
void ImageViewer::paintEvent(QPaintEvent *)...{
QPainter painter(this);
painter.drawImage(QPoint(0,0),*image);
}
bool ImageViewer::ShowImage()...{
IplImage*pImage = NULL;
CvCapture*pCapture = NULL;
if((pCapture = cvCaptureFromCAM(-1))== NULL)...{
cout<< "Open camera failed!";
return false;
}
while((pImage= cvQueryFrame(pCapture))!= NULL)...{
image= IplImageToQImage(pImage);
update();
}
cvReleaseImage(&pImage);
cvReleaseCapture(&pCapture);
return true;
}
QPainter painter(this);
painter.drawImage(QPoint(0,0),*image);
}
bool ImageViewer::ShowImage()...{
IplImage*pImage = NULL;
CvCapture*pCapture = NULL;
if((pCapture = cvCaptureFromCAM(-1))== NULL)...{
cout<< "Open camera failed!";
return false;
}
while((pImage= cvQueryFrame(pCapture))!= NULL)...{
image= IplImageToQImage(pImage);
update();
}
cvReleaseImage(&pImage);
cvReleaseCapture(&pCapture);
return true;
}
评论
换一张
上一页1...-1-1-1-1-1-1-1...-1下一页
- QT和OpenCV 显示视频 http://zllxsha.blog.163.com/blog/static/50555091201011892029213/
- openCV 转自(http://zhang-jh04.blog.163.com/blog/static/97487172200962092332160/)
- QT类继承图(转自:http://blog.163.com/sxs_solo/blog/static/263333820086410169909/)
- http://junxia0404.blog.163.com/blog/static/265275572007498251691/
- http://blog.163.com/xiaoloong@126/blog/static/113726939201022761055233/
- http://qgjie456.blog.163.com/blog/static/3545136720112305582651/
- http://blog.163.com/mad010@126/blog/static/12237155200841645952814/
- 宏展开 http://hubeihuyanwei.blog.163.com/blog/static/2820528420111151152949/
- http://blog.163.com/023_dns/blog/static/1187273662012125112426472/
- http://blog.163.com/ecy_fu/blog/static/4445126200921512556887/
- http://picano.blog.163.com/blog/static/3108297620101112114513648/
- live555 http://jl9045.blog.163.com/blog/static/216206722011316103126788/
- http://blog.163.com/guotai_li/blog/static/110718702201091293641905/
- http://strong0511.blog.163.com/blog/static/15115379520124510362211/
- http://cl314413.blog.163.com/blog/static/19050797620121080918237/
- 转自:http://rongjih.blog.163.com/blog/static/33574461201247102329705/
- http://qbaok.blog.163.com/blog/static/1012926520119219573294/
- http://ranfeng0610.blog.163.com/blog/static/185708284201251524110617/
- Linux基本操作 1-----命令行BASH的基本操作
- UVA 10382 Watering Grass(变相的最小覆盖问题)
- ZOJ 3057 组合博弈 DP
- SQL Server 2008不允许保存更改
- 旧诗
- QT和OpenCV 显示视频 http://zllxsha.blog.163.com/blog/static/50555091201011892029213/
- UVA591- Box of Bricks
- Struts2中启用各个内置对象的方法
- 装载、链接与库
- 细说MVC 结构
- fread和fwrite使用的题..
- 在struts2的action中获取或设置http型session变量的值
- 关于string的成员函数substr
- UVA846- Steps