IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 【机器视觉学习笔记】大津法/Otsu最大类间方差法 最佳阈值处理(C++) -> 正文阅读

[人工智能]【机器视觉学习笔记】大津法/Otsu最大类间方差法 最佳阈值处理(C++)

平台:Windows 10 20H2
Visual Studio 2015
OpenCV 4.5.3


本文所用源码修改自C++ opencv 图片二值化最佳阈值确定(大津法,OTSU算法)——Sharon Liu

概念

????????Otsu算法,也叫最大类间方差法,是1979年由日本学者大津提 出的(所以也叫大津法),是一种自适应阈值确定的方法,是一种全局的二值化算法。
????????它是根据图像的灰度特性,将图像分为前景背景两个部分。 当取最佳阈值时,两部分之间的差别应该是最大的。在Otsu算法中所采用的衡量差别的标准就是较为常见的最大类间方差。前景和背景之间的类间方差如果越大,就说明构成图像的两个部分之间的差别越大。
????????当部分目标被错分为背景或部分背景被错分为目标,都会导致两部分差别变小。
????????当所取阈值的分割使类间方差最大时,就意味着错分概率最小。
在这里插入图片描述

C++源码

OtsuThreshold

/******************************************************************************************
Function:       OtsuThreshold
Description:	图片二值化最佳阈值确定(大津法,OTSU算法)
Input:          src:原图片
Return:         阈值
******************************************************************************************/
int OtsuThreshold(Mat src)
{
	int threshold;

	try
	{
		int height = src.rows;
		int width = src.cols;

		//histogram  
		float histogram[256] = { 0 };
		for (int i = 0; i < height; i++) 
		{
			unsigned char* p = (unsigned char*)src.data + src.step*i;
			for (int j = 0; j < width; j++) 
			{
				histogram[*p++]++;
			}
		}
		//normalize histogram  
		int size = height*width;
		for (int i = 0; i < 256; i++) 
		{
			histogram[i] = histogram[i] / size;
		}

		//average pixel value  
		float avgValue = 0;
		for (int i = 0; i < 256; i++) 
		{
			avgValue += i*histogram[i];
		}

		float maxVariance = 0;
		float w = 0, u = 0;
		for (int i = 0; i < 256; i++) 
		{
			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;
}
//————————————————
//版权声明:本文为CSDN博主「Sharon Liu」的原创文章,遵循CC 4.0 BY - SA版权协议,转载请附上原文出处链接及本声明。
//原文链接:https ://blog.csdn.net/sylsjane/article/details/80872744

主函数

图片路径根据实际情况调整,注意反斜杠是转义字符的开头,故“\”应替换为“\\”

int main(int argc, char * argv[])
{
	Mat Image = imread("D:\\Work\\OpenCV\\Workplace\\Test_1\\1.jpg", 0);

	int thresholdValue = OtsuThreshold(Image);
	cout << "类间方差为: " << thresholdValue << endl;

	Mat imageOutput;
	threshold(Image, imageOutput, thresholdValue, 255, CV_THRESH_BINARY);

	Mat imageOtsu;
	threshold(Image, imageOtsu, 0, 255, CV_THRESH_OTSU); //Opencv Otsu算法

	imshow("原图", Image);
	imshow("Output Image", imageOutput);
	imshow("Opencv Otsu", imageOtsu);

	waitKey(0);

	return 0;
}

效果

原图
在这里插入图片描述
效果
在这里插入图片描述
OpenCv自带的Otsu算法结果,与上图一致
在这里插入图片描述

完整源码

#include <opencv2\opencv.hpp>
#include <iostream>
#include <opencv2\imgproc\types_c.h>

using namespace cv;
using namespace std;


/******************************************************************************************
Function:       OtsuThreshold
Description:	图片二值化最佳阈值确定(大津法,OTSU算法)
Input:          src:原图片
Return:         阈值
******************************************************************************************/
int OtsuThreshold(Mat src)
{
	int threshold;

	try
	{
		int height = src.rows;
		int width = src.cols;

		//histogram  
		float histogram[256] = { 0 };
		for (int i = 0; i < height; i++) 
		{
			unsigned char* p = (unsigned char*)src.data + src.step*i;
			for (int j = 0; j < width; j++) 
			{
				histogram[*p++]++;
			}
		}
		//normalize histogram  
		int size = height*width;
		for (int i = 0; i < 256; i++) 
		{
			histogram[i] = histogram[i] / size;
		}

		//average pixel value  
		float avgValue = 0;
		for (int i = 0; i < 256; i++) 
		{
			avgValue += i*histogram[i];
		}

		float maxVariance = 0;
		float w = 0, u = 0;
		for (int i = 0; i < 256; i++) 
		{
			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;
}
//————————————————
//版权声明:本文为CSDN博主「Sharon Liu」的原创文章,遵循CC 4.0 BY - SA版权协议,转载请附上原文出处链接及本声明。
//原文链接:https ://blog.csdn.net/sylsjane/article/details/80872744

int main(int argc, char * argv[])
{
	Mat Image = imread("D:\\Work\\OpenCV\\Workplace\\Test_1\\1.jpg", 0);

	int thresholdValue = OtsuThreshold(Image);
	cout << "类间方差为: " << thresholdValue << endl;

	Mat imageOutput;
	threshold(Image, imageOutput, thresholdValue, 255, CV_THRESH_BINARY);

	Mat imageOtsu;
	threshold(Image, imageOtsu, 0, 255, CV_THRESH_OTSU); //Opencv Otsu算法

	imshow("原图", Image);
	imshow("Output Image", imageOutput);
	imshow("Opencv Otsu", imageOtsu);

	waitKey(0);

	return 0;
}
  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-09-23 11:28:02  更:2021-09-23 11:28:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 23:21:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码