树莓派+安卓随身远程监控系统

树莓派+安卓随身远程监控系统

🗨

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

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

 

一、安装mjpg-stream

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

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

 

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

将工程下载或 git clone https://github.com/jacksonliam/mjpg-streamer.git 后,传送到树莓派系统中解压:

 

  1. unzip mjpg-streamer-master.zip  

 

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

 
  1. sudo apt-get install cmake  
  2.   
  3. sudo apt-get install libjpeg8-dev  

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

 

 
  1. make clean all  

 

进入树莓派设置菜单:

 

 
  1. sudo raspi-config  

 

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

 

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

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

 

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

 

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

 

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

 

 

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

 

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

 

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

 
  1. http://<树莓派IP>:8080/?action=stream   
  2.   
  3. http://<树莓派IP>:8080/javascript_simple.html  

 

 

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

1、打开以下文件:

 

 
  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获取图片数据流

 

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

 

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

 
  1. /************************** msg接收 *************************/  
  2.   
  3.         handler = new Handler() {  
  4.             @Override  
  5.             public void handleMessage(Message msg) {  
  6.                 switch (msg.what) {  
  7.                     case HttpThreadPost.POST:  
  8.                         result = (String) msg.obj;  
  9.                         break;  
  10.                     case HttpThreadGet.GET:  
  11.                         result = (String) msg.obj;  
  12.                         break;  
  13.                     case HttpThreadGet.GETIMG:  
  14.                         buffer = (byte[])msg.obj;  
  15.                         try {  
  16.                             image = BitmapFactory.decodeByteArray(buffer, 0, buffer.length, BitmapFactoryinfo);  
  17.                             faceDetect(image);  
  18.                         } catch (Exception e) {  
  19.                             Log.e(TAG, e.toString());  
  20.                         }  
  21.                         doGet();    //再请求  
  22.                         break;  
  23.                     default:  
  24.                         break;  
  25.                 }  
  26.             }  
  27.         };  

 

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

 
  1. /************************** format bitmap *************************/  
  2.   
  3.     private void detectSetup() {  
  4.         BitmapFactoryinfo = new BitmapFactory.Options();  
  5.         BitmapFactoryinfo.inPreferredConfig = Bitmap.Config.RGB_565;  //构造位图生成的参数,必须为565。类名+enum  
  6. }  
  7.   
  8.    

 

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

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

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

 
  1. /************************** face detect *************************/  
  2.   
  3.     private void faceDetect(Bitmap fBitmap) {  
  4. //        myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.baby, BitmapFactoryOptionsbfo);  
  5.         int imageWidth = fBitmap.getWidth();  
  6.         int imageHeight = fBitmap.getHeight();  
  7.         myFace = new FaceDetector.Face[numberOfFace];       //分配人脸数组空间  
  8.         myFaceDetect = new FaceDetector(imageWidth, imageHeight, numberOfFace);  
  9.         numberOfFaceDetected = myFaceDetect.findFaces(fBitmap, myFace);    //FaceDetector 构造实例并解析人脸  
  10.         countertext.setText("numberOfFaceDetected is " + numberOfFaceDetected);  
  11.         Log.i(TAG,"numberOfFaceDetected is " + numberOfFaceDetected);  
  12.         Bitmap bitmapTemp = Bitmap.createBitmap(fBitmap.getWidth(), fBitmap.getHeight(), Bitmap.Config.RGB_565);  
  13.         Canvas canvas = new Canvas(bitmapTemp);  
  14.         canvas.drawColor(Color.TRANSPARENT);  
  15.         Paint myPaint = new Paint();  
  16.         myPaint.setColor(Color.GREEN);  
  17.         myPaint.setStyle(Paint.Style.STROKE);  
  18.         myPaint.setStrokeWidth(3);          //设置位图上paint操作的参数  
  19.         canvas.drawBitmap(fBitmap, 00, myPaint);  
  20.   
  21.         for(int i=0; i < numberOfFaceDetected; i++){  
  22.             Face face = myFace[i];  
  23.             PointF myMidPoint = new PointF();  
  24.             face.getMidPoint(myMidPoint);  
  25.             myEyesDistance = face.eyesDistance();   //得到人脸中心点和眼间距离参数,并对每个人脸进行画框  
  26.             canvas.drawRect(            //矩形框的位置参数  
  27.                     (int)(myMidPoint.x - myEyesDistance),  
  28.                     (int)(myMidPoint.y - myEyesDistance),  
  29.                     (int)(myMidPoint.x + myEyesDistance),  
  30.                     (int)(myMidPoint.y + myEyesDistance),  
  31.                     myPaint);  
  32.         }  
  33.         imageview.setImageBitmap(bitmapTemp);  
  34. }  

 

 

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

 
  1. @Override  
  2.     protected void onDestroy() {  
  3.         super.onDestroy();  
  4.         if(myHttpThreadGet.isAlive()) {  
  5.             myHttpThreadGet.interrupt();  
  6.         }  
  7. }  

 

最后附上效果图:

 

 

 


 

 

树莓派之网络摄像头配置

0x01.安装支持库

1
$ sudo aptitude install libjpeg8-dev imagemagick libv4l-dev cmake

0x02.编译mjpg-streamer

当前用户是pi,目录是/home/pi/。

1
2
3
4
5
$ git clone https://github.com/jacksonliam/mjpg-streamer.git
$ cd mjpg-streamer/mjpg-streamer-experimental/
$ sudo make clean all
$ cd ..
$ sudo chown -R pi:pi mjpg-streamer-experimental/

0x03.编写启动脚本

1
$ sudo vi /etc/init.d/webcam

0x04.脚本内容

修改代码中第15行的DAEMON变量为mjpg-streamer的执行目录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#!/bin/sh

# /etc/init.d/webcam

### BEGIN INIT INFO
# Provides: webcam
# Required-Start: $network
# Required-Stop: $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: mjpg_streamer for webcam
# Description: Streams /dev/video0 to http://IP/?action=stream
### END INIT INFO

DAEMON=/home/pi/mjpg-streamer/mjpg-streamer-experimental
WC_USER=user
WC_PASSWORD=password
WC_PORT=12345

f_message(){
echo "[+] $1"
}

# Carry out specific functions when asked to by the system
case "$1" in
start)
f_message "Starting mjpg_streamer"
$DAEMON/mjpg_streamer -b -i "$DAEMON/input_uvc.so" -o "$DAEMON/output_http.so -w $DAEMON/www -c $WC_USER:$WC_PASSWORD -p $WC_PORT"
sleep 2
f_message "mjpg_streamer started"
;;
stop)
f_message "Stopping mjpg_streamer…"
killall mjpg_streamer
f_message "mjpg_streamer stopped"
;;
restart)
f_message "Restarting daemon: mjpg_streamer"
killall mjpg_streamer
$DAEMON/mjpg_streamer -b -i "$DAEMON/input_uvc.so" -o "$DAEMON/output_http.so -w $DAEMON/www -c $WC_USER:$WC_PASSWORD -p $WC_PORT"
sleep 2
f_message "Restarted daemon: mjpg_streamer"
;;
status)
pid=`ps -A | grep mjpg_streamer | grep -v "grep" | grep -v mjpg_streamer. | awk '{print $1}' | head -n 1`
if [ -n "$pid" ];
then
f_message "mjpg_streamer is running with pid ${pid}"
f_message "mjpg_streamer was started with the following command line"
cat /proc/${pid}/cmdline ; echo ""
else
f_message "Could not find mjpg_streamer running"
fi
;;
*)
f_message "Usage: $0 {start|stop|status|restart}"
exit 1
;;
esac
exit 0

默认登录的用户名是user,密码是password,端口是12345(可以在代码中第16,17,18行修改)。

0x05.赋予脚本执行权限

1
$ sudo chmod +x /etc/init.d/webcam

0x06.配置脚本开机启动

1
$ sudo update-rc.d webcam defaults

0x07.启动网络摄像头后台程序

1
$ sudo /etc/init.d/webcam start

0x08.查看网络摄像头运行状态

1
$ sudo /etc/init.d/webcam status

0x09.重启网络摄像头后台程序

1
$ sudo /etc/init.d/webcam restart

0x10.停止网络摄像头后台程序

1
$ sudo /etc/init.d/webcam stop

0x11.浏览器中查看网络摄像头

访问地址:http://树莓派的IP地址:自定义的端口号

 


 

Stream with MJPG-streamer

Here you find a detailed description how to install MJPG-streamer:

1. Install build dependencies
sudo apt-get install libjpeg8-dev imagemagick libv4l-dev make gcc git cmake g++

2. Download MJPG-streamer
git clone https://github.com/jacksonliam/mjpg-streamer.git

3. Open directory
cd mjpg-streamer/mjpg-streamer-experimental/

4. Build MJPG-streamer
make mjpg_streamer input_file.so output_http.so input_uvc.so

5. Install MJPG-streamer
sudo mkdir /usr/local/mjpg-streamer
sudo cp mjpg_streamer /usr/local/mjpg-streamer
sudo cp output_http.so input_file.so input_uvc.so /usr/local/mjpg-streamer
sudo cp -r www /usr/local/mjpg-streamer

6. Run MJPG-streamer as background process
cd /usr/local/mjpg-streamer;sudo ./mjpg_streamer -i "/usr/local/mjpg-streamer/input_uvc.so" -o "/usr/local/mjpg-streamer/output_http.so -w /usr/local/mjpg-streamer/www" -b

7. Make it start at bootup automatically (optinal)
If you do not want to start MJPG-streamer manually after every restart:
cd /etc/init.d
sudo wget http://www.repetier-server.com/en/software/extras/mjpgstreamer-init-debian/mjpgstreamer
sudo chmod 755 mjpgstreamer
sudo update-rc.d mjpgstreamer defaults

Now you can use these commands to start and stop MJPG-streamer:
sudo /etc/init.d/mjpgstreamer start
sudo /etc/init.d/mjpgstreamer stop
sudo /etc/init.d/mjpgstreamer restart
sudo /etc/init.d/mjpgstreamer status

8. Get ip address
After installing the MJPG-streamer you need to get the local ip address of the server. With ip addr you find your ip address in such a line:

inet 192.168.2.3/24 brd 192.168.2.255 scope global eth0

Here your ip address would be 192.168.2.3.

9. Enter the URLs
This are the required URLs (replace <ip address> with your ip address):
Dynamic Image URL: http://<ip address>:8080/?action=stream
Static Image URL: http://<ip address>:8080/?action=snapshot

 


频道:Android