基于opencv与android的手机远程监控

前言:最近搞了一下andriod和socket网络通信,结合之前搞得opencv,立即有了一个把三者结合起来的想法。好了,搞吧。所以搞出来一个远程监控,功能就是把电脑的摄像头数据传到手机上。


环境:VS2015,opencv,android studio


VS端:

其实就是打开一个摄像头,再把图像数据通过socket发送出去,问题不大。但要注意图片尺寸默认480*640。

main函数伪代码:

初始化tcp和udp服务端,

开启tcp和udp监听线程,

打开摄像头,

打开录像功能,

一直读图,并转化为灰色,

如果收到服务端的信号,则传输图像,

由于android端bitmap与这里灰度图的显示是相反的,所以传图的时候也对每一个像素取反,

最后结束。


初始化部分其实网上有许多,直接用就好了。

监听线程如果收到“ss",则表示开始传输,收到”ee"则表示结束。

这里要注意的是,使用udp传输是不稳定的,所以传输的时候每一帧都加上开头和结尾的判断标志,而且发送过快的话andriod端会出现丢包的情况,所以每次传输后面都加了延时。并且由于MTU限制,每一帧的实际数据长度不能超过1472。

对于TCP来说则没有限制,直接传输图片数据就好了。这个就挺快的,实测在同一局域网下能达到20帧。

下面是详细代码:

#include<opencv2\opencv.hpp>
#include <math.h>
#include <process.h>
#include "winsock.h"
//socket库的lib
#pragma comment(lib,"ws2_32.lib")

#define PORT 8888

using namespace cv;
using namespace std;

SOCKET socksvr,tcpsvr, tcpsockclient;
CHAR szRecv[1472] = { 0 };
CHAR szSend[1472] = { 0 };
struct sockaddr_in clientaddr = { 0 };
struct sockaddr_in tcpclientaddr = { 0 };
int nLen = sizeof(clientaddr);
int tcpnLen = sizeof(tcpclientaddr);
volatile HANDLE udpreceive,tcpreceive;
UINT threadid,tcpthreadid;
int start = 0;


void delay(int s)
{
	while (s > 0)s--;
}
void TCPServerInit()
{
	tcpsvr = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (INVALID_SOCKET == tcpsvr)
	{
		return;
	}
	/*************建立服务器端套接字地址***********************/
	/********************绑定IP和端口号******************/
	struct sockaddr_in svraddr = { 0 };
	svraddr.sin_family = AF_INET;//代表internet协议族
	svraddr.sin_port = htons(PORT);
	//htonl()函数是将u_long型变量从主机字节顺序变为TCP/IP网络字节顺序。
	svraddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//inet_addr("127.0.0.1");//htonl(INADDR_ANY);//此宏为0,当前机器上任意IP地址,也可以指定当前机的ip和端口。//127.0
														  //绑定,将服务器端套接字与服务器端套接字地址绑定
	bind(tcpsvr, (struct sockaddr *)&svraddr, sizeof(svraddr));//指定名字,类型,长度。绑定套接字。
																//侦听
	listen(tcpsvr, SOMAXCONN);//第一个参数是套接字,第二个参数是等待连接队列的最大长度。
}
void UDPServerInit()
{
	//创建socket
	socksvr = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (INVALID_SOCKET == socksvr)
	{
		return;
	}
	//服务器套接字地址
	//绑定ip与端口,先定义端口等一些信息。
	struct sockaddr_in svraddr = { 0 };
	svraddr.sin_family = AF_INET;
	svraddr.sin_port = htons(PORT);
	svraddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	bind(socksvr, (struct sockaddr*)&svraddr, sizeof(svraddr));

}



void TCPSendImage(Mat image)
{
	//int i;
	//int datanum;
	//send(tcpsockclient, "ss", 2, 0);//发送函数。
	//sendto(socksvr, "ss", 2, 0, (struct sockaddr*)&clientaddr, nLen);
	if(start==0)closesocket(tcpsockclient);
	else send(tcpsockclient, (const char*)image.data, image.cols*image.rows, 0);
	//for (i = 0; i < image.rows; i += 2)
	//{
	//	send(tcpsockclient, (const char*)image.ptr<uchar>(i), image.cols * 2, 0);//发送函数。
	//	//sendto(socksvr, (const char*)image.ptr<uchar>(i), image.cols * 2, 0, (struct sockaddr*)&clientaddr, nLen);
	//	//datanum=recvfrom(socksvr, szRecv, sizeof(szRecv), 0, (struct sockaddr*)&clientaddr, &nLen);

	//	//delay(100000);
	//}
	//send(tcpsockclient, "ee", 2, 0);//发送函数。
	//sendto(socksvr, "ee", 2, 0, (struct sockaddr*)&clientaddr, nLen);
	//datanum = recvfrom(socksvr, szRecv, sizeof(szRecv), 0, (struct sockaddr*)&clientaddr, &nLen);
}


void SendImage(Mat image)
{
	int i;
	int datanum;
	sendto(socksvr, "ss", 2, 0, (struct sockaddr*)&clientaddr, nLen);
	for
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值