常用opencv3+Visual Studio12阈值分割代码

  • T6_341703
    了解作者
  • 6.6MB
    文件大小
  • 文件格式
  • 0
    收藏次数
  • VIP专享
    资源类型
  • 0
    下载次数
  • 2022-04-22 00:03
    上传日期
自己总结的,很简单的代码,图片路径大家改一改,代码看懂后可以把注释去掉也能用,可计算不同方法耗时
阈值分割.rar
内容介绍
#include <opencv2/opencv.hpp> #include<opencv2/highgui/highgui.hpp> #include<iostream> #include<time.h> using namespace std; using namespace cv; int IterationThreshold(Mat gray); int EntropySeg(Mat src); int pValueThreshold(Mat Frame, int maxValue, double ratio, int valueTop); int main() { clock_t start, finish; double totaltime; start = clock(); Mat src = imread("C:/Users/dxscd/Desktop/图片1.jpg",1); const int width = src.cols; const int height = src.rows; Mat gray,OutImage1, OutImage2, OutImage3,OutImage4,OutImage5; gray.create(height, width, CV_8UC1); cvtColor(src, gray, CV_BGR2GRAY); int graythreshold,T1; int thres = IterationThreshold(gray); T1 = EntropySeg(gray); Mat OutImage6 = gray.clone(); //用哪个方法就注释掉其他方法,可计算耗时 //threshold(gray, OutImage1, thres, 255, CV_THRESH_BINARY);//迭代阈值分割 graythreshold = threshold(gray,OutImage2,0,255,CV_THRESH_BINARY | CV_THRESH_OTSU); //大律法 //adaptiveThreshold(gray,OutImage3,255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY,151,0);//自适应阈值 //threshold(gray,OutImage4, 50, 255, CV_THRESH_BINARY);//固定阈值分割 //threshold(gray, OutImage5, T1, 255, CV_THRESH_BINARY);//最大熵阈值分割 //int res = pValueThreshold(OutImage6, 218, 0.26346,255);//P参数法 finish = clock(); totaltime = (double)(finish - start) / CLOCKS_PER_SEC; cout << "此程序锁耗时间为:" << totaltime << "秒" << endl; /*namedWindow("迭代阈值",0); imshow("迭代阈值", OutImage1);*/ /*namedWindow("OTSU",0); imshow("OTSU", OutImage2);*/ /*namedWindow("自适应阈值",0); imshow("自适应阈值", OutImage3);*/ /*namedWindow("固定阈值",0); imshow("固定阈值", OutImage4);*/ /*namedWindow("最大熵阈值",0); imshow("最大熵阈值", OutImage5);*/ /*namedWindow("P参数法",0); imshow("P参数法", OutImage6);*/ imwrite("C:/Users/dxscd/Desktop/迭代阈值.jpg", OutImage2); //imwrite("C:/Users/dxscd/Desktop/OTSU.jpg", OutImage2); //imwrite("C:/Users/dxscd/Desktop/自适应阈值.jpg", OutImage3); //imwrite("C:/Users/dxscd/Desktop/固定阈值.jpg", OutImage4); //imwrite("C:/Users/dxscd/Desktop/最大熵阈值.jpg", OutImage5); /*imwrite("C:/Users/dxscd/Desktop/P参数法.jpg", OutImage6);*/ waitKey(0); return 0; } //迭代阈值分割****************************************************************************************************** int IterationThreshold(Mat gray)//迭代阈值分割 { int width = gray.cols; int height = gray.rows; //直方图统计 int histData[256] = {0}; for(int j = 0; j < height; j ++) { uchar*data = (uchar*)(gray.ptr<uchar>(0) + j * gray.step); for (int i = 0; i < width; i ++) { histData[data[i]]++; } } //求图像的平均灰度值作为初始阈值 int T0 = 0; for (int i = 0; i < 256; i ++) { T0 += i * histData[i]; } T0 /= width * height; //迭代 int T1 = 0, T2 = 0; int num1 = 0, num2 = 0; int T = 0; while (1) { for ( int i = 0; i < T0+1; i ++) { T1 += i * histData[i]; num1 += histData[i]; } if (num1 == 0) continue; for ( int i = T0 + 1; i < 256; i ++) { T2 += i * histData[i]; num2 += histData[i]; } if (num2 == 0) continue; T = (T1 / num1 + T2 / num2) / 2; if ( T == T0 ) break; else T0 = T; } return T; } //最大熵阈值分割************************************************************************* int EntropySeg(Mat src) { 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; } //Mat dst; //threshold(src, dst, index, 255, 0); return index; } //P参数法**************************************************************** int pValueThreshold(Mat Frame, int maxValue, double ratio, int valueTop) { //直方图均衡化 equalizeHist(Frame, Frame); //计算直方图 Mat hist; //将要获得的直方图 int imgNum = 1; //图像数量 int histDim = 1; //直方图维度 int histSize = 256; //每个维度的bin个数 float range[] = { 0,256 }; //每个维度的统计范围 const float* histRange = { range }; bool accumulate = false; calcHist(&Frame, 1, 0, Mat(), hist, 1, &histSize, &histRange, true, false); //hist中的第一行,是直方图的值. float* p = hist.ptr<float>(0); //循环计算阈值 int countPix = Frame.cols * Frame.rows; int thresholdPix = 0; double ratioReal; int thresholdValue = maxValue; for (; thresholdValue >= 0; thresholdValue--) { thresholdPix += p[thresholdValue]; ratioReal = (double)thresholdPix / countPix; if (ratioReal>ratio) { break; } } //可能图像不符合要求 if (thresholdValue < 0) { return -1; } //使用阈值将图像二值化 int curValue = 0; for (int i = 0; i < Frame.rows; ++i) { for (int j = 0; j < Frame.cols; ++j) { curValue = Frame.at<uchar>(i, j); if (curValue >= thresholdValue && curValue <= maxValue) { Frame.at<uchar>(i, j) = 0; } else { Frame.at<uchar>(i, j) = valueTop; } } } return 0; }
评论
    相关推荐