`
M_ittrue
  • 浏览: 75095 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

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,所以简单的处理是必要的,这些方法,在我的其它文章里可以找得到,至于服务器实现,大家可以联系我与我讨论,阶段性的说明已经完毕,我会在以后继续把我的项目进展告诉大家(当然,包括大家想知道的技术关键实现),话不多说(其实说了很多),谢谢观看..
1
3
分享到:
评论
2 楼 ihopethatwell 2012-01-05  
期待更详细
1 楼 sunleije 2011-02-14  
重点没有啊,想看识别怎么和opencv交互的

相关推荐

Global site tag (gtag.js) - Google Analytics