ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

OTSU算法(大津法—最大类间方差法)原理及实现

2022-02-03 21:30:38  阅读:276  来源: 互联网

标签:大津法 类间 int double 方差 Grayscale Mi OTSU


OTSU算法(大津法—最大类间方差法)原理及实现

背景

大津法(OTSU)是一种确定图像二值化分割阈值的算法,由日本学者大津于1979年提出。从大津法的原理上来讲,该方法又称作最大类间方差法,因为按照大津法求得的阈值进行图像二值化分割后,前景与背景图像的类间方差最大。

方差:

在这里插入图片描述
它是按图像的灰度特性,将图像分成背景和前景两部分。因方差是灰度分布均匀性的一种度量,背景和前景之间的类间方差越大,说明构成图像的两部分的差别越大,当部分前景错分为背景或部分背景错分为前景都会导致两部分差别变小。

优点:

计算简单,方便,不受图像的亮度的影响,在简单双峰场景中能进行快速分割

缺点:

噪声的干扰大,当图像没有典型的双峰时,不能够精确分割,对于多峰图像则失去效果。

应用:

医学影像分割,目标识别等,常和其它算法结合使用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

基本原理:

OPENCV实现:

#include<opencv2/opencv.hpp>
#include<vector>
#include<iostream>


using namespace std;
using namespace cv;


void otsu(Mat input,Mat&output,int&thres)
{
	const int Grayscale = 256;
	int width = input.cols;
	int height = input.rows;

	double Graystatistics[Grayscale] = { 0 };


	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width;j++)
		{
			int Grayvalue = input.at<uchar>(i, j);
			Graystatistics[Grayvalue]++;//直方图统计

		}
	}

	double allnum = width * height;
	double Pi[Grayscale] = { 0 };//单个个灰度的概率
	double P[Grayscale] = { 0 };//累计灰度概率
	double Mi[Grayscale] = { 0 };//累计灰度平均和

    double Psum = 0;
	double cumgray = 0;
	for (int i = 0; i < Grayscale; i++)
	{
		Pi[i] = Graystatistics[i] / allnum;
		P[i] = Pi[i] + Psum;
		Psum = P[i];
		Mi[i] = cumgray + (double)i * Pi[i];
		cumgray = Mi[i];
	}

	//计算类间方差
	double var = 0;
	thres = 0;
	for (int i = 0; i < Grayscale; i++)
	{
		double fenzi = (Mi[Grayscale - 1] * P[i] - Mi[i]) * (Mi[Grayscale - 1] * P[i] - Mi[i]);
		double fenmu = P[i] * (1 - P[i]);
		double vau = fenzi / fenmu;
		if (vau > var)
		{
			var = vau;
			thres = i;
		}

	}
	cout << thres << endl;
	
	input.copyTo(output);


	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			int value = output.at<uchar>(i, j);
			if (value >thres)
			{
				output.at<uchar>(i, j) = 255;
			}
			else
			{
				output.at<uchar>(i, j) = 0;
			}
		}
	}
	

}



int main()
{
	Mat a = imread("1.bmp");
	cvtColor(a, a, COLOR_RGB2GRAY);
	Mat b;
	int th = 0;
	otsu(a, b, th);

	int Otsu1 = cv::threshold(a, b, 0, 255, THRESH_OTSU +THRESH_BINARY);
	cout << Otsu1 << endl;
	imshow("1", b);
	return 0;
}

opencv接口:

double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type)

效果:

在这里插入图片描述在这里插入图片描述

标签:大津法,类间,int,double,方差,Grayscale,Mi,OTSU
来源: https://blog.csdn.net/qq_44733143/article/details/122778818

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有