C:Android camera S:PC opencV阶段总结

最近在跟一学长在合作开发一项目,以PC这Server端,Android为Client端,通过调用Android HTC的Camera获取图片帧数据,利用Socket与Server建立的无线连接将数据进行传输,Server以C++编程为基础对传回来的数据恢原,并以opencV作为核心技术处理,进期阶段是想实现图片的自动识别,后期阶段是对移动物体的更高精确实别,该项目最初定义,属于一类实事监控软件。

由于Android方面的低子比较薄,而学长在opencV方面已有建树,所以,我们打算协同攻克AndroidClient端。下面,让我来浅谈我们的开发过程(该项目现在只处于初级阶段)。

项目不是写出来的,而是一步一步测试出来的。无可非议,一条最基本的C/S连接是必须的。一般的Android软件开发,我想都会经过三个开台的。一:PC android AVD(模拟器)二:embedded (嵌入式) 三:嵌入式程序移植到真机

我们是直接不经过第二步的,毕竟我们的项目目的是just for fun. 为减少模拟器上所得的可执行.apk程序能较快移植到HTC真机上测试,我们应用了第三方基于WIFI数据转输软件-discover;建立连接中,Socket网络编程还是老方法,基于TCP/IP协议
// 创建Socket
socket = new Socket("192.168.1.90", 54321);
Log.v("Conection", "Conection Success!");//这是android中的调试语句
// 向服务器发送消息
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.println(message);
// 接收来自服务器的消息
BufferedReader br = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String msg = br.readLine();

在手机上运行一个程序,很多都会涉及到手机相关底层线程的权限应用,我们最初同样忽略了这一点以致于调试了半天。是的,相信你已经猜出来。我们还必须在AndroidManifest.xml里面进行权限配置,在接下来的Camera使用也同样要配置权限的。
这样,手机客户端就可以发送信息了,服务器也能较容接收到信息。
我们可以把AndroidManifest转换到xml格式然后加入一句:
<uses-permission android:name="android.permission.INTERNET" />

接下来,我们就改变发送信息的类型。我们第二次是用位图作为发送数据,当然,为了较快见到成效,最好使用小一点的,在Android中只支持位图与png,jpeg的转换。我们是先预置一张jpeg格式的图片在res/drawable-hdpi/icon.jpeg中,然后通过R.drawable.icon获取资android自动为icon分配的资源标识去调用图片的。然后将其转化为Bitmap位图,以三通道格式进行解释,最后把相关数据发送,服务器端自然是按照已定的协议进行还原,显示。
//将图片读入
InputStream is = getResources().openRawResource(R.drawable.icon);
//把图片转换为位图
Bitmap mBitmap = BitmapFactory.decodeStream(is);
byte type = 1;//定义数据协议类型
//获取位图的宽和高
int Width = mBitmap.getWidth();
int Height = mBitmap.getHeight();
//该方法效率虽高,但是传入的pixels必须是int数组,为降低内存消耗且先用以下办法
//mBitmap.getPixels(pixels, offset, stride, x, y, width, height);
//存储位图像素的数组
byte[] imagedata = new byte[3*Width*Height];
for(int row=0;row<Width;row++)
for(int col=0;col<Height;col++){
int index = 3*(Width*row+col);
int argb=mBitmap.getPixel(row, col);
//位运算,因为在服务器端rgb位置是刚好相反的
byte r = (byte)((argb>>16)&0xff);
byte g = (byte)((argb>>8)&0xff);
byte b = (byte)((argb)&0xff);
imagedata[index + 0] = r;
imagedata[index + 1] = g;
imagedata[index + 2] = b;
}
//按协议发送数据
dos.writeByte(type);
dos.writeInt(Width);
dos.writeInt(Height);
dos.write(imagedata);
Log.v("flymessage", "Success!!");
socket.close();

接下来我们就要去从HTC的摄像头中获取一帧帧的图片发送给服务端,并形成一视频流。
对不起大家,现在才来更新。我们的进度已经去到了获得视频流的阶段,相应的技术点,让我一一向大家道来.
在实现这一过程中,我们遇到了最不想看到的时间,硬件问题.由于我们拿来做测试的真机并不是行货,导致程序在模拟器上能运行,但在真机上运行时,最关键获得位图信息data[]的方法却根本没有被调用,经过上网查找,才知道这是版本问题。我们曾试过降低版本,甚至对机子进行刷机,依然没有得到很好的解决,最终,只能等等行货机的出实...
终于,一部Mo的里程杯出现了...
对于上面所说的技术点,随着项目的进度,我们都做了相应的修改。主要还是集中在对图象的处这块上,很明显,图象的获取以及处理是我们的关键技术.在android中,从camera上获得的原始数据是YCbCr_420_SP,当然,这个可能会因版本的不同不有所差异。为了保真同时更易于我们的解码,我们试把它改成MPGE/RGBA888等熟悉的编码方式,结果,事与愿违。在服务端上我们用的是C++语言,两种语言对付同一种编码,总是难以达到最好的效果。有时失真度很大,更有时根本无法传送。这一直是我们苦恼的问题。有时程序在模拟器上能运行,在真正上却不行,我们怀疑是权限的问题。然后,想要修改这一格式只要获得camera的权限既可,这个我们是在一开始就获得了的,寻找解决问题的方法中...
由于项目是想从手机获得图片后,再进行图片的处理,因此对图片的色彩要求并不高,也就是说,就算是黑白图片,也已经满足要求.所以,我们就只获取黑白图片得了,在整个data[]中Withd*heigh前面是RGB数据,后面是A透明度数据(也就是色彩数据),因此我们只抽获了前面的部分,接下来的就简单多了,也就是socket数据通信...
嗯,补充一点,虽然是只要黑白图片,但原始数据是YCbCr_420_SP,所以简单的处理是必要的,这些方法,在我的其它文章里可以找得到,至于服务器实现,大家可以联系我与我讨论,阶段性的说明已经完毕,我会在以后继续把我的项目进展告诉大家(当然,包括大家想知道的技术关键实现),话不多说(其实说了很多),谢谢观看..
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值