用Opencv+树莓派+socket 实现远程监控

用Opencv+树莓派+socket 实现远程监控

网上现在很多基于树莓派的远程监控都是用的ssh来完成的,但是这样不能获取实时图片数据用于后续处理,这里介绍的是一种利用socket编程通过TCP协议实现的网络传输,以实时获取画面。

材料:树莓派(我用的3b+),一个免驱摄像头,一台电脑

准备工作:树莓派安装系统,同时配置opencv,树莓派和电脑在同一局域网。

1实现原理

远程监控自然分为两端,一边是边缘端用于获取图像信息并且发送图片信息,另一边也就是接收端用于接受图像信息并显示在屏幕上。

1.1 图像传输方法

这里使用的是socket编程通过TCP协议传输图像信息,具体的socket编程相关原理这里不做详细赘述。但是有人会问,图像信息是怎么通过TCP传输的呢,这里用到了opencv自带的图像解编码函数:
cv::imencode Mat数据编码成数据流
cv::imdecode 数据流解码成Mat
通过imencode将图片信息变成数据流,用于传输,PC端接到后再用imdecode函数解码为Mat类型数据。

1.2边缘端

将摄像头插到树莓派上,并用5v,2.5A的电源给树莓派供电,使用前记得给摄像头使能。我用纸盒做了一个简单的定型。
用Opencv+树莓派+socket 实现远程监控
用Opencv+树莓派+socket 实现远程监控

1.3 PC端

PC端这边用的VS2013+opencv2.49,代码如下(代码中的树莓派IP可以在树莓派中输入 sudo ifconfig 里面的wlan0里面获取,注意树莓派和PC要在同一局域网下):

#include <iostream>
#include <string>
#include <WinSock2.h> //包含WinSock2.h头文件
#include<opencv2\opencv.hpp>
using namespace std;
using namespace cv;
#pragma comment(lib, "ws2_32.lib") //加载 ws2_32.dll 
#pragma warning(disable:4996)


#define BUF_SIZE 100
int main()
{
	//****初始化
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData);

	//****创建套接字
	SOCKET sock = socket(PF_INET, SOCK_STREAM, 0);

	//****创建sockAddr结构体
	sockaddr_in sockAddr;
	memset(&sockAddr, 0, sizeof(sockAddr));
	sockAddr.sin_family = PF_INET;
	sockAddr.sin_port = htons(18000);
	sockAddr.sin_addr.s_addr = inet_addr("192.168.1.100"); //树莓派的局域网IP

	//****建立连接
	connect(sock, (SOCKADDR*)& sockAddr, sizeof(SOCKADDR));
	cout << "客户端发送链接请求" << endl;
	char tack[20000] = { 0 };
	//****接收服务器传回的数据	
	Mat src;
	Mat test = Mat::zeros(Size(300, 300), CV_8UC1);
	Mat tring = Mat::zeros(Size(300, 300), CV_8UC1);
	namedWindow("src", CV_WINDOW_AUTOSIZE);
	int label = 0;
	Mat t;
	while (1)
	{
		if (recv(sock, tack, 18000, NULL) != (-1)) {
			cout << "等待服务端发送信息.." << endl;
			//cout << tack << endl;
			cout << strlen(tack) << endl;
			if (strlen(tack) != 4) {
				label = 0;
				memset(tack, 0, 20000);  //重置缓冲区
				continue;
			}
			else {
				label = 1;
			}
			//输出接收到的数据
			if (strlen(tack) == 4 && label == 1) {
				label = 1;
				vector<uchar>end;
				for (int i = 0; i < 18000; i++)
				{
					end.push_back(tack[i]);
				}
				src = imdecode(end, 1);
				if (!src.data){
					printf("no image");
					src = t;
				}
				else{
					src.copyTo(t);
				}
				medianBlur(src, src, 5);  //去噪
				imshow("src", src);
				waitKey(10);
			}
			else {
				continue;
			}
			memset(tack, 0, 20000);  //重置缓冲区
		}
	}

	//关闭套接字、终止使用 DLL
	closesocket(sock);
	WSACleanup();

	return 0;
}

2 实验效果

把树莓派放在窗户边上:
用Opencv+树莓派+socket 实现远程监控
先运行树莓派上的程序(我用的电脑自带的远程桌面操作),树莓派和电脑端显示如下所示:用Opencv+树莓派+socket 实现远程监控
用Opencv+树莓派+socket 实现远程监控

上一篇:getnameinfo函数


下一篇:C语言基础-网络相关函数