用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的電源給樹莓派供電,使用前記得給攝像頭使能。我用紙盒做了一個簡單的定型。
在這裏插入圖片描述
在這裏插入圖片描述

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 實驗效果

把樹莓派放在窗戶邊上:
在這裏插入圖片描述
先運行樹莓派上的程序(我用的電腦自帶的遠程桌面操作),樹莓派和電腦端顯示如下所示:在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章