CSocket 传输 IplImage

近期开发一视频监控系统,需要进行网络数据下视频数据的传输。

在此之前,希望你有MFC基础的功底,具体详见《孙鑫深入了解VC++视频教程》第13、14、15章等有关网络和多线程的章节。

关于opencv的基本知识(怎么配置以及如何使用)请参见其他资料,这里需要补充下IplImage详解http://blog.csdn.net/google0802/article/details/8986791

最重要的是要搞明白IplImage里面的origin(弄错后传过去的图像是倒着的)和char *imageData;               /* 指向排列的图像数据 */ 里面存储了char型的图像矩阵数据。

要先把图像的基本信息(width,height,depth,nchannels)传过去,然后传imageData,而另一端先接收图像的基本信息,用cvCreateImage来构造,然后接收imageData数据。

网络资料鱼龙混杂,具体分来以下几类:

最原始的方式实现;

CSocket实现;

多线程实现;

最原始的方式参见孙鑫的教程,从网络通信的原理一直讲到多线程再到异步IO,有关同步、异步、阻塞、非阻塞等概念详见文后链接。

套接字模式—阻塞模式开发http://blog.csdn.net/wangningyu/article/details/4571614给出了工程源代码

感觉孙老师不地道,虽然深入了解底层细节有助于我们对细节的把握,但实际开发还是要封装好的代码的,C语言面向过程的方式显然是不合适的。

套接字模式—非阻塞模式开发(1)总结了阻塞模式和非阻塞模式的优缺点

C++ Socket编程步骤http://www.cnblogs.com/Sniper-quay/archive/2011/06/22/2086636.html做了一小结

 

socket阻塞与非阻塞,同步与异步、I/O模型:http://284772894.iteye.com/blog/1852265

IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇)http://blog.csdn.net/historyasamirror/article/details/5778378

基于Socket的文件传输(使用CSocket类)http://blog.csdn.net/leixiaohua1020/article/details/12025731有源代码编译通过

基于UDP协议的简单基本视频传输程序的编写http://blog.csdn.net/jhh_move_on/article/details/9118075原始的UDP方式进行的传输,有源代码编译通过,因数据量小一次能传完,但数据量大了就有问题

 

揭开Socket编程的面纱http://www.cnblogs.com/goodcandle/archive/2005/12/10/socket.html

 

深入 CSocket 编程之阻塞和非阻塞模式http://blog.csdn.net/yjgx007/article/details/237955里面的两篇参考文献给出了源代码,非常不错

 

使用MFC类库进行socket编程的入门实例http://www.cppblog.com/changshoumeng/articles/112813.html这个总算接近实用水平了,我的代码就是在这基础上改的。

说下我新加的部分:为CServerDemoDlg 添加成员函数void SendImage(IplImage *img);负责发送图片

具体实现为:

void CServerDemoDlg::SendImage(IplImage *img)
{
	try
	{
		if(!img->imageData)
			return;
		RecvSock->Send((char*)&img->width,4);
		RecvSock->Send((char*)&img->height,4);
		RecvSock->Send((char*)&img->depth,4);
		RecvSock->Send((char*)&img->nChannels,4);
		int buffersize=1024;
		RecvSock->Send((char*)&buffersize,4);
		int num=0,ret;
		while(num<=img->imageSize-buffersize)
		{
			ret=RecvSock->Send((char*)(img->imageData+num),buffersize);
			num+=ret;
		}
		ret=RecvSock->Send((CHAR*)img->imageData+num,img->imageSize-num);
	}
	catch (CException* e)
	{
	}
}

  

void CServerDemoDlg::OnButton1() 
{
	img=cvLoadImage("bluerose.jpg");
	SendImage(img);
}

同理客户端接收主要代码:

void CClientDemoDlg::RecvImage(IplImage *img)
{
	try
	{
		int width,height,depth,channels;
		ClientSock->Receive((char*)&width,4);
		ClientSock->Receive((char*)&height,4);
		ClientSock->Receive((char*)&depth,4);
		ClientSock->Receive((char*)&channels,4);
		img=cvCreateImage(cvSize(width,height),depth,channels);
		int imsize=img->imageSize;
		int buffersize;
		ClientSock->Receive((char*)&buffersize,4);
		int num=0,ret;
		while(num<img->imageSize-buffersize)
		{
			ret=ClientSock->Receive((char*)(img->imageData+num),buffersize);
			num+=ret;
		}
		ClientSock->Receive((char*)(img->imageData+num),img->imageSize-num);
		DrawPicToHDC(img,IDC_PIC);
		cvReleaseImage(&img);
	}
	catch (CException* e)
	{
	}

}

  看下最后的效果吧:

 

 

 

 

 

posted @ 2014-04-10 22:34  迷若烟雨  阅读(374)  评论(0编辑  收藏  举报