1、参考博客:https://www.cnblogs.com/riddick/p/7989871.html
2、但是博客代码的i和j的下标表示有些问题
3、修改code-1之后,可以成功运行的代码
1 #include <opencv2opencv.hpp>
2 #include <iostream>
3 #include <string>
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
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/273915
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!