nabice 发表于 2018-9-19 14:32:19

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

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

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

using namespace cv;
using namespace std;

char FORCE = 0;

void sigal_handler(int signo) {
    if(signo == SIGUSR1) {
      FORCE = 1;
    } else if(signo == SIGTERM) {
      FORCE = 2;
    }
}

int main(int argc, char *argv[])
{
    VideoCapture cap(0);
    if(!cap.isOpened())
      return -1;
    if (signal(SIGUSR1, sigal_handler) == SIG_ERR) {
      return -2;
    }
    if (signal(SIGTERM, sigal_handler) == SIG_ERR) {
      return -2;
    }
    Mat prev, current, diff, store1, store2;
    int nz, diff_count = 0;
    VideoWriter vw;
    cap >> prev;
    cvtColor(prev, prev, CV_BGR2GRAY);
    chdir("/dir/am");
    for(;;) {
      if(FORCE == 2) {
            return 0;
      }
      if(!cap.read(current)) {
            cout <<"restart" <<endl;
            cap.release();
            cap.open(0);
      }
      if(FORCE) {
            store1 = store2.clone();
      }
      store2 = current.clone();
      cvtColor(current, current, CV_BGR2GRAY);
      absdiff(prev, current, diff);
      blur(diff, diff, Size(5, 5));
      threshold(diff, diff, 10, 255, THRESH_BINARY_INV);
      nz = countNonZero(diff);
      if(nz < 280000 || FORCE) {
            if(diff_count == 0 && FORCE == 0) {
                diff_count = 1;
            } else {
                time_t rawtime;
                struct tm *timeinfo;
                char TIME;
                time(&rawtime);
                FORCE = 0;
                string t = to_string(rawtime);
                timeinfo = localtime(&rawtime);
                strftime(TIME, 40, "%F %T", timeinfo);
                putText(store1, TIME, Point(10, 464), CV_FONT_HERSHEY_PLAIN, 1, Scalar(255,255,255));
                imwrite(t + ".jpg", store1);
                vw.open(t + ".mp4", VideoWriter::fourcc('a','v','c','1'), 5, Size(640, 480));
                if(!vw.isOpened()) {
                  cout <<"Write video failed." <<endl;
                } else {
                  vw.write(store1);
                  for(int i=0;i<50;i++) {
                        vw.write(store2);
                        usleep(200000);
                        cap >> store2;
                  }
                  vw.release();
                }
                current = store2.clone();
                cvtColor(current, current, CV_BGR2GRAY);
            }
            store1 = store2.clone();
            prev = current;
            continue;
      }
      diff_count = 0;
      sleep(3);
      prev = current;
    }
    return 0;
}3、搭建web服务器
前面之所以强调mp4,是因为mp4方便在浏览器播放。我用go做的服务器,其他的就见仁见智了。


页: [1]
查看完整版本: CB4的运动探测并自动记录的系统