9crk

9crk

1个粉丝

34

问答

0

专栏

6

资料

9crk  发布于  2015-02-01 23:52:53
采纳率 0%
34个问答
7573

开源motion代码分析

本帖最后由 9crk 于 2015-2-3 13:21 编辑

motion:国外的开源视频移动侦测软件,集成了ffmpeg和流媒体服务,提供运动报警(执行脚本)及录像功能(不过不支持H264)。

借花献佛,主要分析一下其运动侦测算法。

项目主页:http://sourceforge.net/projects/motion/ 源码已上传: [attach]2241[/attach] motion接口在motion.c文件中 static void motion_loop(void arg) 主要关注/ MOTION LOOP - MOTION DETECTION SECTION / 这一段代码。 [code] /* The actual motion detection takes place in the following

  • diffs is the number of pixels detected as changed
  • Make a differences picture in image_out
  • 1.做帧差

  • alg_diff_standard is the slower full feature motion detection algorithm
  • alg_diff first calls a fast detection algorithm which only looks at a
  • fraction of the pixels. If this detects possible motion alg_diff_standard
  • is called. */

        if (cnt->threshold && !cnt->pause) {
            /* if we've already detected motion and we want to see if there's
             * still motion, don't bother trying the fast one first. IF there's
             * motion, the alg_diff will trigger alg_diff_standard
             * anyway
             */
            if (cnt->detecting_motion || cnt->conf.setup_mode)
                cnt->current_image->diffs = alg_diff_standard(cnt, cnt->imgs.image_virgin);
            else
                cnt->current_image->diffs = alg_diff(cnt, cnt->imgs.image_virgin);

    2.开关灯处理 /* Lightswitch feature - has light intensity changed?

    • This can happen due to change of light conditions or due to a sudden change of the camera
    • sensitivity. If alg_lightswitch detects lightswitch we suspend motion detection the next
    • 5 frames to allow the camera to settle.
    • Don't check if we have lost connection, we detect "Lost signal" frame as lightswitch */ if (cnt->conf.lightswitch && !cnt->lost_connection) { if (alg_lightswitch(cnt, cnt->current_image->diffs)) { if (cnt->conf.setup_mode) motion_log(-1, 0, "Lightswitch detected");

                  if (cnt->moved < 5)
                      cnt->moved = 5;
      
                  cnt->current_image->diffs = 0;
                  alg_update_reference_frame(cnt, RESET_REF_FRAME);
              }
          }

      3.开关灯滤波 /* Switchfilter feature tries to detect a change in the video signal

    • from one camera to the next. This is normally used in the Round
    • Robin feature. The algorithm is not very safe.
    • The algorithm takes a little time so we only call it when needed
    • ie. when feature is enabled and diffs>threshold.
    • We do not suspend motion detection like we did for lightswitch
    • because with Round Robin this is controlled by roundrobin_skip. */ if (cnt->conf.switchfilter && cnt->current_image->diffs > cnt->threshold) { cnt->current_image->diffs = alg_switchfilter(cnt, cnt->current_image->diffs, cnt->current_image->image);

              if (cnt->current_image->diffs <= cnt->threshold) {
                  cnt->current_image->diffs = 0;
      
                  if (cnt->conf.setup_mode)
                      motion_log(-1, 0, "Switchfilter detected");
              }
          }

      4.噪点消除 /* Despeckle feature

    • First we run (as given by the despeckle option iterations
    • of erode and dilate algorithms.[color=Red]//主要使用了腐蚀与膨胀操作[/color]
    • Finally we run the labelling feature.
    • All this is done in the alg_despeckle code. */ cnt->current_image->total_labels = 0; cnt->imgs.largest_label = 0; olddiffs = 0;

          if (cnt->conf.despeckle && cnt->current_image->diffs > 0) {
              olddiffs = cnt->current_image->diffs;
              cnt->current_image->diffs = alg_despeckle(cnt, olddiffs);
          } else if (cnt->imgs.labelsize_max) {
              cnt->imgs.labelsize_max = 0; /* Disable labeling if enabled */
          }    
      
      } else if (!cnt->conf.setup_mode) {
          cnt->current_image->diffs = 0;
      }

      5.智能灵敏度设置 / Manipulate smart_mask sensitivity (only every smartmask_ratio seconds) / if (cnt->smartmask_speed && (cnt->event_nr != cnt->prev_event)) { if (!--smartmask_count) { alg_tune_smartmask(cnt); smartmask_count = smartmask_ratio; } }

      /* cnt->moved is set by the tracking code when camera has been asked to move.
  • When camera is moving we do not want motion to detect motion or we will
  • get our camera chasing itself like crazy and we will get motion detected
  • which is not really motion. So we pretend there is no motion by setting
  • cnt->diffs = 0.
  • We also pretend to have a moving camera when we start Motion and when light
  • switch has been detected to allow camera to settle. */ if (cnt->moved) { cnt->moved--; cnt->current_image->diffs = 0; }

[/code]

可见主要是执行了alg_diff函数。 做完帧差后,再加入了开关灯切换、开关灯滤波、 噪点清除、smartMask(灵敏度设置)

算法主要在alg.c 以下是alg.h的接口函数。

[code]void alg_locate_center_size(struct images , int width, int height, struct coord ); void alg_draw_location(struct coord , struct images , int width, unsigned char , int); int alg_diff(struct context , unsigned char ); int alg_diff_standard(struct context , unsigned char ); int alg_lightswitch(struct context , int diffs); int alg_switchfilter(struct context , int, unsigned char ); void alg_noise_tune(struct context , unsigned char ); void alg_threshold_tune(struct context , int, int); int alg_despeckle(struct context , int); void alg_tune_smartmask(struct context ); void alg_update_reference_frame(struct context , int);[/code]

[code]int alg_diff(struct context cnt, unsigned char new) { int diffs = 0;

if (alg_diff_fast(cnt, cnt->conf.max_changes / 2, new))
    diffs = alg_diff_standard(cnt, new);

return diffs;

}[/code]

主要算法接口是alg_diff,alg_diff_fast是用于减少计算量的,当帧差统计信息小于一个值时,就不执行alg_diff_standard。

分析其实现代码可以发现:噪点消除、智能灵敏度算法的主要核心还是腐蚀与膨胀操作。

易百纳技术社区文件: motion-3.2.12.tar.gz
下载
我来回答
回答7个
时间排序
认可量排序

zk922

0个粉丝

4

问答

0

专栏

0

资料

zk922 2015-02-02 12:27:07
认可0
不过不支持 H264..蛋蛋的忧伤。

hanlin

0个粉丝

0

问答

0

专栏

0

资料

hanlin 2015-07-30 12:02:31
认可0
吾问无为谓

Bingo403

0个粉丝

1

问答

0

专栏

0

资料

Bingo403 2016-03-09 14:07:41
认可0
学习下还是不错的

H伟伯爵H

0个粉丝

0

问答

0

专栏

0

资料

H伟伯爵H 2016-12-01 17:25:33
认可0
mark学习学习学习学习学习:lol

Ethan_ZSC

0个粉丝

0

问答

0

专栏

0

资料

Ethan_ZSC 2016-12-07 09:58:57
认可0
看代码有点吃不消,继续努力

rupert

0个粉丝

1

问答

0

专栏

0

资料

rupert 2017-04-03 15:49:04
认可0

学习下还是不错的

钓鱼大师

0个粉丝

1

问答

0

专栏

0

资料

钓鱼大师 2017-06-03 14:05:33
认可0
做算法的都是牛人啊
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
相关问答
无更多相似问答 去提问
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区