Qt打开网络摄像头~[Qt]

Nico_拉倒 2016-12-21 11:14:50
使用Qt打开网络摄像头,需要用到摄像头自己的API,处理函数只能在API的回调函数里面进行,需要在回调函数里面调用Widget类的部件,但是这样不行,有没有什么办法啊》求大神指导!!在VS下没问题,只需要在void CALLBACK DecCBFun1()这个回调函数里面cvShowImage(rgbimg1);就可以了,但是在Qt里面就不行~需要可提供摄像头的SDK~

Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<cv.h>
#include<highgui.h>
#include<imgproc.hpp>
#include<QPixmap>
#include<QSize>
#include<dhconfigsdk.h>
#include<dhnetsdk.h>
#include<dhplay.h>

using namespace cv;

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
Q_OBJECT

public:
explicit Widget(QWidget *parent = 0);
~Widget();

private slots:
void opencamera();

private:
Ui::Widget *ui;
//IplImage* rgbimg1;
QSize size;
//QImage qimage;
};

#endif // WIDGET_H

Widget.cpp

#include "widget.h"
#include "ui_widget.h"

#define PLAYPORT1 1
#define HEIGHT 720
#define WIDTH 1280

//全局变量
unsigned long lLogin1;
long lRealPlay1;
IplImage *rgbimg1 = cvCreateImage(cvSize(1280, 720),IPL_DEPTH_8U,3);
QImage qimage;

Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
rgbimg1=NULL;

QObject::connect(ui->openCamBtn,SIGNAL(clicked()),this,SLOT(opencamera()));
}

Widget::~Widget()
{
delete ui;
}

void copy_yuvImage_to_IplImage_color(const unsigned char *input_img,IplImage* out_img)
{
IplImage *image,*yimg,*uimg,*vimg,*uuimg,*vvimg;
unsigned char *ptr_yimg,*ptr_uimg,*ptr_vimg;
int col,row;

CvSize frameSize = (WIDTH,HEIGHT);
CvSize frameSize_q = (WIDTH/2,HEIGHT/2);
image = cvCreateImage(frameSize,IPL_DEPTH_8U,3);
yimg = cvCreateImage(frameSize,IPL_DEPTH_8U,1);
uimg = cvCreateImage(frameSize_q,IPL_DEPTH_8U,1);
vimg = cvCreateImage(frameSize_q,IPL_DEPTH_8U,1);

uuimg = cvCreateImage(frameSize,IPL_DEPTH_8U,1);
vvimg = cvCreateImage(frameSize,IPL_DEPTH_8U,1);

for(row=0;row<HEIGHT;row++)
{
ptr_yimg = (unsigned char*)(yimg->imageData + row*yimg->widthStep);

for(col=0;col<WIDTH;col++)
{
*ptr_yimg++ = input_img[row*WIDTH+col];
}
}
for(row=0;row<HEIGHT/2;row++)
{
ptr_uimg = (unsigned char*)(uimg->imageData + row*uimg->widthStep);
ptr_vimg = (unsigned char*)(vimg->imageData + row*vimg->widthStep);

for(col=0;col<WIDTH/2;col++)
{
*ptr_uimg++ = input_img[HEIGHT*WIDTH + row*WIDTH/2 + col];
*ptr_vimg++ = input_img[(HEIGHT*WIDTH+HEIGHT*WIDTH/4) + row*WIDTH/2 + col ];

}
}
cvResize(uimg,uuimg,CV_INTER_LINEAR);
cvResize(vimg,vvimg,CV_INTER_LINEAR);

cvMerge(yimg,uuimg,vvimg,NULL,image);
cvCvtColor(image,out_img,CV_YCrCb2RGB);

cvReleaseImage(&image);
cvReleaseImage(&yimg);
cvReleaseImage(&vimg);
cvReleaseImage(&uimg);
cvReleaseImage(&uuimg);
cvReleaseImage(&vvimg);
}

void CALLBACK DisConnectFunc(LONG lLoginID, char *pchDVRIP, LONG nDVRPort, DWORD dwUser)
{
printf("设备断线.\n");
return;
}

void CALLBACK AutoReConnectFunc(LONG lLoginID, char *pchDVRIP, LONG nDVRPort, DWORD dwUser)
{
printf("自动重连成功.\n");
return;
}


void CALLBACK RealDataCallBackEx1(LONG lRealHandle, DWORD dwDataType, BYTE *pBuffer,DWORD dwBufSize, LONG lParam, DWORD dwUser)
{
if (dwDataType == 0) //原始视频流送播放库
{
PLAY_InputData(PLAYPORT1,pBuffer,dwBufSize);
}
}

//移走数据后,快速返回,即开始解码回调下一帧数据;不要在回调中运行长事务,否则阻塞解码下一帧数据
// pbuf里的数据是YUV I420格式的数据
void CALLBACK DecCBFun1(LONG nPort,char * pBuf,LONG nSize,FRAME_INFO * pFrameInfo, void* pUserData, LONG nReserved2)//处理视频只能在这个回调函数里面进行
{
if(pFrameInfo->nType == 3) //视频数据
copy_yuvImage_to_IplImage_color((const unsigned char *)pBuf,rgbimg1);
cvShowImage("1",rgbimg1);
//qimage = QImage((const uchar*)rgbimg1->imageData, rgbimg1->width, rgbimg1->height, QImage::Format_RGB888).rgbSwapped();//rgbSwapped()
qimage = qimage.scaled(ui->label->width(), ui->label->height(),Qt::IgnoreAspectRatio, Qt::SmoothTransformation);//设置图片大小和label的长宽一致
// ui->label->setPixmap(QPixmap::fromImage(qimage));
// ui->label->resize(ui->label->pixmap()->size());
cvWaitKey(10);
return;
}

void Widget::opencamera()
{
//打开播放通道
PLAY_OpenStream(PLAYPORT1,0,0,1024*1024);
PLAY_SetDecCallBackEx(PLAYPORT1, DecCBFun1,NULL);
PLAY_Play(PLAYPORT1,NULL);

CLIENT_LogClose();
NET_DEVICEINFO deviceInfo ={0};

CLIENT_Init(DisConnectFunc, 0);//初始化sdk,设置断线回调函数
CLIENT_SetAutoReconnect(AutoReConnectFunc, 0);
lLogin1 = CLIENT_Login("192.168.1.109",37777,"admin","admin",&deviceInfo);//登陆设备,用户需另选设备。

if(lLogin1 != 0)
{
ui->lineEdit->setText(QString("Login Success ,Start Real Play\n"));
lRealPlay1 = CLIENT_RealPlay(lLogin1,0,0);

if(lRealPlay1 != 0)
{
//窗口句柄传空值,网络库只回调原始数据
CLIENT_SetRealDataCallBackEx(lRealPlay1, RealDataCallBackEx1, 0, 0x1f);
}
}
else
{
ui->lineEdit->setText(QString(" Login Fail \n)"));
}
//

}


...全文
1080 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_39645827 2017-07-28
  • 打赏
  • 举报
回复
现在搞定了没有,求助
  • 打赏
  • 举报
回复
感觉是 cvShowImage没成功
Nico_拉倒 2016-12-22
  • 打赏
  • 举报
回复
cvShowImage(rgbimg1);其实不想用的,主要是想用后面的语句显示在UI上,但是现在利用cvShowImage也不行,一点打开摄像头按钮就中断,出现,不知道怎么回事。
//qimage = QImage((const uchar*)rgbimg1->imageData, rgbimg1->width, rgbimg1->height, QImage::Format_RGB888).rgbSwapped();//rgbSwapped()
qimage = qimage.scaled(ui->label->width(), ui->label->height(),Qt::IgnoreAspectRatio, Qt::SmoothTransformation);//设置图片大小和label的长宽一致
// ui->label->setPixmap(QPixmap::fromImage(qimage));
// ui->label->resize(ui->label->pixmap()->size());

16,240

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧