視頻移動偵測區域報警的原理、實現與應用

    做者 原野之狼 日期 2012-7-26 11:43:00
視頻移動偵測區域報警的原理、實現與應用   簡介   ====== 此項目用於前端攝像頭的視頻移動偵測報警。 以前已經發布了一個版本,功能比較簡單,如今在之前版本的基礎上增長了區域報警的功能。 所謂區域報警,就是在攝像頭的視角範圍定義出一些區域,當此區域的出現非法入侵的時候就產生報警。 經過這種方式能夠有效的對重點區域進行監控而忽略其它的一些非重點區域。   功能要求   ============ - 以矩形區域來表徵目標 - 支持多區域報警 - 支持多級別報警   原理與實現   ===============         移動偵測         ============ 經過分析目標區域的圖片灰度值的變化來判斷。 繼承初版本的算法(詳情參考相關文檔),採用二次差分的方式來對目標區域進行檢測。 首先,在不考慮分區域報警的情形下,分析一下其算法實現。具體步驟以下: 1. 採集第一幀圖片,計算出灰度值,並保存該灰度值。 2. 採集第二幀圖片,計算出灰度值,並與前一次保存的灰度值進行比較,計算出灰度變化方向,並保存該變化方向,其包含三種情形:  - 灰度不變  - 灰度變大  - 灰度變小 用本次計算出來的灰度值覆蓋上一次計算出的灰度值。 3. 採集第三幀圖片, 計算出灰度值,並與前一次保存的灰度值進行比較,計算出灰度變化方向,並結合前一次的灰度變化方向來作判斷,   若本次的灰度變化方向與前一次的灰度變化方向相異,則代表目標區域出現了變化,應該產生報警。即:  - 本次灰度變小,前一次灰度變大,產生報警。  - 本次灰度變大,前一次灰度變小,產生報警。  - 本次灰度不變,不動做。  - 前一次灰度不變,不動做。 用本次計算出來的灰度值覆蓋上一次計算出的灰度值。 用本次計算出來的灰度變化方向覆蓋上一次計算出來的灰度變化方向。 4. 繼續採集圖片,並以上一步的算法來分析。此時進入穩定的循環檢測期。         區域報警         ============ 使用區域報警,其原理和上述小節描述的是徹底同樣的, 只是爲了支持區域報警,程序中使用了特定的數據結構來描述這個加強功能。 - 灰度數組 使用數組 last_y[] 來存儲上一幀jpeg圖片的各個block的灰度值。 數組長度爲 (IMG_WIDTH_MAX / JPEG_BLOCK_DIM) * (IMG_HEIGHT_MAX / JPEG_BLOCK_DIM) 當前幀的灰度值存儲在 crt_y[]數組中。 - 灰度變化方向數組 使用二維數組 last_y_direction[][] 存儲上一幀jpeg圖片的灰度變化方向。 定義了三個宏來標示:  - #define BLK_Y_NO_CHANGE 0  - #define BLK_Y_INCREASED 1  - #define BLK_Y_DECREASED 2 數組的第一維長度是 ALARM_SENSITY_LEVEL_MAX, 因爲須要支持多級別報警,因此須要記錄每個級別的灰度變化方向。 數組的第二維長度是 (IMG_WIDTH_MAX / JPEG_BLOCK_DIM) * (IMG_HEIGHT_MAX / JPEG_BLOCK_DIM) / 4, 爲了節約內存資源,每一個字節存儲了4組變化方向。 - 報警數組 使用數組 alarm_tbl[] 存儲目前的報警狀態,爲了節約內存資源,每一位表明一個block。 - 已註冊報警區域 使用數組 alarm_zone_tbl[] 來存儲已註冊的報警區域,最大報警區域數可配置。 - 程序流程 程序流程和以前的描述是一致的,整體比較簡單,看代碼便可,不在贅述。         灰度計算         ============ 使用第三方代碼,具體原理超出本文檔的範圍。   應用步驟   ============ 1. 初始化系統。若是在主程序的啓動代碼裏有對全局變量進行清零操做,則這一步能夠省略。   reset_motion_detect(); 2. 設置視頻分辨率。參數不要超過範圍,不然會返回錯誤。每次改變攝像頭的分辨率以後都須要調用此函數從新初始化系統。   set_img_dim(640, 480); 3. 註冊報警區域。   參數1:矩形區域的座標採用比例數來設置,所以當攝像頭的分辨率改變以後不會影響系統的工做。   矩形結構體的各個元素的取值範圍是[0 ~ 999] ,表明[0.000 ~ 0.999] , 注意是閉區間。   參數2:ID號不能重複。   參數3:報警級別使用頭文件定義的宏來表示,不要採用數字。   Rect alarm_zone = {400, 600, 400, 600};  /* 中間區域 */      if (!add_alarm_zone(&alarm_zone, 1, ALARM_SENSITY_LV3)) {       /* 添加報警區域成功 */   } else {       /* 出錯了! */   }   能夠添加多個報警區域,區域座標能夠交叉重疊。 4. 開始移動偵測。   Image img;   AlarmInfoArray alarm_info;   int alarm_count;   int i;      img.pbuf = jpeg_buf;   img.len = jpeg_len;      if (!motion_detect(&img, &alarm_info, &alarm_count)) {       for (i = 0; i < alarm_count; i++) {           /*            業務邏輯在這裏處理            printf("Alarm->  id:%d, level:%d, zone%d, %d) (%d, %d) \n",               (int)alarm_info.id, (int)alarm_info.alarm_level,               (int)alarm_info.zone.left, (int)alarm_info.zone.top,               (int)alarm_info.zone.right, (int)alarm_info.zone.bottom);           */       }   } else {       /* 出錯或者未就緒 */   }   以上代碼須要以必定的間隔(好比0.5秒)循環調用,圖片幀存在jpeg_buf裏,幀長度存在jpeg_len裏。 5. 移除報警區域。   移除以上註冊的ID號爲1的報警區域。   if (!rm_alarm_zone(1)) {       /* 成功移除 */;   } else {       /* 出錯 */   } 6. 更改配置信息 - ALARM_ZONE_MAX  用於定義總的報警區域數,能夠根據須要配置。 /* How many zones which are being monitored */ #define ALARM_ZONE_MAX 20 - ALARM_SENSITY_LEVEL_MAX  用於定義報警級別數,最大限制在5。 /* Don't be great than 5 */ #define ALARM_SENSITY_LEVEL_MAX 5 - ALARM_SENSITY_START_VAL  用於定義報警的門檻值,小於該值系統認爲沒有變化。 /* The start threshold */ #define ALARM_SENSITY_START_VAL 5 - ALARM_SENSITY_STEP_VAL  用於定義報警級別的步進值。 /* The stepping value of each sensity level */  #define ALARM_SENSITY_STEP_VAL 10   聯繫我   ========= Author: Hugui E-Mail: y_y_z_l  AT  163.com Date:   2012.7.6  
相關文章
相關標籤/搜索