基于qt和opencv的远程视频监控与播放
来源:互联网 发布:c语言读入txt文本文件 编辑:程序博客网 时间:2024/05/16 10:54
当有摄像头接入时,则采集实时视频显示到界面并且使用子线程保存视频,并且当检测到有服务器连接时,则发送每帧图像到服务器,并且实时显示。当没有检测到摄像头时,可以打开保存的录像视频,显示到界面播放的同时通过tcp协议发送到服务器端显示。源代码已上传:http://download.csdn.net/detail/lidefu1000810218/9839045
部分代码如下:
server:
#ifndef SERVER_H
#define SERVER_H
#include <QWidget>
#include<QTcpSocket>
#include<QTcpServer>
#include<QString>
#include<QtNetwork>
#include<QMessageBox>
#include<QImage>
namespace Ui {
class Server;
}
class Server : public QWidget
{
Q_OBJECT
public:
explicit Server(QWidget *parent = 0);
~Server();
QTcpServer *tcpServer;
QTcpSocket *tcpServerConnection;
QStringList *fortunes;
QImage *img;
quint64 basize;
public slots:
void sendFortune();
// QByteArray GetPicData(QString fromPic);
void DisplayError(QAbstractSocket::SocketError socketError);
void ReadMyData();
void ShowImage(QByteArray ba);
private:
Ui::Server *ui;
};
#endif // SERVER_H
#include "server.h"
#include "ui_server.h"
/*
1.创建tcpServer ,tcpServer = new QTcpServer(this);使之监听本机的某个端口,tcpServer->listen(QHostAddress("192.168.1.100"),6666)
2,关联信号newConnection和槽函数sendMessage, connect(tcpServer,SIGNAL(newConnection()),this,SLOT(sendMessage()));其中信号newConnection在有客户端的连接请求(即客户端执行tcpSocket->connectToHost)时发射
3.实现槽函数sendMessage,在里面从tcpServer取得已经建立但挂起的QTcpSocket连接
QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
用clientConnection 传输数据给客户
QByteArray block;
clientConnection->write(block);
*/
Server::Server(QWidget *parent) :
QWidget(parent),
ui(new Ui::Server)
{
ui->setupUi(this);
ui->image_label->setScaledContents(true);
tcpServer = new QTcpServer(this);
if(!tcpServer->listen(QHostAddress::Any,8888))
{
QMessageBox::critical(this,tr("Fortune Server"),tr("Unable to start the server:%l.").arg(tcpServer->errorString()));
close();
return;
}
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(sendFortune()));
}
Server::~Server()
{
delete ui;
}
void Server::sendFortune()
{
basize=0;
tcpServerConnection = tcpServer->nextPendingConnection();
QByteArray message;
QDataStream out(&message,QIODevice::WriteOnly);
//out.setVersion(QDataStream::Qt_4_6);
out<<(quint16) 0;
out<<tr("OK");//当有连接时则发送一个OK信号给客户端,通知其发送数据
out.device()->seek(0); //定位到第一个16位, 是写入的数据的大小
out<<(quint16)(message.size()-sizeof(quint16));
tcpServerConnection->write(message); //写入发送的数据
connect(tcpServerConnection,SIGNAL(readyRead()),
this,SLOT(ReadMyData()));//当有数据到来时,读取图像数据
connect(tcpServerConnection,SIGNAL(error(QAbstractSocket::SocketError)),
this,SLOT(DisplayError(QAbstractSocket::SocketError)));
}
void Server::DisplayError(QAbstractSocket::SocketError socketError)
{
tcpServerConnection->close();
}
void Server::ReadMyData()
{
QByteArray message;//存放从服务器接收到的字符串
QDataStream in(tcpServerConnection);
in.setVersion(QDataStream::Qt_4_6);
if (basize==0)
{
//判断接收的数据是否有两字节(文件大小信息)
//如果有则保存到basize变量中,没有则返回,继续接收数据
if (tcpServerConnection->bytesAvailable()<(int)sizeof(quint64))
{
return;
}
in>>basize;
}
//如果没有得到全部数据,则返回继续接收数据
if (tcpServerConnection->bytesAvailable()<basize)
{
return;
}
in>>message;//将接收到的数据存放到变量中
ShowImage(message);
}
void Server::ShowImage(QByteArray ba)
{
QString ss=QString::fromLatin1(ba.data(),ba.size());
QByteArray rc;
rc=QByteArray::fromBase64(ss.toLatin1());
QByteArray rdc=qUncompress(rc);
QImage img;
img.loadFromData(rdc);
ui->image_label->setPixmap(QPixmap::fromImage(img));
ui->image_label->resize(img.size());
update();
}
client:
#ifndef CAMARAGET_H
#define CAMARAGET_H
#include <QWidget>
#include <QImage>
#include <QTimer> // 设置采集数据的间隔时间
#include<QtNetwork>
#include<QTcpServer>
#include<QTcpSocket>
#include<QtGui>
#include <highgui.h> //包含opencv库头文件
#include <cv.h>
#include<camthread.h>
using namespace cv;
namespace Ui {
class camaraGet;
}
class camaraGet : public QWidget
{
Q_OBJECT
public:
explicit camaraGet(QWidget *parent = 0);
~camaraGet();
private slots:
void openCamara(); // 打开摄像头
void readFarme(QImage ); // 读取当前帧信息
void closeCamara(); // 关闭摄像头。
void takingPictures(); // 拍照
//void warn();
void openvideo();
void readFarme();
void readMessage();
private:
Ui::camaraGet *ui;
Camthread *camthread;
QTimer *timer;
VideoCapture cap;
bool video;
int op;
QImage image;
QTcpSocket* tcpSocket; //创建tcpsocket
quint16 blockSize; //存放文件的大小信息
QString message;
};
#endif // CAMARAGET_H
#include "camaraget.h"
#include "ui_camaraGet.h"
camaraGet::camaraGet(QWidget *parent) :
QWidget(parent),
ui(new Ui::camaraGet)
{
ui->setupUi(this);
op=0;
ui->label->setScaledContents(true);
ui->label_2->setScaledContents(true);
video=0;
timer=new QTimer();
camthread=new Camthread();
tcpSocket=new QTcpSocket();
/*信号和槽*/
//message=QString("OK");
connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readMessage()));
connect(camthread,SIGNAL(sig_GetOneFrame(QImage)),this,SLOT(readFarme(QImage )));
//connect(timer, SIGNAL(timeout()), this, SLOT(readFarme())); // 时间到,读取当前摄像头信息
connect(ui->open, SIGNAL(clicked()), this, SLOT(openCamara()));
connect(ui->pic, SIGNAL(clicked()), this, SLOT(takingPictures()));
connect(ui->closeCam, SIGNAL(clicked()), this, SLOT(closeCamara()));
// connect(tcpSocket,SIGNAL(error(QAbstractSocket::SocketError)),this,
// SLOT(displayError(QAbstractSocket::SocketError)));
}
void camaraGet::openCamara()
{
if(op==1)
{
return ;
}
connect(camthread,SIGNAL(sig_err(QString)),this,SLOT( openvideo()));
camthread->startPlay();
op=1;
}
void camaraGet::openvideo()
{
op=0;
QMessageBox::warning(this,"Warning","Cameras are not found.");
//connect(ui->open, SIGNAL(clicked()), this, SLOT(openvideo()));
QString filename = QFileDialog::getOpenFileName(this,tr("action"),
"./",
"Image file(*.AVI *.MP4)",0) ;
if (!filename.isEmpty())
{
cap.open(filename.toLatin1().data());
}
if(!cap.isOpened()){
QMessageBox::information(this,tr("提示"),tr("视频没有打开"));
video=0;
}
else
video=1;
timer->start(50);
connect(timer, SIGNAL(timeout()), this, SLOT(readFarme()));
connect(ui->open, SIGNAL(clicked()), this, SLOT(openCamara()));
connect(ui->pic, SIGNAL(clicked()), this, SLOT(takingPictures()));
connect(ui->closeCam, SIGNAL(clicked()), this, SLOT(closeCamara()));
connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readMessage()));
}
void camaraGet::readMessage()
{
qDebug()<<4;
qDebug() << message;
QDataStream in(tcpSocket);
//in.setVersion(QDataStream::Qt_4_6);
if (blockSize == 0) {
//判断接收的数据是否大于两字节,也就是文件的大小信息所占的空间
//如果是则保存到blockSize变量中,否则直接返回,继续接收数据
if(tcpSocket->bytesAvailable() < (int)sizeof(quint16)) return; //bytesAvailable()返回字节数
in >> blockSize;
}
if(tcpSocket->bytesAvailable() < blockSize) return;
// 将接收到的数据存放到变量中
in >> message;
// 显示接收到的数据*/
// qDebug() << message;
}
void camaraGet::readFarme()
{
blockSize=0;//数据大小初始化为0
tcpSocket->abort();//取消已有链接
//连接到某个ip的某个端口,
tcpSocket->connectToHost(QHostAddress::LocalHost,8888);
if(video)
{
qDebug()<<"baofang shipin !";
Mat frame;
//cap>>frame;
if(cap.read(frame))
{
cvtColor(frame,frame,CV_BGR2RGB);
QImage image1((unsigned const char*)frame.data,
frame.cols,frame.rows,QImage::Format_RGB888);
if(message=="OK")
{
QByteArray ba; //用于暂存要发送的数据
QDataStream out(&ba,QIODevice::WriteOnly); //使用数据流写入数据
//out.setVersion(QDataStream::Qt_4_6);
//设置数据流的版本,客户端和服务器端使用的版本要相同
QByteArray byte;
QBuffer buf(&byte);
image1.save(&buf,"JPEG");
QByteArray ss=qCompress(byte,1);
QByteArray vv=ss.toBase64();
out<<(quint64)0;
out<<vv;
out.device()->seek(0);
out<<(quint64)(ba.size()-sizeof(quint64));
//发送数据
tcpSocket->write(ba);
}
else ;
// tcpSocket->disconnectFromHost();
if(op==1)
ui->label->setPixmap(QPixmap::fromImage(image1)); // 将图片显示到label上
}
else
{
timer->stop();
op=0;
}
}
}
void camaraGet::readFarme(QImage img)
{
blockSize=0;//数据大小初始化为0
tcpSocket->abort();//取消已有链接
//连接到某个ip的某个端口,
tcpSocket->connectToHost(QHostAddress::LocalHost,8888);
image=img;
//qDebug()<<"tcp";
if(message=="OK")
{
QByteArray ba; //用于暂存要发送的数据
QDataStream out(&ba,QIODevice::WriteOnly); //使用数据流写入数据
//out.setVersion(QDataStream::Qt_4_6);
//设置数据流的版本,客户端和服务器端使用的版本要相同
QByteArray byte;
QBuffer buf(&byte);
image.save(&buf,"JPEG");
QByteArray ss=qCompress(byte,1);
QByteArray vv=ss.toBase64();
out<<(quint64)0;
out<<vv;
out.device()->seek(0);
out<<(quint64)(ba.size()-sizeof(quint64));
//发送数据
tcpSocket->write(ba);
}
else ;
if(op==1)
{
ui->label->setPixmap(QPixmap::fromImage(image)); // 将图片显示到label上
}
}
void camaraGet::takingPictures()
{
//frame = cvQueryFrame(cam);// 从摄像头中抓取并返回每一帧
// 将抓取到的帧,转换为QImage格式。QImage::Format_RGB888不同的摄像头用不同的格式。
//QImage image((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888);
//QImage image = QImage((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888).rgbSwapped();
// frame=cvLoadImage((filename.toLatin1()).data());
//ui->CameraLabel->setPixmap(QPixmap::fromImage(image));
op=0;
QString filename = QFileDialog::getSaveFileName(this,tr("action"),
"./",
"Image file(*.bmp *.jpg)",0) ;
if (!filename.isEmpty())
if(!image.save(filename))
QMessageBox::information(this,
tr("Warnning"),
tr("Failed to save the image!"));
op=1;
ui->label_2->setPixmap(QPixmap::fromImage(image)); // 将图片显示到label上
}
void camaraGet::closeCamara()
{
ui->label_2->clear();
//this->close();
}
camaraGet::~camaraGet()
{
delete ui;
}
#ifndef CAMTHREAD_H
#define CAMTHREAD_H
#include<QThread>
#include <QTimer> // 设置采集数据的间隔时间
#include <highgui.h> //包含opencv库头文件
#include <cv.h>
#include <QImage>
class Camthread:public QThread
{
Q_OBJECT
public:
explicit Camthread();
~Camthread();
void startPlay();
signals:
void sig_GetOneFrame(QImage); //每获取到一帧图像 就发送此信号
void sig_err(QString); //每获取到一帧图像 就发送此信号
private:
void run();
CvVideoWriter* writer;
QTimer *timer;
CvCapture *cam;// 视频获取结构, 用来作为视频获取函数的一个参数
IplImage *frame;//申请IplImage类型指针,就是申请内存空间来存放每一帧图像
private slots:
void readFrame( ); // 读取当前帧信息
};
#endif // CAMTHREAD_H
#include"camthread.h"
#include<QtGui>
Camthread::Camthread()
{
cam = NULL;
timer = new QTimer(this);
}
Camthread::~Camthread()
{
timer->stop(); // 停止读取数据。
cvReleaseCapture(&cam);//释放内存;
cvReleaseVideoWriter(&writer);
}
void Camthread::startPlay()
{
cam = cvCreateCameraCapture(0);//打开摄像头,从摄像头中获取视频
if(!cam)
{
emit sig_err("error");
//return;
//QMessageBox::warning(,"Warning","Cameras are not found.");
}
else
{
timer->start(50); // 开始计时,超时则发出timeout()信号
start();
}
}
void Camthread::run()
{
// 时间到,读取当前摄像头信息
double fps=30;
frame = cvQueryFrame(cam);
CvSize size=cvGetSize(frame);
writer=cvCreateVideoWriter("Video from CAMERA.avi",CV_FOURCC('X','V','I','D'),
fps,size,1);
connect(timer, SIGNAL(timeout()), this, SLOT(readFrame()));
}
void Camthread::readFrame( )
{
frame = cvQueryFrame(cam);// 从摄像头中抓取并返回每一帧
QImage image = QImage((const uchar*)frame->imageData, frame->width, frame->height,
QImage::Format_RGB888).rgbSwapped();
emit sig_GetOneFrame(image);
}
- 基于qt和opencv的远程视频监控与播放
- 基于opencv与MFC的视频播放。
- OpenCV 播放视频的QT
- QT: 基于QT和嵌入式的视频监控系统
- 基于Qt的视频播放器的设计与实现
- OpenCV:基于MFC的视频播放器和图片读取器
- QT OpenCV 播放视频
- OpenCV 播放视频的QT 代码
- 基于android的远程视频监控系统
- 基于android的远程视频监控系统
- 基于android的远程视频监控系统
- 基于H.264的远程视频监控
- 基于android的远程视频监控系统
- 基于H.264的远程视频监控
- 基于android的远程视频监控系统
- QT 框架中快速应用OpenCV 基于视频播放
- QT 框架中快速应用OpenCV 基于视频播放
- 基于Mplayer的QT视频播放器
- 若干秒后不操作自动关闭窗口
- 汇编语言——寻址方式的综合应用及转移指令的原理
- 复盘二进制的习题(2)
- Python网络通信之黏包问题(五)基于SocketServer模块和socket模块
- SUSE Linux Enterprise Server 12 (x86_64) rpm方式 安装gcc
- 基于qt和opencv的远程视频监控与播放
- 二叉树基本操作汇总练习
- 求两个数的最大公约数和最小公倍数
- 初学Nginx windos下安装
- Java 8新特性汇总
- 文件IO编程八
- LeetCode: 561. Array Partition I
- iOS开发给UITableViewCell绘制分割线
- 欢迎使用CSDN-markdown编辑器