c opencv tcp linux,tcp+opencv 视频传输

环境:

Server: Ubuntu 14.04 LTS + OpenCV2.4.10

Client:: Ubuntu 14.04 LTS + OpenCV2.4.10

我采用的仍是TCP协议的通信,linux上的实现和Windows大同小异。

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 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

usingnamespacecv;

//待传输图像默认大小为 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

structsentbuf

{

charbuf[BUFFER_SIZE];

intflag;

};

classSocketMatTransmissionClient

{

public:

SocketMatTransmissionClient(void);

~SocketMatTransmissionClient(void);

private:

intsockClient;

structsentbuf data;

public:

// 打开socket连接

// params : IP      服务器的ip地址

//          PORT    传输端口

// return : -1      连接失败

//          1       连接成功

intsocketConnect(constchar* IP,intPORT);

// 传输图像

// params : image 待传输图像

// return : -1      传输失败

//          1       传输成功

inttransmit(cv::Mat image);

// 断开socket连接

voidsocketDisconnect(void);

};

#endif

SocketMatTransmissionClient.cpp

/*M///

//

//  基于OpenCV和Socket的图像传输(发送)

//M*/

#include "SocketMatTransmissionClient.h"

SocketMatTransmissionClient::SocketMatTransmissionClient(void)

{

}

SocketMatTransmissionClient::~SocketMatTransmissionClient(void)

{

}

intSocketMatTransmissionClient::socketConnect(constchar* IP,intPORT)

{

structsockaddr_in    servaddr;

if((sockClient = socket(AF_INET, SOCK_STREAM, 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, (structsockaddr*)&servaddr,sizeof(servaddr)) 

{

printf("connect error: %s(errno: %d)\n", strerror(errno), errno);

return-1;

}

else

{

printf("connect successful!\n");

}

}

voidSocketMatTransmissionClient::socketDisconnect(void)

{

close(sockClient);

}

intSocketMatTransmissionClient::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(intk = 0; k 

{

intnum1 = IMG_HEIGHT / PACKAGE_NUM * k;

for(inti = 0; i 

{

intnum2 = i * IMG_WIDTH * 3;

uchar* ucdata = image.ptr(i + num1);

for(intj = 0; 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) 

{

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 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

usingnamespacecv;

#define PACKAGE_NUM 2

#define IMG_WIDTH 640

#define IMG_HEIGHT 480

#define BLOCKSIZE IMG_WIDTH*IMG_HEIGHT*3/PACKAGE_NUM

structrecvBuf

{

charbuf[BLOCKSIZE];

intflag;

};

classSocketMatTransmissionServer

{

public:

SocketMatTransmissionServer(void);

~SocketMatTransmissionServer(void);

intsockConn;

private:

structrecvBuf data;

intneedRecv;

intcount;

public:

// 打开socket连接

// params : PORT    传输端口

// return : -1      连接失败

//          1       连接成功

intsocketConnect(intPORT);

// 传输图像

// params : image   待接收图像

//      image   待接收图像

// return : -1      接收失败

//          1       接收成功

intreceive(cv::Mat& image);

// 断开socket连接

voidsocketDisconnect(void);

};

#endif

SocketMatTransmissionServer.cpp

/*M///

//

//  基于OpenCV和Socket的图像传输(接收)

//

//M*/

#include "SocketMatTransmissionServer.h"

SocketMatTransmissionServer::SocketMatTransmissionServer(void)

{

}

SocketMatTransmissionServer::~SocketMatTransmissionServer(void)

{

}

intSocketMatTransmissionServer::socketConnect(intPORT)

{

intserver_sockfd = socket(AF_INET,SOCK_STREAM, 0);

structsockaddr_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,(structsockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1)

{

perror("bind");

return-1;

}

if(listen(server_sockfd,5) == -1)

{

perror("listen");

return-1;

}

structsockaddr_in client_addr;

socklen_t length = sizeof(client_addr);

sockConn = accept(server_sockfd, (structsockaddr*)&client_addr, &length);

if(sockConn<0)

{

perror("connect");

return-1;

}

else

{

printf("connect successful!\n");

return1;

}

close(server_sockfd);

}

voidSocketMatTransmissionServer::socketDisconnect(void)

{

close(sockConn);

}

intSocketMatTransmissionServer::receive(cv::Mat& image)

{

intreturnflag = 0;

cv::Mat img(IMG_HEIGHT, IMG_WIDTH, CV_8UC3, cv::Scalar(0));

needRecv = sizeof(recvBuf);

count = 0;

memset(&data,0,sizeof(data));

for(inti = 0; i 

{

intpos = 0;

intlen0 = 0;

while(pos 

{

len0 = recv(sockConn, (char*)(&data) + pos, needRecv - pos, 0);

if(len0 

{

printf("Server Recieve Data Failed!\n");

break;

}

pos += len0;

}

count = count + data.flag;

intnum1 = IMG_HEIGHT / PACKAGE_NUM * i;

for(intj = 0; j 

{

intnum2 = j * IMG_WIDTH * 3;

uchar* ucdata = img.ptr(j + num1);

for(intk = 0; 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)

return1;

else

return-1;

}

示例代码:

图像的采集与发送:

SocketClientMat.cpp

#include "SocketMatTransmissionClient.h"

intmain()

{

SocketMatTransmissionClient socketMat;

if(socketMat.socketConnect("127.0.0.1", 6666) 

{

return0;

}

cv::VideoCapture capture(0);

cv::Mat image;

while(1)

{

if(!capture.isOpened())

return0;

capture >> image;

if(image.empty())

return0;

socketMat.transmit(image);

}

socketMat.socketDisconnect();

return0;

}

接收与显示:

SocketServerMat.cpp

#include "SocketMatTransmissionServer.h"

intmain()

{

SocketMatTransmissionServer socketMat;

if(socketMat.socketConnect(6666) 

{

return0;

}

cv::Mat image;

while(1)

{

if(socketMat.receive(image) > 0)

{

cv::imshow("",image);

cv::waitKey(30);

}

}

socketMat.socketDisconnect();

return0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值