在阈值处理中,常用的算法就是OTSU,OTSU是在1979年提出的一种寻找图像阈值的最大类间方差算法。
步骤如下:
1.统计灰度及中每个像素在整幅图中的个数
2.计算每个像素在整幅图像中的概率分布
3.对灰度级进行遍历搜索,计算当前灰度下前景背景类间概率
4.通过目标函数计算出类内与类间方差下对应的阈值
代码如下:
#include "opencv2/highgui/highgui.hpp"#include "opencv2/opencv.hpp"#include "opencv2/core/core.hpp"#include <stdio.h>#include <string>using namespace std;using namespace cv;//OTSU函数实现int OTSU(cv::Mat srcImage){int nCols = srcImage.cols;int nRows = srcImage.rows;int threshold = 0;//统计初始化参数int nSumPix[256];float nProDis[256];for (int i = 0; i < 256; i++){nSumPix[i] = 0;nProDis[i] = 0;}//统计灰度级中每个像素在整附图中的个数for (int i = 0; i < nRows; i++){for (int j = 0; j < nCols; j++){nSumPix[(int)srcImage.at<uchar>(i,j)]++;}}//计算每个灰度级占图像中的概率分布for (int i = 0; i < 256; i++){nProDis[i] = (float)nSumPix[i] / (nCols * nRows);}//遍历灰度级[0, 255],计算出最大类间方差下的阈值float w0, w1, u0_temp, u1_temp, u0, u1, delta_temp;float delta_max = 0;for (int i = 0; i < 256; i++){//初始化相关参数w0 = w1 = u0_temp = u1_temp = u0 = u1 = delta_temp = 0;for (int j = 0; j < 256; j++){//背景部分if (j <= i){//当前i为分割阈值,第一类总的概率w0 += nProDis[j];u0_temp += j * nProDis[j];}//前景部分else{//当前i为分割阈值,第一类总的概率w1 += nProDis[j];u1_temp += j * nProDis[j];}}//计算各类的平均灰度u0 = u0_temp / w0;u1 = u1_temp / w1;delta_temp = (float)(w0 * w1 * pow((u0 - u1), 2));//依次找到最大类间方差下的阈值if (delta_temp > delta_max){delta_max = delta_temp;threshold = i;}}return threshold;}int main(){cv::Mat srcImage = cv::imread("C:\\Users\\LP\\Desktop\\C++\\ConsoleApplication4\\ConsoleApplication4\\RGBFlower4.jpg");if (srcImage.empty()){return -1;}cv::imshow("原图像", srcImage);//灰度转换cv::Mat srcGray;cv::cvtColor(srcImage, srcGray, CV_RGB2GRAY);cv::imshow("srcGray", srcGray);//调用OTSU二值化算法得到阈值int ostuThreshold = OTSU(srcGray);std::cout << ostuThreshold << std::endl;//定义输出结果图像cv::Mat otsuResultImage = cv::Mat::zeros( srcGray.rows, srcGray.cols, CV_8UC1);//利用得到的阈值进行二值化操作for (int i = 0; i < srcGray.rows; i++){for (int j = 0; j < srcGray.cols; j++){//高像素阈值判断if (srcGray.at<uchar>(i,j) > ostuThreshold){otsuResultImage.at<uchar>(i,j) = 255;}else{otsuResultImage.at<uchar>(i,j) = 0;}}}cv::imshow("otsuResultImage", otsuResultImage);cv::waitKey(0);return 0;}
本文介绍了OTSU阈值算法的原理与应用,这是一种用于图像处理的经典算法,能够自动确定最佳阈值,实现图像的二值化处理。文章详细解释了算法的四个主要步骤,并提供了一个使用OpenCV实现OTSU算法的示例代码。
3405

被折叠的 条评论
为什么被折叠?



