CubieBoard中文论坛

 找回密码
 立即注册
搜索
热搜: unable
查看: 7250|回复: 0

CB4的运动探测并自动记录的系统

[复制链接]
发表于 2018-9-19 14:32:19 | 显示全部楼层 |阅读模式
垃圾堆里找到一个摄像头,拿来玩玩。
环境:CC-A80 linux-linaro-server
1、自行编译ffmpeg和opencv,一定要自己编译,不然系统自带的只能生成avi格式文件,无法生成mp4格式的视频文件。
注意事项:
(1)编译opencv时, cmake如下:
  1. mkdir build && cd build
  2. cmake -DWITH_FFMPEG=ON -DBUILD_PROTOBUF=OFF ../
复制代码
注意cmake完了要在输出中检查ffmpeg是否为ON。
(2)opencv的库默认放在了/usr/local/lib/arm-linux-gnueabihf/中,cb4默认没有把这个路径添加到ld.so.conf中,咱们手动加上会方便一些。

2、编写代码:
就是简单的检测是否运动啦,我的是这样,如果连续两帧画面都有变化,就判断为运动,避免有时光线变化造成干扰。然后就是可以发送信号给程序,使其立马拍个视频。摄像头参数分辨率什么的,根据实际情况调整。
  1. #include "opencv2/opencv.hpp"
  2. #include<signal.h>
  3. #include<unistd.h>

  4. using namespace cv;
  5. using namespace std;

  6. char FORCE = 0;

  7. void sigal_handler(int signo) {
  8.     if(signo == SIGUSR1) {
  9.         FORCE = 1;
  10.     } else if(signo == SIGTERM) {
  11.         FORCE = 2;
  12.     }
  13. }

  14. int main(int argc, char *argv[])
  15. {
  16.     VideoCapture cap(0);
  17.     if(!cap.isOpened())
  18.         return -1;
  19.     if (signal(SIGUSR1, sigal_handler) == SIG_ERR) {
  20.         return -2;
  21.     }
  22.     if (signal(SIGTERM, sigal_handler) == SIG_ERR) {
  23.         return -2;
  24.     }
  25.     Mat prev, current, diff, store1, store2;
  26.     int nz, diff_count = 0;
  27.     VideoWriter vw;
  28.     cap >> prev;
  29.     cvtColor(prev, prev, CV_BGR2GRAY);
  30.     chdir("/dir/am");
  31.     for(;;) {
  32.         if(FORCE == 2) {
  33.             return 0;
  34.         }
  35.         if(!cap.read(current)) {
  36.             cout <<"restart" <<endl;
  37.             cap.release();
  38.             cap.open(0);
  39.         }
  40.         if(FORCE) {
  41.             store1 = store2.clone();
  42.         }
  43.         store2 = current.clone();
  44.         cvtColor(current, current, CV_BGR2GRAY);
  45.         absdiff(prev, current, diff);
  46.         blur(diff, diff, Size(5, 5));
  47.         threshold(diff, diff, 10, 255, THRESH_BINARY_INV);
  48.         nz = countNonZero(diff);
  49.         if(nz < 280000 || FORCE) {
  50.             if(diff_count == 0 && FORCE == 0) {
  51.                 diff_count = 1;
  52.             } else {
  53.                 time_t rawtime;
  54.                 struct tm *timeinfo;
  55.                 char TIME[40];
  56.                 time(&rawtime);
  57.                 FORCE = 0;
  58.                 string t = to_string(rawtime);
  59.                 timeinfo = localtime(&rawtime);
  60.                 strftime(TIME, 40, "%F %T", timeinfo);
  61.                 putText(store1, TIME, Point(10, 464), CV_FONT_HERSHEY_PLAIN, 1, Scalar(255,255,255));
  62.                 imwrite(t + ".jpg", store1);
  63.                 vw.open(t + ".mp4", VideoWriter::fourcc('a','v','c','1'), 5, Size(640, 480));
  64.                 if(!vw.isOpened()) {
  65.                     cout <<"Write video failed." <<endl;
  66.                 } else {
  67.                     vw.write(store1);
  68.                     for(int i=0;i<50;i++) {
  69.                         vw.write(store2);
  70.                         usleep(200000);
  71.                         cap >> store2;
  72.                     }
  73.                     vw.release();
  74.                 }
  75.                 current = store2.clone();
  76.                 cvtColor(current, current, CV_BGR2GRAY);
  77.             }
  78.             store1 = store2.clone();
  79.             prev = current;
  80.             continue;
  81.         }
  82.         diff_count = 0;
  83.         sleep(3);
  84.         prev = current;
  85.     }
  86.     return 0;
  87. }
复制代码
3、搭建web服务器
前面之所以强调mp4,是因为mp4方便在浏览器播放。我用go做的服务器,其他的就见仁见智了。


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|粤ICP备13051116号|cubie.cc---深刻的嵌入式技术讨论社区

GMT+8, 2024-3-28 21:55 , Processed in 0.021302 second(s), 15 queries .

Powered by Discuz! X3.4

© 2001-2012 Comsenz Inc. | Style by Coxxs

返回顶部