- 收藏
- 点赞
- 分享
- 举报
开源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。
分析其实现代码可以发现:噪点消除、智能灵敏度算法的主要核心还是腐蚀与膨胀操作。
Markdown 语法
- 加粗**内容**
- 斜体*内容*
- 删除线~~内容~~
- 引用> 引用内容
- 代码`代码`
- 代码块```编程语言↵代码```
- 链接[链接标题](url)
- 无序列表- 内容
- 有序列表1. 内容
- 缩进内容
- 图片![alt](url)
-
2015-02-09 09:51:13
-
2017-11-24 15:23:07
-
2014-12-26 22:08:26
-
2019-12-03 17:17:26
-
32014-04-04 21:58:27
-
2014-11-27 12:17:26
-
2016-11-18 16:01:38
-
2015-11-19 19:06:46
-
22013-11-19 19:14:27
-
2015-04-15 12:39:13
-
2012-12-05 11:23:34
-
2013-11-27 21:32:36
-
2013-12-02 16:51:53
-
582016-06-28 09:00:53
-
2014-04-30 12:33:54
-
2019-11-09 19:12:56
-
2012-12-05 14:30:17
-
2012-12-05 14:31:02
-
2012-12-05 14:31:34
-
5Hi3516CV610 如何使用SD卡升级固件
-
5cat /dev/logmpp 报错 <3>[ vi] [func]:vi_send_frame_node [line]:99 [info]:vi pic queue is full!
-
50如何获取vpss chn的图像修改后发送至vo
-
5FPGA通过Bt1120传YUV422数据过来,vi接收不到数据——3516dv500
-
50SS928 运行PQtools 拼接 推到设备里有一半画面会异常
-
53536AV100的sample_vdec输出到CVBS显示
-
10海思板子mpp怎么在vi阶段改变视频数据尺寸
-
10HI3559AV100 多摄像头同步模式
-
9海思ss928单路摄像头vio中加入opencv处理并显示
-
10EB-RV1126-BC-191板子运行自己编码的程序
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明