opencv读取esp32cam摄像头视频流

opencv读取esp32cam视频

之前在网上看到过安卓读取esp32cam的jpeg数据流,最近又在学opencv所以就想着把java改成c,esp32cam用官方demo或arduino的demo都可以就是端口不一样而已
先来张图片
opencv读取esp32cam摄像头视频流_第1张图片
第一步建立socket并get /stream拉流,然后就是不断地读!!!!!!!!
这些都放在了一个线程
opencv读取esp32cam摄像头视频流_第2张图片
然后处理一下读取数据,因为jpeg照片数据是(byte)0xFF, (byte)0xD8开头ff d9结尾的二进制数据流所以要找到开头位置并打印出http头信息
opencv读取esp32cam摄像头视频流_第3张图片
Content-Length:这个就是图片的大小然后就从 (byte)0xFF, (byte)0xD8 开始读一定的数据

			jj -= 2; int js = 2;sig = 0;
			uchar *cs = new uchar[jj]; vector<uchar> jpg_buff; 
			cs[0] = SOI_MARKER[0];cs[1] = SOI_MARKER[1];
			while (jj > 0)
			{
				sig = recv(clientSocket, (char*)cs+js, jj, 0); 			//printf("Error: Lost connection!\n");
				if (sig <= 0)
				{
					printf("Error: Lost connection!\n");
					break;
				}
				jj -= sig; js += sig;
			}
		

cs就是求到的指针然后利用opencv的imdecode读取内存图像在然后得到mat类并imshow显示记得要waitkey哦

完整代码

#include
#include 
#include 
#include
using namespace std;
using namespace cv;
#pragma comment(lib, "ws2_32.lib")
DWORD WINAPI CreateClientThread(LPVOID lpParameter);
bool a1 = true;
Mat as;

int main() {
	
	HANDLE  h_thread = ::CreateThread(nullptr, 0, CreateClientThread, (LPVOID)"192.168.2.140", 0, nullptr);

	//--------------------------------------------------------------------------------------------------
	
	//InternetCloseHandle(internet);
	while (true)
	{
		if (!a1) {
						imshow("kkk", as);a1 = true;
			waitKey(10);
		}
	}
	return 0;
}
DWORD WINAPI CreateClientThread(LPVOID lpParameter) 
{
	const char SOI_MARKER[] = { (byte)0xFF, (byte)0xD8 };
	//加载套接字库
	WSADATA wsaData;
	int iRet = 0;
	const 	char * a = "GET /stream HTTP/1.1\r\nConnection:Close\r\n\r\n";
	iRet = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (iRet != 0)
	{
		cout << "WSAStartup(MAKEWORD(2, 2), &wsaData) execute failed!" << endl;
		return -1;
	}
	if (2 != LOBYTE(wsaData.wVersion) || 2 != HIBYTE(wsaData.wVersion))
	{
		WSACleanup();
		cout << "WSADATA version is not correct!" << endl;
		return -1;
	}
	//创建套接字
	SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, 0);
	if (clientSocket == INVALID_SOCKET)
	{
		cout << "clientSocket = socket(AF_INET, SOCK_STREAM, 0) execute failed!" << endl;
		return -1;
	}
	//初始化服务器端地址族变量
	SOCKADDR_IN srvAddr;
	//srvAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	inet_pton(AF_INET, (char*)lpParameter, &srvAddr.sin_addr);
	srvAddr.sin_family = AF_INET;
	srvAddr.sin_port = htons(81);
	//连接服务器
	iRet = connect(clientSocket, (SOCKADDR*)&srvAddr, sizeof(SOCKADDR));
	if (0 != iRet)
	{
		cout << "connect(clientSocket, (SOCKADDR*)&srvAddr, sizeof(SOCKADDR)) execute failed!" << endl;
		return -1;
	}

	int x = 0;

	while (true)
	{
		x++;
		//发送消息
		char sendBuf[100];
		sprintf_s(sendBuf, "Hello, this is client %s %d!", "bunny", x);
		printf(sendBuf);
		printf("\n");
		send(clientSocket, a, strlen(a), 0);
		while (true)
		{
			//接收消息
			char r, recvBuf[10000]; int jj=0, sig, j = 0; bool t = true;
			for (int i = 0; t; i++) {
				sig = recv(clientSocket, &r, 1, 0); 			//printf("Error: Lost connection!\n");

				if (sig <= 0)
				{
					printf("Error: Lost connection!\n");
					break;
				}
				recvBuf[i - 1] = r;
				//	printf("%c",r);
				if (r == SOI_MARKER[j])
				{
					j++;
					if (j == 2) {
						j = 0;		recvBuf[i] = '\0';
						char*b = strstr(recvBuf, "Content-Length");
						b = strstr(b, ":");
						jj = atoi(b + 1);
						cout << "jpeg数据流长" << jj << endl;
						t = false;
					};
				}
				else if(r != SOI_MARKER[0]&&j==1)j=0;//else j = 0;
			}
			jj -= 2; int js = 2;sig = 0;
			uchar *cs = new uchar[jj]; vector<uchar> jpg_buff; 
			cs[0] = SOI_MARKER[0];cs[1] = SOI_MARKER[1];
			while (jj > 0)
			{
				sig = recv(clientSocket, (char*)cs+js, jj, 0); 			//printf("Error: Lost connection!\n");
				if (sig <= 0)
				{
					printf("Error: Lost connection!\n");
					break;
				}
				jj -= sig; js += sig;
			}
			/*clock_t start, end;
			start = clock();
			vector dat(cs, cs + js);
			end = clock();*/
			_InputArray pic_arr(cs, js); 
			if (a1) {
				as = imdecode(pic_arr, IMREAD_UNCHANGED);//图像解码
				a1 = false;
			}
			//vector vec_data(&cs[0], &cs[0] + js);
			//printf(&r);
			printf("%s \n", recvBuf);
		}
			//跳出
			if (x == 5)
			{
				break;
			}

		
	}

	//清理
	closesocket(clientSocket);
	WSACleanup();

	system("pause");
	return 0;
}

你可能感兴趣的:(opencv,esp32,c++,visual,studio,程序人生,经验分享,其他)