公式
g=w0 (u0-u)^2+w1 (u1-u) ^2+ w2*(u2-u) ^2
g最大值时,就可以选出两个阈值
求两个阈值
利用这两个阈值分割图像
主函数调用
Otsu算法:最大类间方差法(大津算法),是一种确定阈值的算法。
之所以称为最大类间方差法是因为,用该阈值进行的图像固定阈值二值化,类间方差最大,它是按图像的灰度特性,将图像分成背景和前景两部分,使类间方差最大的分割意味着错分概率最小。
算法评价:
优点:算法简单,当目标与背景的面积相差不大时,能够有效地对图像进行分割。
缺点:当图像中的目标与背景的面积相差很大时,表现为直方图没有明显的双峰,或者两个峰的大小相差很大,分割效果不佳,或者目标与背景的灰度有较大的重叠时也不能准确的将目标与背景分开。
//opencv
#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
/******************************************************************************************
Function: OtsuThreshold
Description: 图片二值化最佳阈值确定(大津法,OTSU算法)
Input: src:原图片
Return: 阈值
******************************************************************************************/
int OtsuThreshold(IplImage* src)
{
int threshold
try
{
int height = src->height
int width = src->width
//histogram
float histogram[256] = { 0 }
for (int i = 0i <heighti++) {
unsigned char* p = (unsigned char*)src->imageData + src->widthStep*i
for (int j = 0j <widthj++) {
histogram[*p++]++
}
}
//normalize histogram
int size = height*width
for (int i = 0i <256i++) {
histogram[i] = histogram[i] / size
}
//average pixel value
float avgValue = 0
for (int i = 0i <256i++) {
avgValue += i*histogram[i]
}
float maxVariance = 0
float w = 0, u = 0
for (int i = 0i <256i++) {
w += histogram[i]
u += i*histogram[i]
float t = avgValue*w - u
float variance = t*t / (w*(1 - w))
if (variance >maxVariance) {
maxVariance = variance
threshold = i
}
}
}
catch (cv::Exception e)
{
}
return threshold
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)