数字图像处理基础实验(三):空域滤波

一、实验内容及原理

1、利用均值模板平滑灰度图像

具体内容:利用 OpenCV 对图像像素进行操作,分别利用 33、55 和 9*9 尺寸的均值模板平滑灰度图像

2、利用高斯模板平滑灰度图像

具体内容:利用 OpenCV 对图像像素进行操作,分别利用 33、55 和 9*9 尺寸的高斯模板平滑灰度图像

高斯模板公式: G ( x , y ) = 1 2 π σ 2 e − x 2 + y 2 2 σ 2 G(x,y)=\frac {1}{2\pi \sigma^{2}}e^{-\frac {x^{2}+y^{2}}{2\sigma^{2}}} G(x,y)=2πσ21e2σ2x2+y2

3、利用 Laplacian、Robert、Sobel 模板锐化灰度图像

具体内容:利用 OpenCV 对图像像素进行操作,分别利用 Laplacian、Robert、 Sobel 模板锐化灰度图像

(1)Robert模板

公式: M ( x , y ) ≈ ∣ z 9 − z 5 ∣ + ∣ z 8 − z 6 ∣ M(x,y)\approx |z_9-z_5|+|z_8-z_6| M(x,y)z9z5+z8z6
数字图像处理基础实验(三):空域滤波_第1张图片

(2)Sobel模板

公式:
g x = ϑ f ϑ x = ( z 7 + 2 z 8 + z 9 ) − ( z 1 + 2 z 2 + z 3 ) g_x=\frac {\vartheta f}{\vartheta x}=(z_7+2z_8+z_9)-(z_1+2z_2+z_3) gx=ϑxϑf=(z7+2z8+z9)(z1+2z2+z3)
g y = ϑ f ϑ y = ( z 3 + 2 z 6 + z 9 ) − ( z 1 + 2 z 4 + z 7 ) g_y=\frac {\vartheta f}{\vartheta y}=(z_3+2z_6+z_9)-(z_1+2z_4+z_7) gy=ϑyϑf=(z3+2z6+z9)(z1+2z4+z7)

数字图像处理基础实验(三):空域滤波_第2张图片

(3)Laplacian模板

在这里插入图片描述
数字图像处理基础实验(三):空域滤波_第3张图片
在这里插入图片描述
在这里插入图片描述
数字图像处理基础实验(三):空域滤波_第4张图片

4、利用高提升滤波算法增强灰度图像

具体内容:利用 OpenCV 对图像像素进行操作,设计高提升滤波算法增强图像

掩模计算公式:
g m a s k ( x , y ) = f ( x , y ) − f ^ ( x , y ) g_{mask}(x,y)=f(x,y)-\hat {f}(x,y) gmask(x,y)=f(x,y)f^(x,y)
在原始图像上加上掩模的权重:
g ( x , y ) = f ( x , y ) + k ∗ g m a s k ( x , y ) g(x,y)=f(x,y)+k*g_{mask}(x,y) g(x,y)=f(x,y)+kgmask(x,y)

5、利用均值模板平滑彩色图像

具体内容:利用 OpenCV 分别对图像像素的 RGB 三个通道进行操作,利 用 33、55 和 9*9 尺寸的均值模板平滑彩色图像

6、利用高斯模板平滑彩色图像

具体内容:利用 OpenCV 分别对图像像素的 RGB 三个通道进行操作,分 别利用 33、55 和 9*9 尺寸的高斯模板平滑彩色图像

7、利用 Laplacian、Robert、Sobel 模板锐化灰度图像

具体内容:利用 OpenCV 分别对图像像素的 RGB 三个通道进行操作,分 别利用 Laplacian、Robert、Sobel 模板锐化彩色图像

二、实验代码

实验环境:
(1)OpenCV3.4.3
(2)Ubuntu16.04
(3)VS Code
(4)C++

#include 
#include 
#include 
#include 
#include 

class Experiment3 {
public:
    // 0 初始化:彩色图片,灰度图片,模板(高提升滤波的模板除外)
    Experiment3(std::vector path){
        filter_name.push_back("均值模板平滑");
        filter_name.push_back("高斯模板平滑");
        filter_name.push_back("Laplacian模板锐化");
        filter_name.push_back("Robert模板锐化");
        filter_name.push_back("Sobel模板锐化");
        filter_name.push_back("高提升滤波算法增强");

        pic_color.push_back("灰度");
        pic_color.push_back("彩色");

        filter_size_string.push_back("3 x 3");
        filter_size_string.push_back("5 x 5");
        filter_size_string.push_back("9 x 9");

        for(int i = 0; i < path.size(); i++){
            original_color_image.push_back(cv::imread(path[i]));
            original_gray_image.push_back(color2Gray(original_color_image[i]));
        }

        template_size = 3;
        int step = 2;
        for(int i = 0; i < 3; i++){
            filter_size.push_back(template_size);
            makemeanTemplate(template_size);
            makeGaussTemplate(template_size);
            template_size += step;
            step +=2;
        }
        makeLaplacianTemplate();
        makeRobertTemplate();
        makeSobelTemplate();
        computerGaussTemplateSum();
    }
    // 0.1、彩色图像转灰度图像
    cv::Mat color2Gray(cv::Mat src_image){
        //创建与原图同类型和同大小的矩阵
	    cv::Mat gray_image(src_image.rows, src_image.cols, CV_8UC1);
        if(src_image.channels()!=1){
            for(int i = 0; i < src_image.rows; i++)
                for(int j = 0; j < src_image.cols; j++)
                    gray_image.at(i, j) = (src_image.at(i, j)[0] + src_image.at(i, j)[1] + src_image.at(i, j)[2]) / 3;
        }
        else
            gray_image = src_image.clone();
        return gray_image;
    }
    // 0.2 生成均值模板
    void makemeanTemplate(int size){
        mean_template.push_back(cv::Mat::ones(size, size, CV_8UC1));
    }
    // 0.3 生成高斯模板
    void makeGaussTemplate(int size=3, int sigma=1){
        cv::Mat gaussTemplate = cv::Mat::zeros(size, size, CV_32F);
        
        int center=size/2;
        double min = g(center,center);
        for(int i=0; i < size; i++)
            for(int j=0; j < size; j++)
                gaussTemplate.at(i, j) = g(i-center,j-center)/min;
        
        gaussTemplate.convertTo(gaussTemplate, CV_8U);
        gauss_template.push_back(gaussTemplate);
    }
    // 0.3.1 计算正态分布
    double g(double x, double y, double sigma=1){
        return exp(-(x*x + y*y)/(2*sigma*sigma));
    }
    // 0.3.2 计算高斯模板的和
    void computerGaussTemplateSum(){
        for(int k=0; k < 3; k++){
            int sum = 0;
            for(int i=0; i < gauss_template[k].rows; i++)
                for(int j=0; j < gauss_template[k].cols; j++)
                    sum += gauss_template[k].at(i, j);
            gauss_template_sum.push_back(sum);
        }
    }
    // 0.4 生成Laplacian
    void makeLaplacianTemplate(){
        laplacian_template = (cv::Mat_(3,3) << 0,  1, 0, 
                                                      1, -4, 1, 
                                                      0,  1, 0);
    }
    // 0.5 生成Robert
    void makeRobertTemplate(){
        robert_template.push_back((cv::Mat_(3,3) << 0,  0,  0, 
                                                           0, -1,  0, 
                                                           0,  0,  1));

        robert_template.push_back((cv::Mat_(3,3) << 0,  0,   0, 
                                                           0,  0,  -1, 
                                                           0,  1,   0));
    }
    // 0.6 生成Sobel模板
    void makeSobelTemplate(){
        sobel_template.push_back((cv::Mat_(3,3) <<  -1,   0,   1, 
                                                           -2,   0,   2, 
                                                           -1,   0,   1));

        sobel_template.push_back((cv::Mat_(3,3) <<  -1,  -2,  -1, 
                                                            0,   0,   0, 
                                                            1,   2,   1));
    }
    // 0.7 生成灰度图像mask
    void makeGrayHighPromoteMask(int id){
        highPromote_gray_mask.push_back(original_gray_image[id] - gray_image_process[id * 5]);
    }
    // 0.8 生成彩色图像mask
    void makeColorHighPromoteMask(int id){
        highPromote_color_mask.push_back(original_color_image[id] - color_image_process[id * 5]);
    }
    // 1、灰度空域滤波
    void graySpatialFiltering(int pic_id, int size_id=0, int select=0){
        int size = filter_size[size_id];
        int m = size/2;
        
        cv::Mat image_process = cv::Mat::zeros(original_gray_image[pic_id].size(), original_gray_image[pic_id].type());
        cv::Mat image_grad = cv::Mat::zeros(original_gray_image[pic_id].size(), original_gray_image[pic_id].type());
        for(int i=m; i < original_gray_image[pic_id].rows - m; i++)
            for(int j=m; j < original_gray_image[pic_id].cols - m; j++){ 
                cv::Mat sub_matrix = original_gray_image[pic_id](cv::Rect(j - m, i - m, size, size));
                int grad, value;   
                if(select == 0)
                    image_process.at(i, j) = computerMeanResult(sub_matrix, size_id);
                else if(select == 1)
                    image_process.at(i, j) = computerGaussResult(sub_matrix, size_id);
                else if(select == 2)
                    image_grad.at(i, j) = computerLaplacianResult(sub_matrix);
                else if(select == 3)
                    image_grad.at(i, j) = computerRobertResult(sub_matrix);
                else if(select == 4)
                    image_grad.at(i, j) = computerSobelResult(sub_matrix);
                else if(select == 5)
                    grayHighPromote(pic_id);
                
                if(select == 2 || select == 3 || select == 4){
                    grad = image_grad.at(i, j);
                    value = sub_matrix.at(m, m);
                    if(grad + value > 255)
                        image_process.at(i, j) = 255;
                    else
                        image_process.at(i, j) = grad + value;
                }
            }
        gray_image_process.push_back(image_process);
        if(select == 2)
            gray_image_grad_laplacian.push_back(image_grad);
        else if(select == 3)
            gray_image_grad_robert.push_back(image_grad);
        else if(select == 4)
            gray_image_grad_sobel.push_back(image_grad);
    }
    // 2 计算均值滤波
    int computerMeanResult(cv::Mat& image_block, int size_id){
        int sum = filter_size[size_id] * filter_size[size_id];
        return image_block.dot(mean_template[size_id])/sum;
    }
    // 3 计算高斯滤波
    int computerGaussResult(cv::Mat& image_block, int size_id){
        int sum = gauss_template_sum[size_id];
        return image_block.dot(gauss_template[size_id])/sum;
    }
    // 4 计算Laplacian滤波
    int computerLaplacianResult(cv::Mat& image_block){
        float g = 0.0;
        for(int i=0; i < image_block.rows; i++)
            for(int j=0; j < image_block.cols; j++)
                g += float(image_block.at(i, j)) * laplacian_template.at(i, j);
        if(abs(g) > 255)
            return 255;
        else if(g < 0)
            return -g;
        else
            return g;
    }
    // 5 计算Robert滤波
    int computerRobertResult(cv::Mat& image_block){
        float Gx = float(image_block.at(2,2)) - float(image_block.at(1,1));
        float Gy = float(image_block.at(2,1)) - float(image_block.at(1,2));
        float g =  abs(Gx) + abs(Gy);
        if(g > 255)
            return 255;
        if(g < 0)
            return 0;
        return g;
    }
    // 6 计算Sobel滤波
    int computerSobelResult(cv::Mat& image_block){
        float Gx = 0.0;
        float Gy = 0.0;
        for(int i=0; i < image_block.rows; i++)
            for(int j=0; j < image_block.cols; j++){
                Gx += float(image_block.at(i, j)) * sobel_template[0].at(i, j);
                Gy += float(image_block.at(i, j)) * sobel_template[1].at(i, j);
            }
        float g =  abs(Gx) + abs(Gy);
        if(g > 255)
            return 255;
        if(g < 0)
            return 0;
        return g;
    }
    // 7 利用高提升滤波算法增强灰度图像
    void grayHighPromote(int id, double k = 2){
       gray_image_process.push_back(original_gray_image[id] + k * highPromote_gray_mask[id]);
    }
    // 8 利用高提升滤波算法增彩色度图像
    void colorHighPromote(int id, double k = 2){
       color_image_process.push_back(original_color_image[id] + k * highPromote_color_mask[id]);
    }
    // 9 彩色图像滤波
    void colorSpatialFiltering(int pic_id, int size_id=0, int select=0){
        int size = filter_size[size_id];
        int m = size/2;
        
        cv::Mat image_process = cv::Mat::zeros(original_color_image[pic_id].size(), original_color_image[pic_id].type());
        cv::Mat image_grad = cv::Mat::zeros(original_color_image[pic_id].size(), original_color_image[pic_id].type());
        std::vector channels;
        cv::split(original_color_image[pic_id], channels);

        for(int i=m; i < original_color_image[pic_id].rows - m; i++)
            for(int j=m; j < original_color_image[pic_id].cols - m; j++){ 
                for(int k=0; k < 3; k++){
                    cv::Mat sub_matrix = channels[k](cv::Rect(j - m, i - m, size, size));
                    int grad, value;   
                    if(select == 0)
                        image_process.at(i, j)[k] = computerMeanResult(sub_matrix, size_id);
                    else if(select == 1)
                        image_process.at(i, j)[k] = computerGaussResult(sub_matrix, size_id);
                    else if(select == 2)
                        image_grad.at(i, j)[k] = computerLaplacianResult(sub_matrix);
                    else if(select == 3)
                        image_grad.at(i, j)[k] = computerRobertResult(sub_matrix);
                    else if(select == 4)
                        image_grad.at(i, j)[k] = computerSobelResult(sub_matrix);
                    else if(select == 5)
                        colorHighPromote(pic_id);
                    
                    if(select == 2 || select == 3 || select == 4){
                        grad = image_grad.at(i, j)[k];
                        value = sub_matrix.at(m, m);
                        if(grad + value > 255)
                            image_process.at(i, j)[k] = 255;
                        else
                            image_process.at(i, j)[k] = grad + value;
                    }
                }
            }
        color_image_process.push_back(image_process);
        if(select == 2)
            color_image_grad_laplacian.push_back(image_grad);
        else if(select == 3)
            color_image_grad_robert.push_back(image_grad);
        else if(select == 4)
            color_image_grad_sobel.push_back(image_grad);
    }
    // 10 测试灰度均值\高斯滤波器
    void test_MeanAndGaussGrayFilter(int filter_id){
        for(int i = 0; i < original_gray_image.size(); i++)
            for(int j = 0; j < filter_size.size(); j++){
                graySpatialFiltering(i, j, filter_id);
                std::cout<< pic_color[0] <<"-----"< filter_name;
    std::vector pic_color;

    std::vector original_color_image;
    std::vector original_gray_image;

    std::vector  color_image_process;
    std::vector  gray_image_process;

    // 梯度幅值图像
    std::vector  color_image_grad_robert;
    std::vector  gray_image_grad_robert;

    std::vector  color_image_grad_sobel;
    std::vector  gray_image_grad_sobel;

    std::vector  color_image_grad_laplacian;
    std::vector  gray_image_grad_laplacian;

    // 模板尺寸:3*3,5*5,9*9
    std::vector mean_template;
    std::vector gauss_template;
    std::vector gauss_template_sum;

    // 以下模板尺寸固定
    cv::Mat laplacian_template;
    std::vector robert_template;
    std::vector sobel_template;

    // 不同图片的 mask
    std::vector highPromote_gray_mask;
    std::vector highPromote_color_mask;

    std::vector filter_size;
    std::vector filter_size_string;
    int template_size;
};
   
int main(){
    std::vector path;
    path.push_back("/home/lyd/image_process/pic/lena.jpg");
    Experiment3 a(path);

    for(int i=0; i < 2; i++)
        a.test_MeanAndGaussGrayFilter(i);

    for(int i=2; i < 5; i++)
        a.test_LaplacianRobertSobelGrayFilter(i);
    a.test_HighPromoteGrayFilter();

    for(int i=0; i < 2; i++)
        a.test_MeanAndGaussColorFilter(i);

    for(int i=2; i < 5; i++)
        a.test_LaplacianRobertSobelColorFilter(i);
    a.test_HighPromoteColorFilter();
    return 1;
}

三、实验结果

1、 均值滤波(灰度图像):

数字图像处理基础实验(三):空域滤波_第5张图片

2、 高斯滤波(灰度图像):

数字图像处理基础实验(三):空域滤波_第6张图片

3、 Laplacian、Robert、Sobel 模板锐化(灰度图像):

Laplacian:
数字图像处理基础实验(三):空域滤波_第7张图片
Robert:
数字图像处理基础实验(三):空域滤波_第8张图片
Sobel:
数字图像处理基础实验(三):空域滤波_第9张图片

4、 高提升滤波算法增强(灰度图像):

数字图像处理基础实验(三):空域滤波_第10张图片

5、 均值滤波(彩色图像):

数字图像处理基础实验(三):空域滤波_第11张图片

6、 高斯滤波(灰度图像):

数字图像处理基础实验(三):空域滤波_第12张图片

7、 Laplacian、Robert、Sobel 模板锐化(彩色图像):

Laplacian:
数字图像处理基础实验(三):空域滤波_第13张图片
Robert:
数字图像处理基础实验(三):空域滤波_第14张图片
Sobel:
数字图像处理基础实验(三):空域滤波_第15张图片

你可能感兴趣的:(图像处理)