基于树莓派和安卓客户端的移动监控系统

接触树莓派已经有2周了,在linux发现了好多很不错的工具,其中mjpg-streamphddns还有libcv什么的,都是很不错的工具。加上我会一点点安卓移动端的开发,所以结合一下自己掌握的技术,实现一个基于树莓派和安卓的监控系统。

为了方便大家学习,工程代码已经上传:http://download.csdn.net/detail/devintt/8447193

本文均为原创,转载请注明出处,谢谢。

一、安装mjpg-stream

以下技术参考http://blog.csdn.net/blueslime/article/details/12429411

下面的文字是使用githubjacksonliammjpg-streamer-experimental,在树莓派新版系统上可以进行完全编译,适合强迫症患者。而且还能支持树莓派的专用摄像头Pi Cam

项目工程:https://github.com/jacksonliam/mjpg-streamer

将工程下载后,传送到树莓派系统中解压:

unzip mjpg-streamer-master.zip

编译此工程需要用到cmake和支持库:

sudo apt-get install cmake

sudo apt-get install libjpeg8-dev

然后进入工程mjpg-streamer-experimental,进行完全编译:

make clean all

进入树莓派设置菜单:

sudo raspi-config

移动到第五项“Enable Camera”,回车进入,按tab键切换到“Enable”回车确认。回到主菜单,tab键切换到“Finish”回车确认。树莓派会自动重启。

 

重启后,命令行进入mjpg-streamer-experimental目录

使用下面指令启动普通USB摄像头:

./mjpg_streamer -i "./input_uvc.so" -o "./output_http.so -w ./www"

启动树莓派专用摄像头RaspiCamera的指令是:

./mjpg_streamer -i "./input_raspicam.so" -o "./output_http.so -w ./www"

 

查看图像,在PC端打开浏览器,输入下面网址可以看到静态截图:

http://<树莓派IP>:8080/?action=snapshot

输入下面两条网址可以看到动态图像:

http://<树莓派IP>:8080/?action=stream 

http://<树莓派IP>:8080/javascript_simple.html

 

但是市面上大部分摄像头都是支持YUV的,而不是JPEG的。mjpg-stream支持JPEG和YUV两种格式。直接运行出现i: init_VideoIn failed错误,解决方法:

1、打开以下文件:

sudo nano mjpg-streamer/plugins/input_uvc/input_uvc.c

2、翻到大概第三页将一行中的:

int width = 640, height = 480, fps = -1, format = V4L2_PIX_FMT_MJPEG, i;

修改成

int width = 640, height = 480, fps = -1, format = V4L2_PIX_FMT_YUYV, i;

需要重新编译才会有效。

二、编写安卓客户端

其实完成第一步就几乎完成了很大部分的工作了,用手机浏览器输入ip地址就可以查看。但是编写手机客户端有利于摄像头的管理和加入脸部捕获什么的,让监控系统更加逼格。

先介绍一下用http实现图片获取的方法,我在另一篇文章里面说的比较清晰,

http://blog.csdn.net/devintt/article/details/38893869

我在这里主要说说图片获取之后的处理和显示的方法。

http获取图片数据流

  private void doGet() {
        //get http img
        String url = "http://192.168.0.105:8080/?action=snapshot";
//        Log.d(TAG, url);
        myHttpThreadGet = new HttpThreadGet(url, HttpThreadGet.GETIMG, handler);
        myHttpThreadGet.start();
}

消息传递获取,这里只用了获取图片

/************************** msg接收 *************************/

        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case HttpThreadPost.POST:
                        result = (String) msg.obj;
                        break;
                    case HttpThreadGet.GET:
                        result = (String) msg.obj;
                        break;
                    case HttpThreadGet.GETIMG:
                        buffer = (byte[])msg.obj;
                        try {
                            image = BitmapFactory.decodeByteArray(buffer, 0, buffer.length, BitmapFactoryinfo);
                            faceDetect(image);
                        } catch (Exception e) {
                            Log.e(TAG, e.toString());
                        }
                        doGet();    //再请求
                        break;
                    default:
                        break;
                }
            }
        };

由于图片是JPEG格式的数据流,需要通过BitmapFactory重新编码,如果要实现人脸识别FaceDetector的话需要将图片格式化Bitmap.Config.RGB_565

/************************** format bitmap *************************/

    private void detectSetup() {
        BitmapFactoryinfo = new BitmapFactory.Options();
        BitmapFactoryinfo.inPreferredConfig = Bitmap.Config.RGB_565;  //构造位图生成的参数,必须为565。类名+enum
}

 

获取到图片并格式化之后就可以经行显示了,如果要加入人脸检测的话,就调用这个。

以下技术参考http://blog.csdn.net/zhandoushi1982/article/details/8613916

这里的方法可以将检测出来的人脸经行描绘出来,并且可以同时识别多个,由于我们的图片是静态一张一张的,所以我们用的是静态的方法。

/************************** face detect *************************/

    private void faceDetect(Bitmap fBitmap) {
//        myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.baby, BitmapFactoryOptionsbfo);
        int imageWidth = fBitmap.getWidth();
        int imageHeight = fBitmap.getHeight();
        myFace = new FaceDetector.Face[numberOfFace];       //分配人脸数组空间
        myFaceDetect = new FaceDetector(imageWidth, imageHeight, numberOfFace);
        numberOfFaceDetected = myFaceDetect.findFaces(fBitmap, myFace);    //FaceDetector 构造实例并解析人脸
        countertext.setText("numberOfFaceDetected is " + numberOfFaceDetected);
        Log.i(TAG,"numberOfFaceDetected is " + numberOfFaceDetected);
        Bitmap bitmapTemp = Bitmap.createBitmap(fBitmap.getWidth(), fBitmap.getHeight(), Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(bitmapTemp);
        canvas.drawColor(Color.TRANSPARENT);
        Paint myPaint = new Paint();
        myPaint.setColor(Color.GREEN);
        myPaint.setStyle(Paint.Style.STROKE);
        myPaint.setStrokeWidth(3);          //设置位图上paint操作的参数
        canvas.drawBitmap(fBitmap, 0, 0, myPaint);

        for(int i=0; i < numberOfFaceDetected; i++){
            Face face = myFace[i];
            PointF myMidPoint = new PointF();
            face.getMidPoint(myMidPoint);
            myEyesDistance = face.eyesDistance();   //得到人脸中心点和眼间距离参数,并对每个人脸进行画框
            canvas.drawRect(            //矩形框的位置参数
                    (int)(myMidPoint.x - myEyesDistance),
                    (int)(myMidPoint.y - myEyesDistance),
                    (int)(myMidPoint.x + myEyesDistance),
                    (int)(myMidPoint.y + myEyesDistance),
                    myPaint);
        }
        imageview.setImageBitmap(bitmapTemp);
}


为了防止退出的时候没有关闭http通信,造成下次再打开会出现FC,所以需要中断http通信。

@Override
    protected void onDestroy() {
        super.onDestroy();
        if(myHttpThreadGet.isAlive()) {
            myHttpThreadGet.interrupt();
        }
}

最后附上效果图:




  • 1
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值