tcp+opencv 视频传输
来源:互联网 发布:bugclose 源码下载 编辑:程序博客网 时间:2024/05/21 06:57
环境:
Server: Ubuntu 14.04 LTS + OpenCV2.4.10
Client:: Ubuntu 14.04 LTS + OpenCV2.4.10
我采用的仍是TCP协议的通信,linux上的实现和Windows大同小异。
Linux中opencv的编译安装可以参考 http://blog.csdn.net/pengz0807/article/details/49915573
TCP协议通信的一般步骤我再重新说一下:
客户端:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
4、设置要连接的对方的IP地址和端口等属性;
5、连接服务器,用函数connect();
6、收发数据,用函数send()和recv(),或者read()和write();
7、关闭网络连接;
服务器端:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt(); * 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();
4、开启监听,用函数listen();
5、接收客户端上来的连接,用函数accept();
6、收发数据,用函数send()和recv(),或者read()和write();
7、关闭网络连接;
8、关闭监听;
我把图像的发送和接收分别封装在了两个类中:
采集与发送:
SocketMatTransmissionClient.h
- /*M///////////////////////////////////////////////////////////////////////////////////////
- //
- // 基于OpenCV和Socket的图像传输(发送)
-
- //M*/
- #ifndef __SOCKETMATTRANSMISSIONCLIENT_H__
- #define __SOCKETMATTRANSMISSIONCLIENT_H__
- #include "opencv2/opencv.hpp"
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- using namespace cv;
- //待传输图像默认大小为 640*480,可修改
- #define IMG_WIDTH 640 // 需传输图像的宽
- #define IMG_HEIGHT 480 // 需传输图像的高
- #define PACKAGE_NUM 2
- //默认格式为CV_8UC3
- #define BUFFER_SIZE IMG_WIDTH*IMG_HEIGHT*3/PACKAGE_NUM
- struct sentbuf
- {
- char buf[BUFFER_SIZE];
- int flag;
- };
- class SocketMatTransmissionClient
- {
- public:
- SocketMatTransmissionClient(void);
- ~SocketMatTransmissionClient(void);
- private:
- int sockClient;
- struct sentbuf data;
- public:
- // 打开socket连接
- // params : IP 服务器的ip地址
- // PORT 传输端口
- // return : -1 连接失败
- // 1 连接成功
- int socketConnect(const char* IP, int PORT);
- // 传输图像
- // params : image 待传输图像
- // return : -1 传输失败
- // 1 传输成功
- int transmit(cv::Mat image);
- // 断开socket连接
- void socketDisconnect(void);
- };
- #endif
SocketMatTransmissionClient.cpp
- /*M///////////////////////////////////////////////////////////////////////////////////////
- //
- // 基于OpenCV和Socket的图像传输(发送)
- //M*/
- #include "SocketMatTransmissionClient.h"
- SocketMatTransmissionClient::SocketMatTransmissionClient(void)
- {
- }
- SocketMatTransmissionClient::~SocketMatTransmissionClient(void)
- {
- }
- int SocketMatTransmissionClient::socketConnect(const char* IP, int PORT)
- {
- struct sockaddr_in servaddr;
- if ((sockClient = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- {
- printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
- return -1;
- }
- memset(&servaddr, 0, sizeof(servaddr));
- servaddr.sin_family = AF_INET;
- servaddr.sin_port = htons(PORT);
- if (inet_pton(AF_INET, IP, &servaddr.sin_addr) <= 0)
- {
- printf("inet_pton error for %s\n", IP);
- return -1;
- }
- if (connect(sockClient, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
- {
- printf("connect error: %s(errno: %d)\n", strerror(errno), errno);
- return -1;
- }
- else
- {
- printf("connect successful!\n");
- }
- }
- void SocketMatTransmissionClient::socketDisconnect(void)
- {
- close(sockClient);
- }
- int SocketMatTransmissionClient::transmit(cv::Mat image)
- {
- if (image.empty())
- {
- printf("empty image\n\n");
- return -1;
- }
- if(image.cols != IMG_WIDTH || image.rows != IMG_HEIGHT || image.type() != CV_8UC3)
- {
- printf("the image must satisfy : cols == IMG_WIDTH(%d) rows == IMG_HEIGHT(%d) type == CV_8UC3\n\n", IMG_WIDTH, IMG_HEIGHT);
- return -1;
- }
- for(int k = 0; k < PACKAGE_NUM; k++)
- {
- int num1 = IMG_HEIGHT / PACKAGE_NUM * k;
- for (int i = 0; i < IMG_HEIGHT / PACKAGE_NUM; i++)
- {
- int num2 = i * IMG_WIDTH * 3;
- uchar* ucdata = image.ptr<uchar>(i + num1);
- for (int j = 0; j < IMG_WIDTH * 3; j++)
- {
- data.buf[num2 + j] = ucdata[j];
- }
- }
- if(k == PACKAGE_NUM - 1)
- data.flag = 2;
- else
- data.flag = 1;
- if (send(sockClient, (char *)(&data), sizeof(data), 0) < 0)
- {
- printf("send image error: %s(errno: %d)\n", strerror(errno), errno);
- return -1;
- }
- }
- }
SocketMatTransmissionServer.h
- /*M///////////////////////////////////////////////////////////////////////////////////////
- //
- // 基于OpenCV和Socket的图像传输(接收)
- //M*/
- #ifndef __SOCKETMATTRANSMISSIONSEVER_H__
- #define __SOCKETMATTRANSMISSIONSEVER_H__
- #include "opencv2/opencv.hpp"
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <unistd.h>
- #include <sys/shm.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- using namespace cv;
- #define PACKAGE_NUM 2
- #define IMG_WIDTH 640
- #define IMG_HEIGHT 480
- #define BLOCKSIZE IMG_WIDTH*IMG_HEIGHT*3/PACKAGE_NUM
- struct recvBuf
- {
- char buf[BLOCKSIZE];
- int flag;
- };
- class SocketMatTransmissionServer
- {
- public:
- SocketMatTransmissionServer(void);
- ~SocketMatTransmissionServer(void);
- int sockConn;
- private:
- struct recvBuf data;
- int needRecv;
- int count;
- public:
- // 打开socket连接
- // params : PORT 传输端口
- // return : -1 连接失败
- // 1 连接成功
- int socketConnect(int PORT);
- // 传输图像
- // params : image 待接收图像
- // image 待接收图像
- // return : -1 接收失败
- // 1 接收成功
- int receive(cv::Mat& image);
- // 断开socket连接
- void socketDisconnect(void);
- };
- #endif
SocketMatTransmissionServer.cpp
- /*M///////////////////////////////////////////////////////////////////////////////////////
- //
- // 基于OpenCV和Socket的图像传输(接收)
- //
- //M*/
- #include "SocketMatTransmissionServer.h"
- SocketMatTransmissionServer::SocketMatTransmissionServer(void)
- {
- }
- SocketMatTransmissionServer::~SocketMatTransmissionServer(void)
- {
- }
- int SocketMatTransmissionServer::socketConnect(int PORT)
- {
- int server_sockfd = socket(AF_INET,SOCK_STREAM, 0);
- struct sockaddr_in server_sockaddr;
- server_sockaddr.sin_family = AF_INET;
- server_sockaddr.sin_port = htons(PORT);
- server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
- if(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1)
- {
- perror("bind");
- return -1;
- }
- if(listen(server_sockfd,5) == -1)
- {
- perror("listen");
- return -1;
- }
- struct sockaddr_in client_addr;
- socklen_t length = sizeof(client_addr);
- sockConn = accept(server_sockfd, (struct sockaddr*)&client_addr, &length);
- if(sockConn<0)
- {
- perror("connect");
- return -1;
- }
- else
- {
- printf("connect successful!\n");
- return 1;
- }
- close(server_sockfd);
- }
- void SocketMatTransmissionServer::socketDisconnect(void)
- {
- close(sockConn);
- }
- int SocketMatTransmissionServer::receive(cv::Mat& image)
- {
- int returnflag = 0;
- cv::Mat img(IMG_HEIGHT, IMG_WIDTH, CV_8UC3, cv::Scalar(0));
- needRecv = sizeof(recvBuf);
- count = 0;
- memset(&data,0,sizeof(data));
- for (int i = 0; i < PACKAGE_NUM; i++)
- {
- int pos = 0;
- int len0 = 0;
- while (pos < needRecv)
- {
- len0 = recv(sockConn, (char*)(&data) + pos, needRecv - pos, 0);
- if (len0 < 0)
- {
- printf("Server Recieve Data Failed!\n");
- break;
- }
- pos += len0;
- }
- count = count + data.flag;
- int num1 = IMG_HEIGHT / PACKAGE_NUM * i;
- for (int j = 0; j < IMG_HEIGHT / PACKAGE_NUM; j++)
- {
- int num2 = j * IMG_WIDTH * 3;
- uchar* ucdata = img.ptr<uchar>(j + num1);
- for (int k = 0; k < IMG_WIDTH * 3; k++)
- {
- ucdata[k] = data.buf[num2 + k];
- }
- }
- if (data.flag == 2)
- {
- if (count == PACKAGE_NUM + 1)
- {
- image = img;
- returnflag = 1;
- count = 0;
- }
- else
- {
- count = 0;
- i = 0;
- }
- }
- }
- if(returnflag == 1)
- return 1;
- else
- return -1;
- }
示例代码:
图像的采集与发送:
SocketClientMat.cpp
- #include "SocketMatTransmissionClient.h"
- int main()
- {
- SocketMatTransmissionClient socketMat;
- if (socketMat.socketConnect("127.0.0.1", 6666) < 0)
- {
- return 0;
- }
- cv::VideoCapture capture(0);
- cv::Mat image;
- while (1)
- {
- if (!capture.isOpened())
- return 0;
- capture >> image;
- if (image.empty())
- return 0;
- socketMat.transmit(image);
- }
- socketMat.socketDisconnect();
- return 0;
- }
接收与显示:
SocketServerMat.cpp
- #include "SocketMatTransmissionServer.h"
- int main()
- {
- SocketMatTransmissionServer socketMat;
- if (socketMat.socketConnect(6666) < 0)
- {
- return 0;
- }
- cv::Mat image;
- while (1)
- {
- if(socketMat.receive(image) > 0)
- {
- cv::imshow("",image);
- cv::waitKey(30);
- }
- }
- socketMat.socketDisconnect();
- return 0;
- }
- tcp+opencv 视频传输
- tcp+opencv 视频传输+raspberry
- OpenCV结合socket进行实时视频传输(TCP协议)
- 基于socket(TCP)和opencv的实时视频传输
- 【视频传输】二、Opencv结合socket进行视频传输(TCP协议)
- 【视频传输】一、Opencv结合socket进行视频传输(TCP协议)
- tcp视频传输-服务端
- tcp视频传输-客户端
- 基于opencv的视频传输
- QT+Opencv视频文件TCP网络传输
- 基于TCP协议的视频传输
- TCP/UDP传输摄像头采集的数据(opencv)
- Linux-视频监控系统(5)-TCP传输子系统实现
- TCP传输
- TCP 传输
- TCP传输
- TCP传输
- TCP传输
- [SDUT](3469)深度优先搜索练习之神奇的矩环 ---DFS(图)
- 数据库测试
- webSQL操作数据库
- HDU6098-2017多校6-贪心&水-Inversion
- Servlet下载服务器文件
- tcp+opencv 视频传输
- HDU6105(博弈题,非酋得不到救赎)
- spring cloud
- Spring Security 概述与快速启动
- 【转载】NAND Flash的续介绍
- 对集合中的对象进行排序
- 短信验证集成步骤
- 虚函数和纯虚函数的区别
- B. Mr. Kitayuta's Colorful Graph(并查集)