图像滤波处理和直方图均衡化

高斯滤波:

 1 #include<iostream>
 2 #include <opencv2/core/core.hpp>
 3 #include <opencv2/highgui/highgui.hpp>
 4 #include <opencv2/imgproc/imgproc.hpp>
 5 #include "guassfilter.h"
 6 
 7 using namespace std;
 8 using namespace cv;
 9 
10 double **GuassKenel(int size, double sigma) {
11     int i, j;
12     double sum = 0.0;
13     int center = size / 2;
14     const double PI = 4.0*atan(1.0); //圆周率π赋值
15 
16     double **arr = new double*[size];//建立一个size*size大小的二维数组
17     for (i = 0; i < size; i++)
18         arr[i] = new double[size];
19 
20     for (i = 0; i < size; i++)
21         for (j = 0; j < size; j++) {
22             arr[i][j] = (1 / (2 * PI*sigma*sigma))*exp(-((i - center)*(i - center) + (j - center)*(j - center)) / (sigma*sigma * 2));
23             sum += arr[i][j];
24         }
25     for (i = 0; i < size; i++) {
26         for (j = 0; j < size; j++)
27             arr[i][j] /= sum;
28     }
29     return arr;
30 }
31 
32 
33 void GaussFilter(const Mat _src, Mat &_dst, int ksize, double ksigma) {
34 
35     if (!_src.data) return;
36     double **arra;
37     Mat tmp(_src.size(), _src.type());
38     for (int i = 0; i < _src.rows; i++)
39         for (int j = 0; j < _src.cols; j++) {
40             //边缘不进行处理
41             if ((i - (ksize / 2)) > 0 && (i + (ksize / 2))  < _src.rows && (j - (ksize / 2)) > 0 && (j + (ksize / 2)) < _src.cols) {
42                 arra = GuassKenel(ksize, ksigma);
43                 tmp.at<uchar>(i, j) = 0;
44                 for (int x = 0; x < ksize; x++) {
45                     for (int y = 0; y < ksize; y++) {
46                         tmp.at<uchar>(i, j) += arra[x][y] * _src.at<uchar>(i + (ksize / 2) - x, j + (ksize / 2) - y);
47                     }
48                 }
49             }
50             else {
51                 tmp.at<uchar>(i, j) = _src.at<uchar>(i, j);
52             }
53         }
54     tmp.copyTo(_dst);
55 }
View Code

拉普拉斯滤波:

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "laplace.h"

using namespace std;
using namespace cv;

void LaplaceFilter(const Mat _src, Mat & _dst) {

    if (!_src.data) return;
    Mat tmp(_src.size(), _src.type());
    for (int i = 0; i < _src.rows; i++) {
        for (int j = 0; j < _src.cols; j++) {
            if ((i - 1) > 0 && (i + 1)  < _src.rows && (j - 1) > 0 && (j + 1) < _src.cols) {
                double arra[3][3] = { { 0,-1,0 },{ -1,5,-1 },{ 0,-1,0 } };
                tmp.at<uchar>(i, j) = 0;
                for (int x = 0; x < 3; x++) {
                    for (int y = 0; y < 3; y++) {
                        tmp.at<uchar>(i, j) += arra[x][y] * _src.at<uchar>(i + 1 - x, j + 1 - y);
                    }
                }
            }
            else {
                tmp.at<uchar>(i, j) = _src.at<uchar>(i, j);
            }
        }
    }
    tmp.copyTo(_dst);
}
View Code

 均值滤波:

 1 #include <iostream>
 2 #include <opencv2/core/core.hpp>
 3 #include <opencv2/highgui/highgui.hpp>
 4 #include <opencv2/imgproc/imgproc.hpp>
 5 #include "meanfilter.h"
 6 
 7 using namespace std;
 8 using namespace cv;
 9 
10 double **MeanKenel(int size) {
11     double **arr = new double*[size];//建立一个size*size大小的二维数组
12     for (int i = 0; i < size; i++)
13         arr[i] = new double[size];
14 
15     for (int i = 0; i < size; i++) {
16         for (int j = 0; j < size; j++) {
17             arr[i][j] = 1.0 / 9;
18         }
19     }
20     return arr;
21 }
22 
23 void MeanFilter(const Mat _src, Mat & _dst, int ksize) {
24 
25     if (!_src.data) return;
26     double **arra;
27     Mat tmp(_src.size(), _src.type());
28     for (int i = 0; i < _src.rows; i++) {
29         for (int j = 0; j < _src.cols; j++) {
30             if ((i - (ksize / 2)) > 0 && (i + (ksize / 2))  < _src.rows && (j - (ksize / 2)) > 0 && (j + (ksize / 2)) < _src.cols) {
31                 arra = MeanKenel(ksize);
32                 tmp.at<uchar>(i, j) = 0;
33                 for (int x = 0; x < ksize; x++) {
34                     for (int y = 0; y < ksize; y++) {
35                         tmp.at<uchar>(i, j) += arra[x][y] * _src.at<uchar>(i + (ksize / 2) - x, j + (ksize / 2) - y);
36                     }
37                 }
38             }
39             else {
40                 tmp.at<uchar>(i, j) = _src.at<uchar>(i, j);
41             }
42         }
43     }
44     tmp.copyTo(_dst);
45 }
View Code

直方图均衡化:

 1 #include <iostream>
 2 #include <opencv2/core/core.hpp>
 3 #include <opencv2/highgui/highgui.hpp>
 4 #include <opencv2/imgproc/imgproc.hpp>
 5 #include "equalization.h"
 6 
 7 using namespace std;
 8 using namespace cv;
 9 
10 
11 
12 void Equalization(Mat& input, Mat &_dst)
13 {
14     int gray[256] = { 0 };  //记录每个灰度级别下的像素个数
15     double gray_prob[256] = { 0 };  //记录灰度分布密度
16     double gray_distribution[256] = { 0 };  //记录累计密度
17     int gray_equal[256] = { 0 };  //均衡化后的灰度值
18     int gray_sum = 0;  //像素总数
19     Mat output = input.clone();
20     gray_sum = input.cols * input.rows;
21 
22     //统计每个灰度下的像素个数
23     for (int i = 0; i < input.rows; i++)
24     {
25         uchar* p = input.ptr<uchar>(i);
26         for (int j = 0; j < input.cols; j++)
27         {
28             int vaule = p[j];
29             gray[vaule]++;
30         }
31     }
32 
33 
34     //统计灰度频率
35     for (int i = 0; i < 256; i++)
36     {
37         gray_prob[i] = ((double)gray[i] / gray_sum);
38     }
39 
40     //计算累计密度
41     gray_distribution[0] = gray_prob[0];
42     for (int i = 1; i < 256; i++)
43     {
44         gray_distribution[i] = gray_distribution[i - 1] + gray_prob[i];
45     }
46 
47     //重新计算均衡化后的灰度值,四舍五入。参考公式:(N-1)*T+0.5
48     for (int i = 0; i < 256; i++)
49     {
50         gray_equal[i] = (uchar)(255 * gray_distribution[i] + 0.5);
51     }
52 
53 
54     //直方图均衡化,更新原图每个点的像素值
55     for (int i = 0; i < output.rows; i++)
56     {
57         uchar* p = output.ptr<uchar>(i);
58         for (int j = 0; j < output.cols; j++)
59         {
60             p[j] = gray_equal[p[j]];
61         }
62     }
63 
64     output.copyTo(_dst);
65 }
View Code

 主函数:

 1 #include <iostream>
 2 #include <opencv2/core/core.hpp>
 3 #include <opencv2/highgui/highgui.hpp>
 4 #include <opencv2/imgproc/imgproc.hpp>
 5 #include "guassfilter.h"
 6 #include "meanfilter.h"
 7 #include "laplace.h"
 8 #include "equalization.h"
 9 
10 using namespace std;
11 using namespace cv;
12 
13 int main() {
14 
15     Mat image = imread("D:\\研一\\图像处理与计算机视觉\\图像处理作业\\img.jpg", 0);
16     Mat gauss1, gauss2, gauss3, mean, laplace, equalization;
17     int a, b, c, d;
18     double e, f, g;
19     cout << "请输入第一次高斯滤波器模板的阶数和方差:" << endl;
20     cin >> a >> e;
21     cout << "请输入第二次高斯滤波器模板的阶数和方差:" << endl;
22     cin >> b >> f;
23     cout << "请输入第三次高斯滤波器模板的阶数和方差:" << endl;
24     cin >> c >> g;
25     cout << "请输入均值滤波器模板的阶数:" << endl;
26     cin >> d;
27     cout << "拉普拉斯滤波器卷积核固定选为:" << endl <<" "<< 0 << " " << -1 << "  " << 0 << endl << -1 << "  " << 5 << " " << -1 << endl <<" "<< 0 << " " << -1 << "  " << 0 << endl;
28     GaussFilter(image, gauss1, a, e);
29     GaussFilter(image, gauss2, b, f);
30     GaussFilter(image, gauss3, c, g);
31     MeanFilter(image, mean, d);
32     LaplaceFilter(image, laplace);
33     Equalization(image, equalization);
34 
35     namedWindow("原图");
36     namedWindow("高斯滤波器1");
37     namedWindow("高斯滤波器2");
38     namedWindow("高斯滤波器3");
39     namedWindow("均值滤波器");
40     namedWindow("拉普拉斯滤波器");
41     namedWindow("直方图均衡化");
42 
43     imshow("原图", image);
44     imshow("高斯滤波器1", gauss1);
45     imshow("高斯滤波器2", gauss2);
46     imshow("高斯滤波器3", gauss3);
47     imshow("均值滤波器",mean);
48     imshow("拉普拉斯滤波器", laplace);
49     imshow("直方图均衡化", equalization);
50 
51     imwrite("原图.jpg", image);
52     imwrite("高斯滤波器1.jpg", gauss1);
53     imwrite("高斯滤波器2.jpg", gauss2);
54     imwrite("高斯滤波器3.jpg", gauss3);
55     imwrite("均值滤波器.jpg", mean);
56     imwrite("拉普拉斯滤波.jpg", laplace);
57     imwrite("直方图均衡化.jpg", equalization);
58 
59     waitKey();
60     return 0;
61 }
View Code

猜你喜欢

转载自www.cnblogs.com/hati/p/9214221.html