目錄
- 概念
- C++原始碼
- OtsuThreshold
- 主函式
- 效果
- 完整原始碼
平臺: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;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/302594.html
標籤:其他
上一篇:2021CVPR多目標檢測:Multiple Object Tracking with Correlation Learning
