使用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
作者:小菜鸟_yang
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。