(大津法或最大類間方差法)使用的是聚類的思想,把影象的灰度數按灰度級分成2個部分,使得兩個部分之間的灰度值差異最大,每個部分之間的灰度差異最小,通過方差的計算來尋找乙個合適的灰度級別來劃分。 所以可以在二值化的時候採用otsu演算法來自動選取閾值進行二值化。otsu演算法被認為是影象分割中閾值選取的最佳演算法,計算簡單,不受影象亮度和對比度的影響。因此,使類間方差最大的分割意味著錯分概率最小。
設t為設定的閾值。
w0分開後前景畫素點數占影象的比例
u0分開後前景畫素點的平均灰度
w1分開後背景畫素點數占影象的比例
u1分開後背景畫素點的平均灰度
影象總平均灰度為: u = w0∗u0 + w1∗u1
從l個灰度級遍歷 t,使得 t 為某個值的時候,前景和背景的方差最大,則 這個 t 值便是我們要求得的閾值。其中,方差的計算公式如下:
g = wo∗(u0−u)∗(u0−u) + w1∗(u1−u)∗(u1−u)
此公式計算量較大,可以採用:
g = w0∗w1∗(u0−u1)∗(u0−u1)
由於otsu演算法是對影象的灰度級進行聚類,因此在執行otsu演算法之前,需要計算該影象的灰度直方圖。
二. **
#include
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include
#include
#include
using namespace cv;
using namespace std;
mat src,dst;
int otsu(mat &src);
int main(int argc, char ** argv)
int otsu(mat &src)
;for (int m = 0; m < src.rows; m++)
}int threshold;
long sum0 = 0, sum1 = 0;
long cnt0, cnt1 = 0;
double w0 = 0, w1 = 0;
double u0 = 0, u1 = 0;
double variance = 0;
int i, j;
double u = 0;
double maxvariance = 0;
for (i = 0; i < 256; i++)
u0 = (double)sum0 / cnt0;
w0 = (double)cnt0 / size;
for (j = i; j <= 255; j++)
u1 = (double)sum1 / cnt1;
w1 = 1 - w0;
u = u0 * w0 + u1 * w1;
variance = w0 * w1 * (u0 - u1) * (u0 - u1);
if (variance > maxvariance)
}return threshold;
}
用OpenCV實現Otsu演算法
最近在學習影象分割反面的知識,在岡薩雷斯的那本書上看到otsu演算法,身邊的同學都是用matlab來實現這個演算法。我覺得matlab寫得話,但是 的效率應該不會高。於是又惡補了一些opencv的一些基本知識,然後看了augusdi的部落格,分析了一下他的 並附上,第二份 是來自某一位大牛的 寫得更...
OTSU演算法介紹及openCV的C 實現
otsu演算法也稱最大類間差法,有時也稱之為大津演算法。前景與背景影象的類間方差最大。因方差是灰度分布均勻性的一種度量,背景和前景之間的類間方差越大,說明構成影象的兩部分的差別越大,當部分前景錯分為背景或部分背景錯分為前景都會導致兩部分差別變小。因此,使類間方差最大的分割意味著錯分概率最小。ostu...
C 實現otsu演算法
類間方差最大化閾值分割演算法 otsu 可以自動計算影象二值化時的閾值,otsu的中心思想是閾值t應使目標與背景兩類的類間方差最大。具體原理如下 otsu是按影象的灰度特性,將影象分成背景和目標兩部分。背景和目標之間的類間方差越大,說明構成影象的兩部分的差別越大,當部分目標錯分為背景或部分背景錯分為...