日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

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

發(fā)布時間:2023/12/9 c/c++ 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【机器视觉学习笔记】大津法/Otsu最大类间方差法 最佳阈值处理(C++) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

  • 概念
  • C++源碼
    • OtsuThreshold
    • 主函數(shù)
  • 效果
  • 完整源碼

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


本文所用源碼修改自C++ opencv 圖片二值化最佳閾值確定(大津法,OTSU算法)——Sharon Liu

概念

????????Otsu算法,也叫最大類間方差法,是1979年由日本學(xué)者大津提出的(所以也叫大津法),是一種自適應(yīng)閾值確定的方法,一種全局的二值化算法。
????????它是根據(jù)圖像的灰度特性,將圖像分為前景背景兩個部分。 當(dāng)取最佳閾值時,兩部分之間的差別應(yīng)該是最大的。在Otsu算法中所采用的衡量差別的標準就是較為常見的最大類間方差。前景和背景之間的類間方差如果越大,就說明構(gòu)成圖像的兩個部分之間的差別越大。
????????當(dāng)部分目標被錯分為背景或部分背景被錯分為目標,都會導(dǎo)致兩部分差別變小。
????????當(dāng)所取閾值的分割使類間方差最大時,就意味著錯分概率最小。

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; } //———————————————— //版權(quán)聲明:本文為CSDN博主「Sharon Liu」的原創(chuàng)文章,遵循CC 4.0 BY - SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。 //原文鏈接:https ://blog.csdn.net/sylsjane/article/details/80872744

主函數(shù)

圖片路徑根據(jù)實際情況調(diào)整,注意反斜杠是轉(zhuǎn)義字符的開頭,故“\”應(yīng)替換為“\\”

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算法結(jié)果,與上圖一致

完整源碼

#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; } //———————————————— //版權(quán)聲明:本文為CSDN博主「Sharon Liu」的原創(chuàng)文章,遵循CC 4.0 BY - SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。 //原文鏈接:https ://blog.csdn.net/sylsjane/article/details/80872744int 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; }

總結(jié)

以上是生活随笔為你收集整理的【机器视觉学习笔记】大津法/Otsu最大类间方差法 最佳阈值处理(C++)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。