博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【C++】如何利用直方图实现快速中值滤波
阅读量:5036 次
发布时间:2019-06-12

本文共 4019 字,大约阅读时间需要 13 分钟。

1、参考博客:https://www.cnblogs.com/riddick/p/7989871.html

2、但是博客代码的i和j的下标表示有些问题

3、修改code-1之后,可以成功运行的代码

1 #include 
2 #include
3 #include
4 5 using namespace cv; 6 using namespace std; 7 8 //计算亮度中值和灰度<=中值的像素点个数 9 int calMediaValue(const int histogram[], int thresh) 10 { 11 int sum = 0; 12 for (int i = 0; i < 256; ++i) 13 { 14 sum += histogram[i]; 15 if (sum >= thresh) 16 { 17 return i; 18 } 19 } 20 return 255; 21 } 22 23 void fastMedianBlur(const Mat &srcImg, Mat &dstImg, int diameter) 24 { 25 int radius = (diameter - 1) / 2; 26 int imgW = srcImg.cols; // 1920 宽 27 int imgH = srcImg.rows; // 1200 高 28 int channels = srcImg.channels(); // 1 29 dstImg = Mat::zeros(imgH, imgW, CV_8UC1); 30 int windowSize = diameter*diameter; // 25 31 32 //直方图 33 int Hist[256] = { 0 }; 34 int histogramSize = 256;//灰度等级 35 int thresholdValue = windowSize / 2 + 1; // 13 36 37 uchar *pSrcData = srcImg.data; 38 uchar *pDstData = dstImg.data; 39 40 int right = imgW - radius; // 1918 41 int bot = imgH - radius; // 1198 42 for (int j = radius; j < bot; j++) // 行 43 { 44 45 for (int i = radius; i < right; i++) //列 46 { 47 //每一行第一个待滤波像素建立直方图 48 if (i == radius) 49 { 50 memset(Hist, 0, histogramSize*sizeof(int)); 51 for (int y = j - radius; y <= min(j + radius, imgH); y++) 52 { 53 for (int x = i - radius; x <= min(i + radius,imgW); x++) 54 { 55 uchar value = pSrcData[y*imgW + x]; 56 Hist[value]++; 57 } 58 } 59 } 60 else//更新直方图 61 { 62 int left = i - radius - 1; 63 int right = i + radius; 64 for (int y = j - radius; y <= min(j + radius, imgH); y++) 65 { 66 //减去左边一列 67 int leftIdx = y*imgW + left; 68 uchar leftValue = pSrcData[leftIdx]; 69 Hist[leftValue]--; 70 71 //加上右边一列 72 int rightIdx = y*imgW + right; 73 uchar rightValue = pSrcData[rightIdx]; 74 Hist[rightValue]++; 75 } 76 } 77 78 //直方图求中值 79 uchar filterValue = calMediaValue(Hist, thresholdValue); 80 pDstData[j*imgW + i] = filterValue; 81 } 82 } 83 84 //边界直接赋原始值,不做滤波处理 85 pSrcData = srcImg.data; 86 pDstData = dstImg.data; 87 //上下边界 88 for (int i = 0; i < imgW; i++) 89 { 90 for (int j = 0; j < radius; j++) 91 { 92 int idxTop = j*imgW + i; 93 pDstData[idxTop] = pSrcData[idxTop]; 94 int idxBot = (imgH - j - 1)*imgW + i; 95 pDstData[idxBot] = pSrcData[idxBot]; 96 } 97 } 98 //左右边界 99 for (int j = radius; j < imgH - radius - 1; j++)100 {101 for (int i = 0; i < radius; i++)102 {103 int idxLeft = j*imgW + i;104 pDstData[idxLeft] = pSrcData[idxLeft];105 int idxRight = j*imgW + imgW - i - 1;106 pDstData[idxRight] = pSrcData[idxRight];107 }108 }109 }110 111 112 int main()113 {114 string imgPath = "D:\\Images\\漂亮的图片\\";115 Mat srcImg = imread(imgPath + "2.jpg", 0);116 Mat dstImg;117 118 double t0 = cv::getTickCount();119 fastMedianBlur(srcImg, dstImg, 5);120 double t1 = cv::getTickCount();121 122 cout << "time=" << (t1 - t0) / cv::getTickFrequency() << " seconds" << endl;123 124 imwrite("srcImg.jpg", srcImg);125 imwrite("myFilter.jpg", dstImg);126 127 return 0;128 }

结果示例,中值滤波后的图片

转载于:https://www.cnblogs.com/liulijin/p/9038230.html

你可能感兴趣的文章
clojure-emacs-autocomplete
查看>>
一个自己写的判断2个相同对象的属性值差异的工具类
查看>>
10 华电内部文档搜索系统 search03
查看>>
[CF803C] Maximal GCD(gcd,贪心,构造)
查看>>
逆时针旋转的矩阵变换
查看>>
第10周15/16/17
查看>>
Tomcat
查看>>
./是当前目录 ../是当前的上一级目录。上上级就是../../一般绝对路径时候常用...
查看>>
oracle连接的三个配置文件(转)
查看>>
Java 8 中如何优雅的处理集合
查看>>
[HNOI2012]永无乡 线段树合并
查看>>
Centos下源码安装git
查看>>
gulp-rev-append md5版本号
查看>>
IO流之File类
查看>>
sql 基础语句
查看>>
CF717A Festival Organization(第一类斯特林数,斐波那契数列)
查看>>
控件发布:div2dropdownlist(div模拟dropdownlist控件)
查看>>
Oracle composite index column ordering
查看>>
kaggle竞赛
查看>>
区块链入门教程
查看>>