使用TCP传送opencv获取的webcam图像

看下效果图:

开发环境:QT5+BOOST+win7+vs2012+opencv2.8

服务器端:

只有使用到了QT(使用qtcreator)

客户端(采集webcam视频通过tcp发送到服务器端)

客户端的tcp用的是boost的,在VS2012里编写(ps.在qtcreator里怎么使用boost啊,boost是用vc11编译的)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

客户端:

采集webcam视频后用hog特征检测,如果图像中有人就发送到服务器端,同时控制台输出:send image finished ,如果没有,就不发送了。控制台输出:no image to send。

采集视频和HOG初始化

        HOGDescriptor hog;
	hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector()); /* 直接调用opencv里的HOG特征检测 */
	VideoCapture cap(0);                        /* open webcam */
	if(!cap.isOpened())  
	{  
		return -1;  
	}  
	Mat frame;  //采集到的视频存在这个mat里
	cap.set(CV_CAP_PROP_FRAME_WIDTH, 320);      /* set width */
	cap.set(CV_CAP_PROP_FRAME_HEIGHT, 240);     /* set height */

 设置连接服务器端的ip和端口

                boost::asio::io_service io_service;
		tcp::endpoint end_point(boost::asio::ip::address::from_string("127.0.0.1"), 3200);

		tcp::socket socket(io_service);
		socket.connect(end_point);
		boost::system::error_code ignored_error;

 hog检测和发送:

while (true)
		{
			vector<Rect> found, found_filtered;
			size_t i, j;
			cap>>frame;
			hog.detectMultiScale(frame, found, 0, Size(4,4), Size(0,0), 1.05, 2);

			imshow("client",frame);   
		
			char c=(char)waitKey(100);
			if (c==27)
			{
				break;
			}

			if (found.size()>=1) {

				frame = (frame.reshape(0,1)); // to make it continuous
				std::string message((char *)frame.data,230400); /* the size of mat data is 320*240*3 */
				socket.write_some(boost::asio::buffer(message), ignored_error);
				cout<<"send image finished"<<endl;


			}
			else
			{
				cout<<"no image to send "<<endl;
			}

		
		}

 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

服务器端

qtcreator创建基于对话框的程序

MyTcpServer类用来与客户端通信

 

MyTcpServer::MyTcpServer(QObject *parent) :
    QObject(parent)
{
    server = new QTcpServer(this);//返回一个通信的socket
    connect(server, SIGNAL(newConnection()),
            this, SLOT(newConnection()));

    if(!server->listen(QHostAddress::Any, 3200))
    {
        qDebug() << "Server could not start";
    }
    else
    {
        qDebug() << "Server started!";
    }
}

 监听新的连接

void MyTcpServer::newConnection()
{

    socket = server->nextPendingConnection();

    connect(socket, SIGNAL(readyRead()),
                this, SLOT(readSlot()));
}

 读取客户端发来的数据

void MyTcpServer::readSlot()
{

    qint64 blockSize = 230400; //320*240*3
    if (socket->bytesAvailable() < blockSize)//直到读到230400byte数据
        {
            return;
        }
    QByteArray b1=socket->read(230400);
    std::vector<uchar> vectordata(b1.begin(),b1.end());
    cv::Mat data_mat(vectordata,true);
    img= data_mat.reshape(3,240);       /* reshape to 3 channel and 240 rows */
    emit readyRead(); //重新运行readSlot

}

对话框界面设置定时器更新客户端传来的图像:

    timer = new QTimer(this);
    timer->start(10); //1000为1秒,10毫秒去取一帧
    connect(timer,SIGNAL(timeout()),this,SLOT(getFrame())); //超时就去取

 

void Dialog::getFrame(){
    QImage image= QImage((uchar*) server->img.data, server->img.cols, server->img.rows, server->img.step, QImage::Format_RGB888).rgbSwapped();
    ui->label->setPixmap(QPixmap::fromImage(image));
}

 

 

 在github的代码:

https://github.com/wzyuliyang/streammat

 

 

posted @ 2014-05-01 10:49  小菜鸟_yang  阅读(1282)  评论(0编辑  收藏  举报