OpenCV与Socket实现树莓派获取摄像头视频至电脑
2016-08-28 21:10
465 查看
OpenCV能够为我们带来便捷的图像处理接口,但是其处理速度在一块树莓派上肯定是不尽如人意的。尤其当我们想要使用复杂的算法时,只能把算法托到服务器上才有可能。这里介绍了一种方法,实现树莓派传输Mat至电脑。
2、配置好电脑上的OpenCV.
树莓派上的,是linux系统;而我电脑上是windows系统,需要注意这一点来进行编程。
服务器接收并显示
先运行服务器,后运行客户端(其实无所谓),我们就可以在服务器上看到树莓派通过摄像头获取到的帧,那么就可以对齐进行很多操作了。
准备工作
1、配置好树莓派上的OpenCV.2、配置好电脑上的OpenCV.
思路
Socket实现方法较为简单,但在此处需要注意的是:树莓派上的,是linux系统;而我电脑上是windows系统,需要注意这一点来进行编程。
代码
树莓派作为客户端,发送Mat.#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <opencv2/opencv.hpp> using namespace cv; using namespace std; void error(const char *msg) { perror(msg); exit(0); } int main() { int sockfd, portno, n; struct sockaddr_in serv_addr; struct hostent *server; portno = atoi("8888"); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket"); server = gethostbyname("10.138.216.104");//这里填IP地址 if (server == NULL) { fprintf(stderr, "ERROR, no such host\n"); exit(0); } bzero((char *)&serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(portno); if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("ERROR connecting"); VideoCapture cap(0); Mat frame; while (true) { cap >> frame; cvtColor(frame, frame, CV_BGR2GRAY); // Send data here int bytes = send(sockfd, frame.data, frame.total()*frame.elemSize(), 0)); } waitKey(0); return 0; }
服务器接收并显示
#include <winsock2.h> #include <opencv.hpp> using namespace cv; using namespace std; #pragma comment(lib,"ws2_32.lib") #define imgSize 307200 //这里需要算一下,因为Visual Studio不能支持用变量初始化数组 //imgSize=frame.total()*frame.elemSize(); //即:如果为灰度图:图像的宽*图像的高 这里是640*480 int main(int argc, char* argv[]) { //初始化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); 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); cout << "Wait.." << endl; do { sClient = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen); } while (sClient == INVALID_SOCKET); cout<<"Received Information come from"<< inet_ntoa(remoteAddr.sin_addr)<<endl; int bytes = 0; while (1) { char socketData[imgSize]; for (int i = 0; i < imgSize; i += bytes) { if ((bytes = recv(sClient, socketData + i, imgSize - i, 0)) == -1) { cout << "!Fault" << endl; exit(-1); } } // change the last loop to below statement Mat img(Size(640, 480), CV_8UC1, socketData);//根据摄像头大小自行修改 imshow("Face_Socket", img); waitKey(1); } closesocket(slisten); WSACleanup(); return 0; }
先运行服务器,后运行客户端(其实无所谓),我们就可以在服务器上看到树莓派通过摄像头获取到的帧,那么就可以对齐进行很多操作了。
相关文章推荐
- OpenCV摄像头视频的获取
- [OpenCV]获取摄像头视频
- 基于opencv在摄像头ubuntu根据视频获取
- javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG、javaCV-openCV)
- [opencv]3.获取摄像头的视频流
- OpenCV 获取摄像头并显示摄像头视频
- opencv打开摄像头获取视频程序
- MFC中使用opencv获取海康摄像头视频
- OpenCV打开摄像头并获取实时视频图像代码
- OpenCV学习笔记(1):获取摄像头并显示摄像头视频
- OpenCV摄像头视频的获取
- OpenCV2 多摄像头读取视频实现
- OpenCV笔记(二)实现获取视频并控制视频的播放速度
- 【python下使用OpenCV实现计算机视觉读书笔记4】保存摄像头视频
- OpenCV摄像头视频的获取
- OpenCV 获取笔记本摄像头,新建窗口显示摄像头视频
- OpenCV2 多摄像头读取视频实现
- OpenCV 获取摄像头,新建窗口显示摄像头视频
- OpenCV2从摄像头获取帧并写入视频文件
- opencv成长之路2:一段用来获取摄像头视频的代码