3.使用树莓派控制摄像头采集视频及运动检测

条件: 树梅派安装opencv和免驱动的摄像头

c源码:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <time.h>            //时间函数头
 4 #include "opencv.hpp"
 5 
 6 /**
 7  * A program to detect motion in front of an USB camera using OpenCV.
 8  **/
 9 
10 int main(int argc, char **argv) {
11   int detectThreshold = 19;        //运动检测预设值(时间)
12   if (argc >= 2) {                //判断参数是否充足判断
13     detectThreshold = atoi(argv[1]);
14     printf("=== Motion detection threshold has been set to: [%d] ===\n", detectThreshold);
15   }
16 
17   /* init 摄影机 */
18   CvCapture* pCapture = cvCreateCameraCapture(0);
19   if (NULL == pCapture) {
20     fprintf(stderr, "Can't initialize webcam!\n");
21     return 1;
22   }
23   cvSetCaptureProperty(pCapture, CV_CAP_PROP_FRAME_WIDTH, 640);
24   cvSetCaptureProperty(pCapture, CV_CAP_PROP_FRAME_HEIGHT, 480);
25   cvSetCaptureProperty(pCapture, CV_CAP_PROP_BRIGHTNESS, 20);
26   cvSetCaptureProperty(pCapture, CV_CAP_PROP_CONTRAST, 10);
27 
28   /* 图像指针 */
29   IplImage *pFrameA = cvQueryFrame(pCapture);    //从摄像头或者文件中抓取并返回一帧
30   IplImage *pFrameB = cvCreateImage(cvSize(pFrameA->width, pFrameA->height), pFrameA->depth, pFrameA->nChannels); //创建图像((矩形框大小),颜色深度,通道)
31   //就是直接把pFrameB这个图像复制给dst,不用给 pFrameDiff 特地开辟内存空间了
32   IplImage *pFrameDiff = cvCloneImage(pFrameB);
33  
34   int nDims = 256;
35   float hRangesArr[] = {0, 255};
36   float* hRanges = hRangesArr;
37   /*直方图,表上数字图像中亮度分布的一种图,标绘了每个像素的亮度数(可以使用直方图对图像进行二值化,通过计算差异图像的直方图,可以知道这两附图有没有差异*/
38   IplImage *pGrayscaleImage = NULL;
39   CvHistogram *pHist = cvCreateHist(1, &nDims, CV_HIST_ARRAY, &hRanges, 1);
40   float fMaxValue = 0.0;
41 
42   time_t ts = 0;  //用于记录当前时间戳和防止1次触发多次监测检测
43   while(true) {
44     pFrameA = cvQueryFrame(pCapture);        //从摄像头或者文件中抓取并返回一帧
45     if(!pFrameA){                                //判断是否成功采集 
46       fprintf(stdout,"Can't grab images!\n");
47       break;
48     }
49     cvAbsDiff(pFrameB,pFrameA,pFrameDiff);  //计算两幅图像的差异
50     cvCopy(pFrameA,pFrameB);                //复制图像,第一个参数是源与第二目标
51     //实现了8位深的灰度图像
52     pGrayscaleImage = cvCreateImage(cvGetSize(pFrameDiff),IPL_DEPTH_8U,1);
53     //void cvCvtColor( const CvArr* src, CvArr* dst, int code );
54     //src 输入的 8-bit,16-bit或 32-bit单倍精度浮点数影像。
55     //dst 输出的8-bit, 16-bit或 32-bit单倍精度浮点数影像。
56     //code 色彩空间转换的模式,该code来实现不同类型的颜色空间转换。比如CV_BGR2GRAY表示转换为灰度图,CV_BGR2HSV将图片从RGB空间转换为HSV空间。其中当code选用CV_BGR2GRAY时,dst需要是单通道图片。当code选用CV_BGR2HSV时,对于8位图,需要将RGB值归一化到0-1之间。这样得到HSV图中的H范围才是0-360,S和V的范围是0-1。
57     cvCvtColor(pFrameDiff, pGrayscaleImage, CV_BGR2GRAY);
58     cvCalcHist(&pGrayscaleImage, pHist, 0, 0);
59 
60     fMaxValue = 0.0;
61     //找到直方图中最大最小直方块,以及他们的位置,并保存到 fMaxValue 中
62     cvGetMinMaxHistValue(pHist, 0, &fMaxValue, 0, 0);
63     //用于对直方图的比例缩放
64     cvConvertScale(pHist->bins, pHist->bins, (fMaxValue ? (255.0 / fMaxValue) : 0.0), 0);
65     //检查是否有运动状态
66     double dRealtimeVal = cvGetReal1D(pHist->bins, 10);
67     if (dRealtimeVal > detectThreshold) {  //触发
68       time_t currentTimestamp = time(NULL);
69       if (currentTimestamp - ts >= 1) {    //对时间戳进行判断
70     ts = currentTimestamp;
71     printf("Motion detected @ %s", ctime(&currentTimestamp));
72       }
73     }
74     cvReleaseImage(&pGrayscaleImage);  //释放内存
75     pGrayscaleImage = NULL;
76  
77     cvWaitKey(10);  //等待n毫秒
78   }
79  //停止捕获图像和释放资源
80   cvReleaseCapture(&pCapture);
81   cvReleaseHist(&pHist);
82   cvReleaseImage(&pFrameA);
83   cvReleaseImage(&pFrameB);
84   cvReleaseImage(&pFrameDiff);
85 
86   pCapture = NULL;
87   pHist = NULL;
88   pFrameA = NULL;
89   pFrameB = NULL;
90   pFrameDiff = NULL;
91 
92   return 0;
93 }

 

脚本:

  detect-motion-using-opencv.sh  

 1 #!/bin/bash
 2 # A script to invoke a C program to detect motion in front of an USB camera using OpenCV.
 3 
 4 CURRENT_DIR=`dirname "$0"`
 5 WORKING_HOME=`cd "$CURRENT_DIR"; pwd`
 6 
 7 SOURCE_FILE=$WORKING_HOME/motion-detection.c
 8 BIN_FILE=$WORKING_HOME/motion-detection
 9 MOTION_DETECTION_THRESHOLD=100
10 
11 # compile the source code if the executable bin not exists
12 if [ ! -f $BIN_FILE ]; then
13     echo "Compiling $SOURCE_FILE ..."
14     g++ -I/usr/include/opencv2/  `pkg-config --cflags opencv --libs opencv` $SOURCE_FILE -o $BIN_FILE
15     if [ $? -ne 0 ]; then
16     echo "Failed to compile $SOURCE_FILE"
17     exit 1
18     fi
19 fi
20 
21 # run the program
22 $BIN_FILE $MOTION_DETECTION_THRESHOLD

 

posted @ 2016-07-26 10:00  极客先锋  阅读(2713)  评论(0编辑  收藏  举报