通过opencv采集视屏,socket进行转发

Server:

#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include<iostream>
#include<WinSock2.h>
#include<windows.h>
#pragma warning(disable:4996)
#pragma comment(lib,"ws2_32.lib") 
using namespace std;
SOCKET listensocket, serversocket;
sockaddr_in socketaddr;
HANDLE event;
HANDLE hHandle[3];
HANDLE getVideoHandle;
DWORD WINAPI getVideoThread(LPVOID lpa);
BOOL SetConsoleColor(WORD wAttributes)
{
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	if (hConsole == INVALID_HANDLE_VALUE)
		return FALSE;
	return SetConsoleTextAttribute(hConsole, wAttributes);
}
DWORD WINAPI AcceptThread(LPVOID lparam)
{
	cout << "等待客户端连接...  " << endl;
	while (true)
	{
		int len = sizeof(socketaddr);
		if ((listensocket = accept(serversocket, (struct sockaddr*)&socketaddr, &len)) != INVALID_SOCKET)
		{
			unsigned long cmd = 1;
			int nState;
			nState = ioctlsocket(listensocket, FIONBIO, &cmd);
			if (nState == SOCKET_ERROR)
				cout << "设置非阻塞模式失败!!" << endl;

			cout << "客户端已连接! " << endl;
			SetConsoleColor(FOREGROUND_RED | FOREGROUND_INTENSITY);
			SetEvent(event);
			return 0;
		}
	}
}
DWORD WINAPI RecvThread(LPVOID lparam)
{
	char buf[1000];
	int len = 0;
	memset(buf, 0, sizeof(char) * 1000);
	//WaitForSingleObject(event, INFINITE);
	while (TRUE)
	{
		len = recv(listensocket, buf, 1000, 0);
		if (len != -1)
		{
			SetConsoleColor(FOREGROUND_GREEN | FOREGROUND_INTENSITY);
			cout << "收到:" << buf << endl;
			SetConsoleColor(FOREGROUND_RED | FOREGROUND_INTENSITY);
			memset(buf, 0, sizeof(char) * 1000);
			len = -1;
		}
	}
	delete[]buf;
	return 0;
}
DWORD WINAPI SendThread(LPVOID lparam)
{
	char buf[1000];
	memset(buf, 0, 1000 * sizeof(char));
	int len;
	WaitForSingleObject(event, INFINITE);
	while (true)
	{
		SetConsoleColor(FOREGROUND_RED | FOREGROUND_INTENSITY);
		cin >> buf;
		if (strcmp(buf, "openvideo") == 0)
		{
			getVideoHandle = CreateThread(NULL, 0,&getVideoThread, NULL, 0, NULL);
			len = send(listensocket, buf, 1000, 0);
			Sleep(300);
			break;
		}
		len = send(listensocket, buf, 1000, 0);
		memset(buf, 0, 1000 * sizeof(char));
	}
	//delete[]buf;
	return 0;
}
DWORD WINAPI getVideoThread(LPVOID lpa)
{
	CvCapture* capture = cvCreateCameraCapture(0);//初始化从摄像头中获取视频
	cvNamedWindow("video");//创建一个窗口对象
	//IplImage *tempImg = cvQueryFrame(capture1);//创建一个临时img
	IplImage *image_src = NULL;
	IplImage *image_dst = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 1);

	int i, j;
	char sendData[1000000] = "";
	while (1)
	{
		image_src = cvQueryFrame(capture);
		cvCvtColor(image_src, image_dst, CV_RGB2GRAY);
	//	cvCopy(image_src, image_dst);
		for (i = 0; i < image_dst->height; i++)
		{
			for (j = 0; j < image_dst->width; j++)
			{
				sendData[image_dst->width * i + j] = ((char *)(image_dst->imageData + i * image_dst->widthStep))[j];
			}
		}
		
		send(listensocket, sendData, 1000000, 0);
		char c = cvWaitKey(33);
		if (c == 27)
			break;
		memset(sendData, 0, 1000000);
	}
	cvReleaseCapture(&capture);
	cvDestroyWindow("video");

	hHandle[2] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&SendThread, NULL, 0, NULL);
	return 0;
}
int main(void)
{
	char ip[20];
	ZeroMemory(ip, 0, 20);
	cout << "输入ip" << endl;
	cin >> ip;
	system("cls");
	WSADATA wsa;
	WSAStartup(MAKEWORD(2, 2), &wsa);
	memset((char*)&socketaddr, 0, sizeof(socketaddr));
	socketaddr.sin_family = AF_INET;
	socketaddr.sin_addr.S_un.S_addr = inet_addr(ip);//sin_addr存储IP地址,使用in_addr这个数据结构
	socketaddr.sin_port = htons(6000);//端口

	if ((serversocket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
	{
		cout << "创建套接字失败!" << endl;
		cerr << GetLastError() << endl;
		system("pause");
		return 0;
	}

	if (bind(serversocket, (sockaddr*)&socketaddr, sizeof(socketaddr)) == SOCKET_ERROR)
	{
		cout << "绑定失败!!" << endl;
		cerr << GetLastError() << endl;
		system("pause");
		return 0;
	}
	listen(serversocket, 10);

	hHandle[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&AcceptThread, NULL, 0, NULL);
	hHandle[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&RecvThread, NULL, 0, NULL);
	hHandle[2] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&SendThread, NULL, 0, NULL);
	event = CreateEvent(NULL, FALSE, FALSE, NULL);

	WaitForMultipleObjects(3, hHandle, TRUE, INFINITE);
	for (int I = 0; I< 3; I++)
		CloseHandle(hHandle[I]);
	CloseHandle(getVideoHandle);
	system("pause");
	return 0;
}


Client:

#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include<iostream>
#include<WinSock2.h>
#include<windows.h>
#pragma warning(disable:4996)
#pragma comment(lib,"ws2_32.lib") 
using namespace std;
SOCKET sock;
HANDLE hHandle[2];
HANDLE showVideo;
DWORD WINAPI RecvThread(LPARAM lparam);
BOOL SetConsoleColor(WORD wAttributes)
{
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	if (hConsole == INVALID_HANDLE_VALUE)
		return FALSE;
	return SetConsoleTextAttribute(hConsole, wAttributes);
}
DWORD WINAPI ShowVideoThread(LPVOID lpa)
{
	char revData[1000000] = "";
	IplImage *image = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 1);
	int i, j;
	cvNamedWindow("client");
	while (true)
	{
		//接收数据
		recv(sock, revData, 1000000, 0);
		for (i = 0; i < image->height; i++)
		{
			for (j = 0; j < image->width; j++)
			{
				((char *)(image->imageData + i * image->widthStep))[j] = revData[image->width * i + j];
			}	
		}

		cvShowImage("client", image);
		char c = cvWaitKey(33);
		if (c == 27)
			break;
		//memset(revData, 0, 1000000);
	}
	cvDestroyWindow("client");
	//closesocket(slisten);
	hHandle[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RecvThread, NULL, 0, NULL);
	return 0;
}
DWORD WINAPI RecvThread(LPARAM lparam)
{
	char buf[1000]="";
	int len = 0;
	memset(buf, 0, sizeof(char) * 1000);
	//WaitForSingleObject(event, INFINITE);
	while (TRUE)
	{
		len = recv(sock, buf, 1000, 0);
		if (len != -1)
		{
			SetConsoleColor(FOREGROUND_GREEN | FOREGROUND_INTENSITY);
			if (strcmp(buf, "openvideo") == 0)
			{
				showVideo = CreateThread(NULL, 0, ShowVideoThread, NULL, 0, NULL);
				return 0;
			}
			cout << "收到:" << buf << endl;
			SetConsoleColor(FOREGROUND_RED | FOREGROUND_INTENSITY);
			memset(buf, 0, sizeof(char) * 1000);
			len = -1;
		}
	}
	//delete[]buf;
	return 0;
}
DWORD WINAPI SendThread(LPARAM lpa)
{
	char buf[1000];
	memset(buf, 0, 1000 * sizeof(char));
	int len;
	while (true)
	{
		SetConsoleColor(FOREGROUND_RED | FOREGROUND_INTENSITY);
		cin >> buf;
		len = send(sock, buf, 1000, 0);
		memset(buf, 0, 1000 * sizeof(char));
	}
	delete[]buf;
	return 0;
}


int main(void)
{
	char ip[20];
	int port;
	memset(ip, 0, sizeof(char) * 20);
	cout << "输入IP地址: " << endl;
	cin >> ip;
//	cout << "输入端口号: " << endl;
//	cin >> port;

	WSADATA wsa;
	WSAStartup(MAKEWORD(2, 2), &wsa);
	sockaddr_in sockaddr;
	sockaddr.sin_addr.S_un.S_addr = inet_addr(ip);
	sockaddr.sin_family = AF_INET;
	sockaddr.sin_port = htons(6000);

	sock = socket(AF_INET, SOCK_STREAM, 0);//流式套接字
	if (connect(sock, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) != 0)
	{
		cout << "连接失败!" << endl;
		cerr << GetLastError() << endl;
		system("pause");
		return -1;
	}
	else
	{
		cout << "连接服务器成功!!" << endl;
		hHandle[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SendThread, NULL, 0, NULL);
		hHandle[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RecvThread, NULL, 0, NULL);
	}
	WaitForMultipleObjects(2, hHandle, TRUE, INFINITE);
	system("pause");
	return 0;
}
核心:

server端的IplImage*转char*

for (i = 0; i < image_dst->height; i++)

{
for (j = 0; j < image_dst->width; j++)
{
sendData[image_dst->width * i + j] = ((char *)(image_dst->imageData + i * image_dst->widthStep))[j];
}
}
Client:char*转IplImage*

for (i = 0; i < image->height; i++)
{
for (j = 0; j < image->width; j++)
{
((char *)(image->imageData + i * image->widthStep))[j] = revData[image->width * i + j];
}
}

你可能感兴趣的:(通过opencv采集视屏,socket进行转发)