1 #include <opencv2/opencv.hpp> 2 #include <opencv2/core/core.hpp> 3 #include <opencv2/highgui/highgui.hpp> 4 #include<iostream> 5 #include<stdlib.h> 6 using namespace cv; 7 using namespace std; 8 9 10 void MeanFilter_my1(const Mat &src, Mat &dst, int ksize)//均值滤波 11 { 12 CV_Assert(ksize % 2 == 1); 13 14 int *kernel = new int[ksize*ksize]; 15 for (int i = 0; i < ksize*ksize; i++) 16 kernel[i] = 1; 17 Mat tmp; 18 int len = ksize / 2; 19 tmp.create(Size(src.cols + len, src.rows + len), src.type());//添加边框 20 dst.create(Size(src.cols, src.rows), src.type()); 21 22 int channel = src.channels(); 23 uchar *ps = src.data; 24 uchar *pt = tmp.data; 25 26 for (int row = 0; row < tmp.rows; row++)//添加边框的过程 27 { 28 for (int col = 0; col < tmp.cols; col++) 29 { 30 for (int c = 0; c < channel; c++) 31 { 32 if (row >= len && row < tmp.rows - len && col >= len && col < tmp.cols - len) 33 pt[(tmp.cols * row + col)*channel + c] = ps[(src.cols * (row - len) + col - len) * channel + c]; 34 else 35 pt[(tmp.cols * row + col)*channel + c] = 0; 36 } 37 } 38 } 39 40 41 uchar *pd = dst.data; 42 pt = tmp.data; 43 for (int row = len; row < tmp.rows - len; row++)//卷积的过程 44 { 45 for (int col = len; col < tmp.cols - len; col++) 46 { 47 for (int c = 0; c < channel; c++) 48 { 49 short t = 0; 50 for (int x = -len; x <= len; x++) 51 { 52 for (int y = -len; y <= len; y++) 53 { 54 t += kernel[(len + x) * ksize + y + len] * pt[((row + x) * tmp.cols + col + y) * channel + c]; 55 } 56 } 57 58 pd[(dst.cols * (row - len) + col - len) * channel + c] = saturate_cast<ushort> (t/(ksize*ksize));//防止数据溢出ushort是16为数据 59 } 60 } 61 } 62 delete[] kernel; 63 } 64 //方差可调节 65 void GaussFilter_my(const Mat &src, Mat &dst, int ksize, double sigmaX, double sigmaY = 0) 66 { 67 CV_Assert(ksize % 2 == 1); 68 69 if (fabs(sigmaY) < 1e-5) 70 sigmaY = sigmaX; 71 72 double *kernel = new double[ksize*ksize]; 73 int center = ksize / 2; 74 double sum = 0; 75 for (int i = 0; i < ksize; i++) 76 { 77 for (int j = 0; j < ksize; j++) 78 { 79 kernel[i * ksize + j] = exp(-(i - center)*(i - center) / (2 * sigmaX*sigmaX) - (j - center)*(j - center) / (2 * sigmaY*sigmaY)); 80 sum += kernel[i*ksize + j]; 81 } 82 } 83 for (int i = 0; i < ksize; i++) 84 { 85 for (int j = 0; j < ksize; j++) 86 { 87 kernel[i*ksize + j] /= sum; 88 } 89 } 90 Mat tmp; 91 int len = ksize / 2; 92 tmp.create(Size(src.cols + len, src.rows + len), src.type());//添加边框 93 dst.create(Size(src.cols, src.rows), src.type()); 94 95 96 int channel = src.channels(); 97 uchar *ps = src.data; 98 uchar *pt = tmp.data; 99 100 for (int row = 0; row < tmp.rows; row++)//添加边框的过程 101 { 102 for (int col = 0; col < tmp.cols; col++) 103 { 104 for (int c = 0; c < channel; c++) 105 { 106 if (row >= len && row < tmp.rows - len && col >= len && col < tmp.cols - len) 107 pt[(tmp.cols * row + col)*channel + c] = ps[(src.cols * (row - len) + col - len) * channel + c]; 108 else 109 pt[(tmp.cols * row + col)*channel + c] = 0; 110 } 111 } 112 } 113 114 uchar *pd = dst.data; 115 pt = tmp.data; 116 for (int row = len; row < tmp.rows - len; row++)//卷积的过程 117 { 118 for (int col = len; col < tmp.cols - len; col++) 119 { 120 for (int c = 0; c < channel; c++) 121 { 122 short t = 0; 123 for (int x = -len; x <= len; x++) 124 { 125 for (int y = -len; y <= len; y++) 126 { 127 t += kernel[(len + x) * ksize + y + len] * pt[((row + x) * tmp.cols + col + y) * channel + c]; 128 } 129 } 130 131 pd[(dst.cols * (row - len) + col - len) * channel + c] = saturate_cast<ushort> (t);//防止数据溢出ushort是16为数据 132 } 133 } 134 } 135 delete[] kernel; 136 } 137 138 int main() 139 { 140 Mat img=imread("E://lena.jpg"); 141 Mat dst=imread("E://heibai.jpg"); 142 imshow("img",img); 143 imshow("dst",dst); 144 int k=7; 145 double sigmaX=0.001; 146 double sigmaY = 0.001; 147 MeanFilter_my1(img,dst,k); 148 imshow("dst1",dst); 149 GaussFilter_my(img,dst,k,sigmaX,sigmaY ); 150 imshow("dst1",dst); 151 152 153 waitKey(0); 154 }