设为首页 加入收藏

TOP

Linux下基于OpenCV的摄像头数据采集与传输(一)
2014-11-24 00:58:16 来源: 作者: 【 】 浏览:9
Tags:Linux 基于 OpenCV 摄像头 数据采集 传输

最近一段时间在搞摄像头的采集和传输。采集通过OpenCV自带的函数库,不用自己编写V4L2,省去了很多事情。主要工作就是在视频的传输了。主要思路是:将采集的一帧视频图像压缩成jpg格式的图片,这样进行过压缩的数据量大大减少。然后通过socket的UDP传输协议将图片通过网络传送到客户端。我之前用的TCP传的,总是有部分数据丢失重传,导致现实界面偶尔出现闪动,出现的错误提示:Corrupt JPEG data: premature end of data segment 本以为网络足够好,可有用下TCP,看来还是没设计好,就转用的UDP协议传输,问题就解决了。


在linux下QT环境中进行的程序编写,服务器端用的是linux C socket编写的,客户端是QT封装的QUdpSocket类编写的,成功实现了传输。但是将客户端放在windows下就没有数据传输,客户端一直不能readyread(),一直没有找到原因,看来还要继续寻找了。


服务器端代码:


widget.h


#ifndef WIDGET_H
#define WIDGET_H


#include
#include
#include
#include


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include


#define PORTNUMBER 4444
#define MAX_SIZE 1024;


namespace Ui {
class Widget;
}


class Widget : public QWidget
{
Q_OBJECT

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


int init_socket();

private:
Ui::Widget *ui;


cv::VideoCapture capture; //摄像头
cv::Mat frame; //帧图像
QTimer *timer; //定时器
QImage img; //QT 图像


int sockfd;
struct sockaddr_in server_addr;



private slots:
void slot_timer();


};


#endif


widget.c


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


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


timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(slot_timer()));


timer->start(33); //启动定时器,设置帧率


capture = cv::VideoCapture(1); //打开摄像头,这里使用了固定的摄像头,随机的话为-1


sockfd = init_socket(); //初始化套接字
}


Widget::~Widget()
{
delete ui;
delete timer;
capture.release();
}


int Widget::init_socket()
{
int sockfd;
if( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 )
{
perror("Socket error");
exit(1);
}


bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORTNUMBER);
//server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_addr.s_addr = inet_addr("192.168.1.115"); //主机IP


return sockfd;
}


void Widget::slot_timer()
{
capture>>frame; //将摄像头的每一帧放入frame
if(frame.empty())
{
printf("frame is empty\n");
return;
}
/*将opencv采集的BGR格式的图像转化成QT下的RGB格式的图像*/
cv::cvtColor(frame, frame, CV_BGR2RGB);
img = QImage((unsigned const char*)frame.data, frame.cols, frame.rows, QImage::Format_RGB888 );
img.save("test.jpg", "JPEG");


QFile file("test.jpg");
if(!file.open(QIODevice::ReadOnly))
{
perror("File open error");
return;
}


QByteArray buffer = file.readAll();
file.flush(); //好像这里没起作用


if(sendto(sockfd, buffer.data(),buffer.size(), 0, (struct sockaddr*)(&server_addr), sizeof(struct sockaddr_in)) < 0)
{
printf("send fail %d\n", buffer.size());
perror("sendto error");
}


file.close();
}


客户端程序:


widget.h


#ifndef WIDGET_H
#define WIDGET_H


#include
#include
#include


namespace Ui {
class Widget;
}


class Widget : public QWidget
{
Q_OBJECT

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

private:
Ui::Widget *ui;
QImage img;
QUdpSocket* receiver;



private slots:
void processPendingDatagram();


};


#endif // WIDGET_H


widget.c


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



#define PORTNUMBER 4444



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


receiver = new QUdpSocket(this);
bool result = receiver->bind(PORTNUMBER, QUdpSocket::ShareAddress);
if

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Linux网络编程--服务器客户端(TC.. 下一篇C++中函数占位符在函数重载中的作..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: