opencv案例之物件計數 自適應閾值介紹

2021-10-02 12:36:52 字數 3585 閱讀 3514

農業領域經常需要計算物件個數或者在其他領域拍照自動計數,可以提高效率,降低成本

自適應閾值處理

在閾值處理操作中,僅通過設定固定閾值很難達到理想分割效果,我們需要從二值化的影象中分離目標區域和背景區域。實際上,目標和背景通常相互依存,我們可以從影象畫素領域塊的分布特徵來自適應確定區域的二值化閾值。opencv中有自適應的閾值化函式。

void

adaptivethreshold

(inputarray src,

outputarray dst,

double maxvalue,

int adaptivemethod,

int thresholdtype,

int bolcksize,

double c)

引數介紹

對引數4與引數7內容的解釋:

自適應閾值化計算大概過程是為每乙個象素點單獨計算的閾值,即每個畫素點的閾值都是不同的,就是將該畫素點周圍b*b區域內的畫素加權平均,然後減去乙個常數c,從而得到該點的閾值。b由引數6指定,常數c由引數7指定。

adaptive_thresh_mean_c,為區域性鄰域塊的平均值,該演算法是先求出塊中的均值,再減去常數c。

adaptive_thresh_gaussian_c,為區域性鄰域塊的高斯加權和。該演算法是在區域中(x, y)周圍的畫素根據高斯函式按照他們離中心點的距離進行加權計算,再減去常數c。

#include

#include

#include

#include

using

namespace std;

using

namespace cv;

#define pic_path "/work/opencv_pic/"

#define pic_name "case4.png"

intmain

(void

)namedwindow

("原圖顯示"

,window_normal)

;imshow

("原圖顯示"

,src)

;cvtcolor

(src,gray_src,color_bgr2gray)

;//影象二值化

mat binaryimg;

//thresh_******** thresh_otsu兩者都是自由確定閾值的巨集 對於直方圖只存在單峰的影象 thresh_******** 效果很好

//在這裡檢測圖可以看出屬於直方圖單峰的情況 顏色相對單一 顏色區分明顯

threshold

(gray_src,binaryimg,0,

255,thresh_binary | thresh_******** )

;imshow

("二值化影象"

,binaryimg)

;//圖形學操作 為後續檢測減少障礙 這裡採取膨脹 減小黑色區域 使得粘連情況稍微好一點

mat kernel =

getstructuringelement

(morph_rect,

size(3

,3),

point(-

1,-1

));dilate

(binaryimg,binaryimg,kernel,

point(-

1,-1

));//距離變換 每個元素都能解析出單峰,距離計算原理 計算影象距離0點最近的距離

//做位反 將背景處理為0 特徵區域處理為大的值

bitwise_not

(binaryimg,binaryimg,

mat())

;namedwindow

("位反處理影象"

,window_normal)

;imshow

("位反處理影象"

,binaryimg)

;//距離變換

distancetransform

(binaryimg,binaryimg,dist_l2,3)

;//歸一化

normalize

(binaryimg,binaryimg,0,

1.0,norm_minmax)

;namedwindow

("距離變換影象"

,window_normal)

;imshow

("距離變換影象"

,binaryimg)

;//對距離變化圖再進行閾值二值化處理 找出各個元素峰值

mat dst_8u;

binaryimg.

convertto

(dst_8u,cv_8uc1)

;adaptivethreshold

(dst_8u,dst_8u,

255,adaptive_thresh_gaussian_c,thresh_binary,

175,

0.0)

;namedwindow

("閾值自適應影象"

,window_normal)

;imshow

("閾值自適應影象"

,dst_8u)

;//由於前面做了bitwise_not 這裡進行一步腐蝕 減小白色區域 消除粘連

kernel =

getstructuringelement

(morph_rect,

size(3

,3),

point(-

1,-1

));erode

(dst_8u,dst_8u,kernel,

point(-

1,-1

),3)

;namedwindow

("進一步腐蝕影象"

,window_normal)

;imshow

("進一步腐蝕影象"

,dst_8u)

;//聯通區域計數

vector> contours;

findcontours

;//繪製輪廓

rng rng

(123456);

mat contourimg = mat::

zeros

(src.

size()

,cv_8uc3)

;for

(size_t i=

0;isize()

;i++

)namedwindow

("繪製輪廓"

,window_normal)

;imshow

("輪廓繪製"

,contourimg)

; cout <<

"一共有 "

<< contours.

size()

<<

" 個玉公尺粒"

);destroyallwindows()

;return0;

}

OpenCV自適應閾值處理

區域性自適應閾值則是根據畫素的鄰域塊的畫素值分布來確定該畫素位置上的二值化閾值。這樣做的好處在於每個畫素位置處的二值化閾值不是固定不變的,而是由其周圍鄰域畫素的分布來決定的。亮度較高的影象區域的二值化閾值通常會較高,而亮度較低的影象區域的二值化閾值則會相適應地變小。不同亮度 對比度 紋理的區域性影象...

opencv 學習之 閾值化 2 自適應閾值

自適應閾值化函式 void cvadaptivethreshold const cvarr src,cvarr dst,double max value,int adaptive method cv adaptive thresh mean c,int threshold type cv thres...

OpenCV 閾值處理 二 自適應閾值

因此在同一副影象上的不同區域採用的是不同的閾值,從而使我們能在亮度不同的情況下得到更好的結果。自適應閾值函式 dst cv.adaptivethreshold src,maxvalue,adaptivemethod,thresholdtype,blocksize,c dst 引數 src 8位單通道...