生活随笔
收集整理的這篇文章主要介紹了
opencv大津算法二值化
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
二值化的前提是灰度化,手動二值化需要不斷進行調(diào)整,找到合適的閾值,大于閾值為白色。
大津二值化又叫最大類間方差法,可以自動確定二值化的閾值。基本思想是遍歷閾值,當(dāng)某個閾值下分割的兩類像素點之間灰度方差最大的時候,就是最優(yōu)的閾值。(因為類間方差越大,兩類的差別越大,不管是前景錯分到背景還是背景錯分到前景都會使類間方差變小)。數(shù)學(xué)推導(dǎo)如下:
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>cv
::Mat
BGR2GRAY(cv
::Mat img
) {int width
= img
.cols
;int height
= img
.rows
;cv
::Mat out
= cv
::Mat
::zeros(height
, width
, CV_8UC1
);for (int y
= 0; y
< height
; y
++) {for (int x
= 0; x
< width
; x
++) {out
.at
<uchar
>(y
, x
) = 0.2126 *img
.at
<cv
::Vec3b
>(y
, x
)[2] \
+ 0.7152 * img
.at
<cv
::Vec3b
>(y
, x
)[1] \
+ 0.0722 * img
.at
<cv
::Vec3b
>(y
, x
)[0];}}return out
;
}cv
::Mat
Binarize_Otsu(cv
::Mat gray
) {int width
= gray
.cols
;int height
= gray
.rows
;double w0
= 0, w1
= 0;double m0
= 0, m1
= 0;double max_sb
= 0, sb
= 0;int th
= 0;int val
;for (int t
= 0; t
< 255; t
++) {w0
= 0;w1
= 0;m0
= 0;m1
= 0;for (int y
= 0; y
< height
; y
++) {for (int x
= 0; x
< width
; x
++) {val
= (int)(gray
.at
<uchar
>(y
, x
));if (val
< t
) {w0
++;m0
+= val
;}else {w1
++;m1
+= val
;}}}m0
/= w0
;m1
/= w1
;w0
/= (height
* width
);w1
/= (height
* width
);sb
= w0
* w1
* pow((m0
- m1
), 2);if (sb
> max_sb
) {max_sb
= sb
;th
= t
;}}std
::cout
<< "大津算法閾值:" << th
<< std
::endl
;cv
::Mat out
= cv
::Mat
::zeros(height
, width
, CV_8UC1
);for (int y
= 0; y
< height
; y
++) {for (int x
= 0; x
< width
; x
++) {if (gray
.at
<uchar
>(y
, x
) > th
) {out
.at
<uchar
>(y
, x
) = 255;}else {out
.at
<uchar
>(y
, x
) = 0;}}}return out
;
}int main(int argc
, const char* argv
[]) {cv
::Mat img
= cv
::imread("C:/Users/zxdn/Desktop/girl.jpg", cv
::IMREAD_COLOR
);cv
::Mat gray
= BGR2GRAY(img
);cv
::Mat out
= Binarize_Otsu(gray
);cv
::imshow("原圖", img
);cv
::imshow("大津二值化", out
);cv
::waitKey(0);cv
::destroyAllWindows();return 0;
}
總結(jié)
以上是生活随笔為你收集整理的opencv大津算法二值化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。