简介:紧接着上一篇文章:【一】Opencv结合socket进行视频传输(TCP协议),我们趁热打铁,接下来在两台电脑之间进行视频的传输,化繁为简我们传输灰度视频。如确实还有问题,可以直接回复博客或图文并茂的将问题邮件给笔者(cuit_hjs@163.com),笔者知识有限,但尽量答复。
那么我们现在就开始吧,找两台都能上网的计算机,然后相互ping一下;传输视频思路是:抓取摄像头的帧画面,传输,如此循环。
跟上一文相同,在PC1上创建server工程,在PC2上创建client工程,代码分别如下:
客户端(client)源代码:
#include "stdafx.h"
#include <WINSOCK2.H>
#include <iostream>
#include <stdio.h>
#include <cv.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#pragma comment(lib,"ws2_32.lib")
int main(int argc, char* argv[])
{
WORD sockVersion = MAKEWORD(2,2);
WSADATA data;
if(WSAStartup(sockVersion, &data) != 0)
{
return 0;
}
SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sclient == INVALID_SOCKET)
{
printf("invalid socket !\n");
return 0;
}
sockaddr_in serAddr;
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(8888);
serAddr.sin_addr.S_un.S_addr = inet_addr("222.18.168.145"); //服务器的IP地址,可以是:①连接外网后分配的②手动设置的
if (connect(sclient, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
{
printf("connect error !\n");
closesocket(sclient);
return 0;
}
//读取图像并发送
IplImage *image_src = NULL;
IplImage *image_dst = cvCreateImage(cvSize(640, 480), 8, 1);//我的摄像头是640x480的,如不同则自行修改
CvCapture *capture = cvCreateCameraCapture(0);//打开摄像头
if (!capture)
{
printf("摄像头打开失败,请检查设备!\n");
}
int i, j;
char sendData[1000000] = "";
cvNamedWindow("client", 1);
while(1)
{
image_src = cvQueryFrame(capture);
cvCvtColor(image_src, image_dst, CV_RGB2GRAY);
for(i = 0; i < image_dst->height; i++)
{
for (j = 0; j < image_dst->width; j++)
{
sendData[image_dst->width * i + j] = ((char *)(image_dst->imageData + i * image_dst->widthStep))[j];
}
}
cvShowImage("client", image_src);//显示原图
cvWaitKey(30);//如果服务端收到的视频比较卡,此处延时适当改大一点
send(sclient, sendData, 1000000, 0);
}
cvReleaseCapture(&capture);
cvDestroyWindow("client");
closesocket(sclient);
WSACleanup();
return 0;
}
服务器端(server)源代码:
#include "stdafx.h"
#include <stdio.h>
#include <winsock2.h>
#include <cv.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#pragma comment(lib,"ws2_32.lib")
int main(void)
{
//初始化WSA
WORD sockVersion = MAKEWORD(2,2);
WSADATA wsaData;
if(WSAStartup(sockVersion, &wsaData)!=0)
{
return 0;
}
//创建套接字
SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(slisten == INVALID_SOCKET)
{
printf("socket error !");
return 0;
}
//绑定IP和端口
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(8888);//端口8888
sin.sin_addr.S_un.S_addr = INADDR_ANY;
if(bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
{
printf("bind error !");
}
//开始监听
if(listen(slisten, 5) == SOCKET_ERROR)
{
printf("listen error !");
return 0;
}
//循环接收数据
SOCKET sClient;
sockaddr_in remoteAddr;
int nAddrlen = sizeof(remoteAddr);
printf("等待连接...\n");
do
{
sClient = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen);
}while(sClient == INVALID_SOCKET);
printf("接受到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr));
char revData[1000000] = "";
IplImage *image_src = cvCreateImage(cvSize(640, 480), 8, 1);//收到的图像是640x480的,如不同请自行修改
int i, j;
int ret;
cvNamedWindow("server", 1);
while(true)
{
//接收数据
ret = recv(sClient, revData, 1000000, 0);
if(ret > 0)
{
revData[ret] = 0x00;
for(i = 0; i < image_src->height; i++)
{
for (j = 0; j < image_src->width; j++)
{
((char *)(image_src->imageData + i * image_src->widthStep))[j] = revData[image_src->width * i + j];
}
}
ret = 0;
}
cvShowImage("server", image_src);//收到的是灰度图像
cvWaitKey(1);
}
cvDestroyWindow("server");
closesocket(slisten);
WSACleanup();
return 0;
}
同样的,弄好了所有的准备工作后,先运行server,再运行client。可以看到效果,如果比较卡,可能是网络原因带宽不够,如果服务端有360加速球(绿色那个浮的圆条),就可以看到下载网速。
到此,实验就算是结束了,但是对于上述效果我不是很满意,因为我在跑代码的时候确实是卡顿卡顿的。那么有一种改进的方法就是,将两台计算机直接用网线相连,一主一从。
用网线连接后,用ipconfig查看,发现二者均没有分配到IP。那么就必须得手动分配IP地址了,在这里设置:网络连接—>本地连接—>属性—>常规—>Internet协议(TCP/IP)的属性中,下面我将server端设置为下图所示:
将client端设置为下图所示:
分配好后,再二者相互ping一下,通了就可以,都没通可能就不得行(注意,请根据自己的网段来设置IP,可以上网搜一下电脑网线直连IP设置)。那么在可以注意到,需要将client中设置IP处的代码改为:
serAddr.sin_addr.S_un.S_addr = inet_addr("222.18.168.150");
接下来运行server和client,可以看到顿卡瞬间就消失了,一下就变畅爽了。甚至试着client处的延时代码改变为:
cvWaitKey(1);
即使这样也是毫无压力,你再看看上传下载网速。同样的道理,我们照猫画虎就可以无压力的传输彩色视频了。
本次实验所需要的代码都已打包上传,下载地址:http://download.csdn.net/detail/hujingshuang/8400587
特别注意:
1、本博客例程仅做学习交流用,切勿用于商业用途。
2、欢迎交流,转载请注明出处:http://blog.csdn.net/hujingshuang/article/details/43193747