图像分割 1.基于阈值的算法
来源:互联网 发布:java while循环 编辑:程序博客网 时间:2024/05/21 00:47
http://blog.csdn.net/xw20084898/article/details/17564957 主要取自这里,修改为Mat类。
单阈值图像分割算法,有手动阀值,自适应阈值,最大熵法,基本全局阈值法,OTSU阈值。
#include<opencv2/opencv.hpp>#include<opencv2/imgproc.hpp>#include<opencv2/highgui.hpp>#include<vector>using namespace cv;using namespace std;void maxEntroy(Mat src,int&Threshold);int BasicGlobalThreshold(int *pg, int x, int y);int ThresholdOtsu(Mat src);int main() {Mat src,gray,dst1,dst2,dst3,dst4, dst5,dst6;src = imread("trees.png");cvtColor(src, gray, CV_BGR2GRAY);imshow("原图", src);imshow("灰度图", gray);///手动设置阈值threshold(gray, dst1,100, 255, CV_THRESH_BINARY);namedWindow("手动阈值",CV_WINDOW_AUTOSIZE);imshow("手动阈值", dst1);///自适应阈值计算图像领域平均灰度double max_value = 255; int adpative_method = CV_ADAPTIVE_THRESH_GAUSSIAN_C;//CV_ADAPTIVE_THRESH_MEAN_C int threshold_type = CV_THRESH_BINARY;int block_size = 21;//阈值的象素邻域大小 int offset = 3;//窗口尺寸 adaptiveThreshold(gray, dst2, max_value, adpative_method, threshold_type, block_size, offset);namedWindow("自适应阈值", CV_WINDOW_AUTOSIZE);imshow("自适应阈值", dst2);///最大熵法int Threshold3;maxEntroy(src, Threshold3);threshold(gray, dst3, Threshold3, 255, CV_THRESH_BINARY);namedWindow("最大熵阈值", CV_WINDOW_AUTOSIZE);imshow("最大熵阈值", dst3);///基本全局阈值法int Threshold4;Mat imgBasicGlobalThreshold = gray.clone();int pg[256], i;for (i = 0; i<256; i++) pg[i] = 0;for (int i= 0; i < gray.rows; i++){for (int j = 0; j < gray.cols; j++){pg[gray.at<uchar>(i,j)]++;//应该是无符号整型}}Threshold4 = BasicGlobalThreshold(pg, 0, 256); // 确定阈值 cout << "The Threshold of this Image in BasicGlobalThreshold is:" << Threshold4 << endl;//输出显示阀值 threshold(imgBasicGlobalThreshold, imgBasicGlobalThreshold, Threshold4, 255, CV_THRESH_BINARY); // 二值化 namedWindow("BasicGlobalThreshold", CV_WINDOW_AUTOSIZE);imshow("BasicGlobalThreshold", imgBasicGlobalThreshold);//显示图像 ///OTSU阈值Mat imgOTSU = gray.clone();int Threshold5;Threshold5 = ThresholdOtsu(imgOTSU);cout << "The Threshold of this Image in Otsu is:" << Threshold5 << endl;//输出显示阀值 threshold(imgOTSU, imgOTSU, Threshold5, 255, CV_THRESH_BINARY); // 二值化 namedWindow("imgOtsu", CV_WINDOW_AUTOSIZE);imshow("imgOtsu", imgOTSU);//显示图像 waitKey(0);}void maxEntroy(Mat src, int &Threshold) {int tbHist[256] = { 0 }; //每种像素个数int index = 0; //最大熵对应的灰度double Property = 0.0; //像素所占概率double maxEntropy = -1.0; //最大熵double frontEntropy = 0.0; //前景熵double backEntropy = 0.0; //背景熵//纳入计算的总像素数int TotalPixel = 0;int nCol = src.cols * src.channels(); //每行的像素个数for (int i = 0; i < src.rows; i++){uchar* pData = src.ptr<uchar>(i);for (int j = 0; j < nCol; ++j){++TotalPixel;tbHist[pData[j]] += 1;}}for (int i = 0; i < 256; i++){//计算背景像素数double backTotal = 0;for (int j = 0; j < i; j++){backTotal += tbHist[j];}//背景熵for (int j = 0; j < i; j++){if (tbHist[j] != 0){Property = tbHist[j] / backTotal;backEntropy += -Property * logf((float)Property);}}//前景熵for (int k = i; k < 256; k++){if (tbHist[k] != 0){Property = tbHist[k] / (TotalPixel - backTotal);frontEntropy += -Property * logf((float)Property);}}if (frontEntropy + backEntropy > maxEntropy) //得到最大熵{maxEntropy = frontEntropy + backEntropy;index = i;}//清空本次计算熵值frontEntropy = 0.0;backEntropy = 0.0;}Threshold = index;}int BasicGlobalThreshold(int *pg, int start, int end){int i, t, t1, t2, k1, k2;double u, u1, u2;t = 0;u = 0;for (i = start; i<end; i++){t += pg[i];u += i*pg[i];}k2 = (int)(u / t); // 计算此范围灰度的平均值 do{k1 = k2;t1 = 0;u1 = 0;for (i = start; i <= k1; i++){ // 计算低灰度组的累加和 t1 += pg[i];u1 += i*pg[i];}t2 = t - t1;u2 = u - u1;if (t1)u1 = u1 / t1; // 计算低灰度组的平均值 elseu1 = 0;if (t2)u2 = u2 / t2; // 计算高灰度组的平均值 elseu2 = 0;k2 = (int)((u1 + u2) / 2); // 得到新的阈值估计值 } while (k1 != k2); // 数据未稳定,继续 return k1; // 返回阈值 }int ThresholdOtsu(Mat src){int height = src.cols;int width = src.rows;//histogramfloat histogram[256] = { 0 };for (int i = 0; i<src.rows; i++) {for (int j = 0; j<src.cols; j++) {histogram[src.at<uchar>(i,j)]++;}}//normalize histogramint size = height*width;for (int i = 0; i<256; i++) {histogram[i] = histogram[i] / size;}//average pixel valuefloat avgValue = 0;for (int i = 0; i<256; i++) {avgValue += i*histogram[i];}int threshold;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;}}return threshold;}
0 0
- 图像分割 1.基于阈值的算法
- 基于粒子群算法的图像阈值分割
- 基于Otsu算法的图像自适应阈值分割
- 基于阈值图像分割
- 基于matlab的图像阈值分割算法---参数法(自动阈值选择)
- 基于阈值法的图像分割技术
- 基于阈值法的图像分割技术
- 图像算法:图像阈值分割
- 图像算法:图像阈值分割
- 基于OTSU算法和基本粒子群优化算法的双阈值图像分割
- 基于OTSU算法和基本粒子群优化算法的双阈值图像分割
- matlab基于遗传算法的最大熵值法的双阈值图像分割
- 基于梯度调整的矩不变自动阈值图像分割算法
- 基于梯度调整的矩不变自动阈值图像分割算法
- 基于MATLAB的图像自适应阈值分割程序
- 图像分割—基于图像数据的自动选择阈值(基本全局阈值处理方法)
- 图像阈值分割---基本的全局阈值
- 图像分割--使用迭代算法的全局阈值处理
- BottomSheetBehavior的坑
- gym 101194 china final Problem H. Great Cells(数学,想法题,好题)
- 畅通工程
- 关于股权,写给技术人的合伙攻略
- How tomcat works——10 安全性
- 图像分割 1.基于阈值的算法
- 初识Vue.js
- 微信小程序开发文档详细讲解
- LeetCode 42. Trapping Rain Water
- 1
- matplotlib.pyplot介绍
- STM32学习之路-AIRCR寄存器PRIGROUP位的配置<NIVC
- C#三层架构详解--以系统登录为例
- 2