基於OpenCV的火焰檢測(二) RGB顏色判據

2022-09-18 11:09:30 字數 3076 閱讀 2161

上文跟大家分享了在做火焰檢測中常用到的影象預處理方法,從這一篇博文開始,我將向大家介紹如何一步一步地檢測出火焰區域。火焰提取要用

到很多判據,今天我要向大家介紹的是最簡單的但是很有效的判據——rgb判據。

在介紹這個判據之前,博主首先給大家簡單介紹一下rgb模型。根據三基色原理,用基色光單位來表示光的量,則在rgb顏色空間,任意色光f都可

以用r、g、b三色不同分量的相加混合而成:

f=r[r]+g[g]+b[b]

當三基色分量都為0(最弱)時混合為黑色光;當三基色分量都為k(最強)時混合為白。改變了f的座標值,也即改變了f的色值。

人眼的視網膜上有兩類感光器:錐狀體和桿狀體。錐狀體主要位於視網膜的中間部分,稱之為**凹,且對顏色高度敏感,稱為白晝視覺或亮視覺;

桿狀體分布面積較大,用來給出視野內的一般的總體影象,沒有彩色感覺,而對低照明度敏感,稱為微光視覺或暗視覺。由於錐狀體對紅、綠、藍三種

對於普通的火焰來說,它的紅色分量和綠色分量會很大,並且綠色分量會大於藍色分量,所以我們設下的簡單判據是:

r > r_**g and

g > g_**g and

r > g > b

其中,r_**g為紅色分量的均值。

在opencv1.0中實現很簡單,下面先擺出**:

int cvbgr_chk(iplimage*img_bgr, iplimage*bgr_chk)

if (img_bgr->nchannels != 3 || bgr_chk->nchannels != 1)

cvscalar **g;

**g = cv**g(img_bgr);

cvsize size = cvgetsize(img_bgr);

iplimage*r = cvcreateimage(size, 8, 1);

iplimage*g = cvcreateimage(size, 8, 1);

iplimage*b = cvcreateimage(size, 8, 1);

iplimage*tmp1 = cvcreateimage(size, 8, 1);

iplimage*tmp2 = cvcreateimage(size, 8, 1);

cvsplit(img_bgr, b, g, r, null);

cvcmps(r, **g.val[2], tmp1, cv_cmp_gt);

cvcmps(g, **g.val[1], tmp2, cv_cmp_gt);

cvmul(tmp1, tmp2, tmp1);

cvcmp(r, g, tmp2, cv_cmp_gt);

cvcmp(g, b, g, cv_cmp_gt);

cvmul(tmp2, g, tmp2);

cvmul(tmp1, tmp2, tmp1);

cvconvertscale(tmp1, bgr_chk, 1.0 / 255);

cvreleaseimage(&r);

cvreleaseimage(&g);

cvreleaseimage(&b);

cvreleaseimage(&tmp1);

cvreleaseimage(&tmp2);

return 0;

}

函式cvbgr_chk的功能是實現影象的rgb檢測,把符合rgb判據的素點置為1,否則置為0,返回的是只有0和1的二值化模板。
對於寫**的習慣,博主在這裡說一下閒話。有些人可能覺得上面函式的格式有點奇怪,特別是返回值,有什麼卵用?我的c++老師曾經說過,在做

專案的時候,較為複雜的函式一般不要把返回值作為輸出結果。什麼意思呢?眾所周知,函式返回值只有乙個,若想返回兩個值或者更多個,用這種

方法就行不通了。對於返回兩個或更多個值的函式,在c語言中在輸入變數後面,這樣就可以輕輕鬆鬆地輸出兩個值。那麼返回值不就可以寫出void

型的嗎?我們的確可以使用void,但是你們想一下,在乙個大專案中,往往不止乙個函式,那如果執行起來報錯了,那麼應該怎麼找錯呢?用斷點找?

定位到具體函式要花一定的時間;用編譯器自帶的檢錯工具?往往輸出並沒有什麼卵用的資訊。如果我們在每個函式裡面設定乙個對輸入輸出變數的異

常情況進行自動報錯的功能,就會大大簡化查錯的程式。比如說,在上面的函式中,把檢錯語句遮蔽掉,我分配給輸出變數的記憶體有三個通道,那麼函

數執行肯定會報錯,那麼我們可不可以簡簡單單地從系統報錯的資訊中解決問題呢?首先,我們先執行一把,看看報錯資訊是啥。

unhandled exception at 0x75d3d3cf in firedectect.exe: microsoft c++ exception: cv::exception at memory location 0x0023f3a8.

有誰可以看出是**出了問題嗎?反正我不能。再點一下「中斷」按鈕有木有好的提示?

……什麼鬼?

所以說,返回簡單的錯誤資訊很重要吧。如果取消遮蔽,那麼就會輸出:

func cvbgr_chk error:

img_bgr->nchannels != 3 || bgr_chk->nchannels != 1

那我們可以很快解決木有?

所以,博主做專案的時候都會採用這種習慣來寫函式,這樣會大大節省查詢低階錯誤的時間。

更多的檢測就不在這裡重複了,或者有些情況效果不是很好,但要記住,這只是眾多判據的其中乙個,我們可以兩三個判據結合來更精確地提

取區域,這就是以後要分享的東西了。

那麼我們下次見~

下文預告:基於opencv的火焰檢測(三)——hsi顏色判據

基於OpenCV的火焰檢測(三) HSI顏色判據

上文向大家介紹了如何用最簡單的rgb判據來初步提取火焰區域,現在我要給大家分享的是一種更加直觀的判據 hsi判據。為什麼說hsi判據是更加直觀的判據呢?老規矩,先介紹一下hsi色彩模型 hsi顏色模型用h s i三引數描述顏色特性,其中 h表示顏色的色調,它表示人的感官對不同顏色的感受,如紅色 綠色...

樹莓派系列五 openCV之火焰檢測(一)

前言 根據 an early fire detection method based on image processing the author is thou ho chao ho chen,ping hsueh wu,and yung chuen chiou 中原理實現火焰檢測。主要結合rgb...

基於Python的OpenCV人臉檢測

注意 本文只是人臉檢測,人臉識別的實現請參見本人另一篇部落格 基於opencv tensorflow keras實現人臉識別 提前做的準備 1 和說明 import cv2 as cv import numpy as np defface detect demo 人臉檢測函式 gray cv.cvt...