图像滤波的分类和实现源码

一、噪声的种类和生成

1.1椒盐噪声

椒盐噪声又称作脉冲噪声,它会随机改变图像中的像素值,是由相机成像、图像传输、解码处理等过程产生的黑白相间的亮暗点噪声,其样子就像在图像上随机地撒上一些盐粒和黑椒粒,因此被称为椒盐噪声

在图像中添加椒盐噪声如下:

#include <opencv2/opencv.hpp>

#include <iostream>

using namespace cv;

using namespace std;

void saltAndPepper(cv::Mat image, int n)

{

    for (int k = 0; k < n / 2; k++)

    {

        int i, j;

        i = std::rand() % image.cols;

        j = std::rand() % image.rows;

        int write_black = std::rand() % 2;

        if (write_black == 0)

        {

            if (image.type() == CV_8UC1)

            {

                image.at<uchar>(j, i) = 255;

            }

            else if (image.type() == CV_8UC3)

            {

                image.at<Vec3b>(j, i)[0] = 255;

                image.at<Vec3b>(j, i)[1] = 255;

                image.at<Vec3b>(j, i)[2] = 255;

            }

        }

        else

        {

            if (image.type() == CV_8UC1)

            {

                image.at<uchar>(j, i) =0;

            }

            else if (image.type() == CV_8UC3)

            {

                image.at<Vec3b>(j, i)[0] = 0;

                image.at<Vec3b>(j, i)[1] = 0;

                image.at<Vec3b>(j, i)[2] = 0;

            }

        }

    }

}

int main()

{

    Mat lena = imread("D://lena.png");//自已定义导入的图像

    Mat equalLena = imread("D://equalLena.png", IMREAD_ANYDEPTH);

    if (lena.empty() || equalLena.empty())

    {

        cout << "请确认是否正确" << endl;

        return -1;

    }

    imshow("lena原图",lena);

    imshow("equalLena原图", equalLena);

    saltAndPepper(lena, 10000);

    saltAndPepper(equalLena, 10000);

    imshow("lena添加椒盐噪声",lena);

    imshow("equalLena添加椒盐噪声", equalLena);

    waitKey(0);

    return 0;

}

1.2高斯噪声

高斯噪声是指噪声分布的概率密度函数服从高斯分布(正态分布)的一类噪声,其产生的主要原因是相机在拍摄时视场较暗且亮度不均匀。相机长时间工作使得温度过高同样会引起高斯噪声,另外,电路元器件自身噪声和互相影响也是造成高斯噪声的重要原因之一

在图像中添加高斯噪声

#include <opencv2/opencv.hpp>

#include <iostream>

using namespace cv;

using namespace std;

void GaussianNoise(Mat imag1,Mat imag2)

{

      Mat lena_noise = Mat::zeros(imag1.rows, imag1.cols, imag1.type());

    Mat equalLena_noise = Mat::zeros(imag1.rows, imag1.cols, imag2.type())

    RNG rng;

    rng.fill(lena_noise, RNG::NORMAL, 10, 20);

    rng.fill(equalLena_noise, RNG::NORMAL, 15, 30);

    imshow("三通道高斯噪声", lena_noise);

    imshow("单通道高斯噪声", equalLena_noise);

    imag1 = imag1 + lena_noise;

    imag2 = imag2 + equalLena_noise;

    imshow("lena添加高斯噪声", imag1);

    imshow("equalLen高斯噪声", imag2);

}

int main()

{

    Mat lena = imread("D://lena.png");

    Mat equalLena = imread("D://equalLena.png", IMREAD_ANYDEPTH);

    if (lena.empty() || equalLena.empty())

    {

        cout << "请确认是否正确" << endl;

        return -1;

    }

    imshow("lena原图",lena);

    imshow("equalLena原图", equalLena);

    GaussianNoise(lena,equalLena);

    waitKey(0);

    return 0;

}

二、图像的线性滤波

2.1图像均值滤波

int main()

{

    Mat lena = imread("D://lena.png", IMREAD_ANYDEPTH);

    Mat lena_salt = imread("D://lena_salt.png", IMREAD_ANYDEPTH);

    Mat lena_guass = imread("D://lena_guass.png", IMREAD_ANYDEPTH);

    if (lena.empty() || lena_salt.empty() || lena_guass.empty())

    {

        cout << "could not load in ...." << endl;

        return -1;

    }

    Mat result_3, result_9;

    Mat result_3guass, result_9guass;

    Mat result_3salt, result_9salt;

    blur(lena, result_3, Size(3, 3));

    blur(lena, result_9, Size(9, 9));

    blur(lena_guass, result_3guass, Size(3, 3));

    blur(lena_guass, result_9guass, Size(9, 9));

    blur(lena_salt , result_3salt, Size(3, 3));

    blur(lena_salt, result_9salt, Size(9, 9));

    imshow("lena", lena);

    imshow("result_3", result_3);

    imshow("result_9", result_9);

    imshow("lena_guass", lena_guass);

    imshow("result_3guass", result_3guass);

    imshow("result_9guass", result_9guass);

     

    imshow("lena_salt", lena_salt);

    imshow("result_3salt", result_3salt);

    imshow("result_9salt", result_9salt);

    waitKey(0);

    return 0;

}

2.2图像方框滤波

int main()

{

   

    Mat lena = imread("D://lena.png");

    if (lena.empty())

    {

        cout << "could not load ...." << endl;

        return -1;

    }

    namedWindow("input", WINDOW_AUTOSIZE);

    imshow("input", lena);

    Mat lena_32F;

    lena.convertTo(lena_32F, CV_32F, 1.0 / 255);

    Mat resultNorm,lena_32fsqr;

    boxFilter(lena, resultNorm, -1, Size(3, 3), Point(-1, -1), false);

    sqrBoxFilter(lena_32F, lena_32fsqr, -1, Size(3, 3), Point(-1, -1), true);

    imshow("resultNorm", resultNorm);

    imshow("lena_32fsqr", lena_32fsqr);

    waitKey(0);

    return 0;

}

2.3图像高斯滤波

int main()

{

    Mat lena = imread("D://lena.png");

    Mat lena_salt = imread("D://lena_salt.png");

    Mat lena_guass = imread("D://lena_guass.png");

    if (lena.empty() || lena_salt.empty() || lena_guass.empty())

    {

        cout << "could not load in ...." << endl;

        return -1;

    }

    Mat result_3, result_9;

    Mat result_3guass, result_9guass;

    Mat result_3salt, result_9salt;

    GaussianBlur(lena, result_3, Size(3, 3),10,20);

    GaussianBlur(lena, result_9, Size(9, 9),10,20);

    GaussianBlur(lena_guass, result_3guass, Size(3, 3), 10, 20);

    GaussianBlur(lena_guass, result_9guass, Size(9, 9), 10, 20);

    GaussianBlur(lena_salt , result_3salt, Size(3, 3), 10, 20);

    GaussianBlur(lena_salt, result_9salt, Size(9, 9), 10, 20);

    imshow("lena", lena);

    imshow("result_3", result_3);

    imshow("result_9", result_9);

    imshow("lena_guass", lena_guass);

    imshow("result_3guass", result_3guass);

    imshow("result_9guass", result_9guass);

     

    imshow("lena_salt", lena_salt);

    imshow("result_3salt", result_3salt);

    imshow("result_9salt", result_9salt);

    waitKey(0);

    return 0;

}

三、图像的非线性滤波

3.1图像中值滤波

using namespace cv;

using namespace std;

int main()

{

     Mat lena = imread("D://lena_salt.png");

    if (lena.empty())

    {

        cout << "could not load ...." << endl;

        return -1;

    }

    namedWindow("input", WINDOW_AUTOSIZE);

    imshow("input", lena);

    Mat img3;

    medianBlur(lena, img3, 3);

    imshow("img3", img3);

    waitKey(0);

    return 0;

}

3.2图像双边滤波

int main()

{

    Mat img1 = imread("D://lena.png");

    Mat img2 = imread("D://test.png");

    if (img1.empty()||img2.empty())

    {

        cout << "could not load ...." << endl;

        return -1;

    }

    Mat result1, result2, result3, result4;

    //验证不同滤波器直径的滤波效果

    bilateralFilter(img1, result1, 9, 50, 25 / 2);

    bilateralFilter(img1, result2, 25, 50, 25 / 2);

    //验证不同标准差值的滤波效果

    bilateralFilter(img2, result3, 9, 9, 9);

    bilateralFilter(img2, result4, 9, 200, 200);

   

    //显示原图

    imshow("img1", img1);

    imshow("img2", img2);

    //不同滤波器直径效果

    imshow("result1", result1);

    imshow("result2", result2);

    //不同标准插值效果

    imshow("result3", result3);

    imshow("result4", result4);

    waitKey(0);

    return 0;

}

四、图像的边缘检测

int main()

{

    Mat kernel1 = (Mat_<float>(1, 2) << 1, -1);

    Mat kernel2 = (Mat_<float>(1, 3) << 1, 0,-1);

    Mat kernel3 = (Mat_<float>(3, 1) << 1, 0,-1);

    Mat kernelXY = (Mat_<float>(2, 2) << 1,0,0,-1);

    Mat kernelYX = (Mat_<float>(2, 2) << 0,-1,1,0);

    Mat img = imread("D://test.png");

    if (img.empty())

    {

        cout << "could not load ...." << endl;

        return -1;

    }

    Mat result1, result2, result3, result4, result5, result6;

    //检测图像边缘,以[1,-1]开始

    filter2D(img, result1, CV_16S, kernel1);

    convertScaleAbs(result1, result1);

    //以[1,0,-1]检测水平方向边缘

    filter2D(img, result2, CV_16S, kernel2);

    convertScaleAbs(result2, result2);

   //以[1,0,-1]检测垂直方向边缘

    filter2D(img, result3, CV_16S, kernel3);

    convertScaleAbs(result3, result3)

    //整幅图像的边缘

    result6 = result2 + result3;

    //检测由左上到右下方向边缘

    filter2D(img, result4, CV_16S, kernelXY);

    convertScaleAbs(result4, result4);

    //检测由右上到左下方向边缘

    filter2D(img, result5, CV_16S, kernelYX);

    convertScaleAbs(result5, result5);

    namedWindow("img", WINDOW_FREERATIO);

    imshow("img", img);

    imshow("result1", result1);

    imshow("result2", result2);

    imshow("result3", result3);

    imshow("result4", result4);

    imshow("result5", result5);

    imshow("result6", result6);

    waitKey(0);

    return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值