简介:紧接着上一篇文章:【一】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