OTSU 获取最佳阈值,及opencv二值化
生活随笔
收集整理的這篇文章主要介紹了
OTSU 获取最佳阈值,及opencv二值化
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
OTSU 算法求最佳閾值,及opencv 二值化
- 前言
- 一、OTSU 算法求最佳閾值
- 二、使用獲取的最佳閾值進行二值化
- 三、效果
前言
OTSU算法,也就是大津算法,屬于自適應的閾值確定方法,用該閾值進行的圖像固定閾值二值化,類間方差最大,它是按圖像的灰度特性,將圖像分成背景和前景兩部分,使類間方差最大的分割意味著錯分概率最小。其核心思路是尋找一個閾值T,把圖像的所有像素點分成兩類,一類的像素值均小于等于T(背景區域),另一類的像素值均大于T(前景區域),當這兩類的類間方差取得最大值時,則認為該T值為最合適的閾值。假設所有像素點的總和是Sum,背景區域所有像素點數為N1,其占圖像總像素數的比例為w1,平均像素值為μ1;前景區域所有像素點數為N2,其占圖像總像素數的比例為w2,平均像素值為μ2;μ 為0-255 的平均像素,那么有以下關系式:
提示:以下是本篇文章正文內容,下面案例可供參考
一、OTSU 算法求最佳閾值
有著上面的算法公式我們就可以很容易的把代碼寫出來了,下面是代碼,如果不需要用QImage的話可以直接使用Mat,選喲 轉換代碼的可以去轉換代碼
int ImageHandle::GetOptimalThreshold(QImage &image)//OTSU (大津法) {//首先先把QImage 轉為三通道并轉換為Matimage = image.convertToFormat(QImage::Format_RGB888);cv::Mat src = this->QImage2Mat(image);//灰度處理,轉成單通道cv::cvtColor(src,src,cv::COLOR_BGR2GRAY);//圖片的寬,高int nRows = src.rows;int nCols = src.cols;int threshold = 0; //最佳閾值double temp = 0.0; //獲取double AvePix[256];int TotalPix[256];double nProDis[256];double nSumProDis[256];//變量初始化for (int i = 0; i < 256; i++){AvePix[i] = 0.0;TotalPix[i] = 0;nProDis[i] = 0.0;nSumProDis[i] = 0.0;}//計算0-255 每個像素值的像素點for (int i = 0; i < nRows; i++){for (int j = 0; j < nCols; j++){TotalPix[(int)src.at<uchar>(i, j)]++;}}//計算每個像素值的像素點 占 總像素點的比例for (int i = 0; i < 256; i++){nProDis[i] = (double)TotalPix[i] / (nRows*nCols);}AvePix[0] = 0;nSumProDis[0] = nProDis[0];//計算背景區域的像素比例 與 像素平均值for (int i = 1; i < 256; i++){nSumProDis[i] = nSumProDis[i - 1] + nProDis[i];AvePix[i] = AvePix[i - 1] + i*nProDis[i];}double mean = AvePix[255];//遍歷像素值 找到類間方差最大的像數值即為最佳閾值for (int i = 1; i < 256; i++){double Pback = nSumProDis[i];double Pfront = 1 - nSumProDis[i];double g= 0.0;if (fabs(Pback ) > 0.000001 && fabs(Pfront ) > 0.000001){double Mback = AvePix[i];double Mfront = (mean - Pback *Mback)/Pfront ;g= (double)(Pback * Pfront * pow((Mback - Mfront), 2)); //大津算法 即(背景像素占總像素的比例 * 前景像素占總像素的比例 * (背景平均像素 - 前景平均像素)的平方)if (g> temp){temp = g;threshold = i;}}}return threshold; }二、使用獲取的最佳閾值進行二值化
QImage ImageHandle::Binarization(QImage &image,int threshold) {image = image.convertToFormat(QImage::Format_RGB888);cv::Mat src = this->QImage2Mat(image);cv::cvtColor(src,src,cv::COLOR_BGR2GRAY);cv::Mat dst;cv::threshold(src,dst,threshold,255,CV_THRESH_BINARY);return this->Mat2QImage(dst); }int main() {QApplication a(argc, argv);QImage temp;temp = QImage("temp.png");ImageHandle f;int i = f.GetOptimalThreshold(temp);temp = f.Binarization(temp,i);QLabel *m_label = new QLabel();m_label->resize(1280,1024);QPixmap I_map = QPixmap::fromImage(temp);I_map = I_map.scaled(m_label->width(),m_label->height(), Qt::KeepAspectRatio, Qt::SmoothTransformation);m_label->setPixmap(I_map);m_label->show();return a.exec();}三、效果
1、二值化前
2、二值化后
總結
以上是生活随笔為你收集整理的OTSU 获取最佳阈值,及opencv二值化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 采购信息记录相关表
- 下一篇: opencv二值化详解