高斯滤波 c++实现

高斯滤波

To smooth the image, a Gaussian filter kernel is convolved with the image.

高斯滤波的实质就是用高斯核对图片进行卷积操作

算法较为简单,在复杂度运行效率方面还有很多需要改进的

从RGB色转为灰度色算法(转) – carekee – 博客园 (cnblogs.com)

彩图转灰度图


Mat gray(Mat& image) {
    Mat dst = Mat::zeros(image.size(), CV_8UC1);
    for (int i = 0; i < image.rows; i++) {
        for (int j = 0; j < image.cols; j++)
        {
            dst.at<uchar>(i, j) = 0.114*image.at<vec3b>(i, j)[0] + 0.587*image.at<vec3b>(i, j)[1] + 0.299*image.at<vec3b>(i, j)[2];
            //&#x5C06;&#x5F69;&#x8272;&#x56FE;&#x50CF;&#x7684;&#x4E09;&#x4E2A;&#x901A;&#x9053;&#x7684;&#x503C;&#xFF0C;&#x6BCF;&#x4E2A;&#x4E58;&#x4EE5;&#x5BF9;&#x5E94;&#x7684;&#x6BD4;&#x4F8B;&#xFF0C;&#x8FDB;&#x884C;&#x76F8;&#x52A0;&#xFF0C;opencv B G R
        }
    }
    return dst;
}</vec3b></vec3b></vec3b></uchar>

填充 padding

padding 的选择,5乘5(padding = 2),3乘3(padding = 1)

高斯滤波 c++实现

如上图,要是右上角的小正方形位于卷积核的中心正方形处,就需要填充一层空的矩形

因此可以推至5乘5的卷积核

我选用的是3*3 的卷积,故填充为1

Mat Padding(Mat& image,int padNum = 1) {
    Mat dst = Mat::zeros(image.size[0]+2*padNum, image.size[1] + 2*padNum, CV_8UC1);
    cout << "dst size" << dst.size << endl;
    for (int i = 0; i < image.rows; i++) {
        for (int j = 0; j < image.cols; j++)
        {
            dst.at<uchar>(i + 1, j + 1) = image.at<uchar>(i, j);
        }
    }

    return  dst;

}</uchar></uchar>

卷积

高斯滤波 c++实现

高斯滤波 c++实现

同样 3*3 的卷积核在主函数里

Mat  convolution(Mat &image, Mat &kernal) {

    Mat dst = Mat ::zeros(image.size(),image.type());
    // padding &#x586B;&#x5145;
    Mat test = Padding(image);// 6*6 &#x586B;&#x5145;&#x4E00;&#x5C42; &#x53D8; 8*8

    //cout << "conv test" << endl;
    for (int i = 0; i < image.rows; i++) {
        for (int j = 0; j < image.cols; j++)
        {
            double pixSum = 0;

            //&#x8FD9;&#x4E2A;&#x50CF;&#x7D20;&#x5C31;&#x5728;&#x5377;&#x79EF;&#x6838;&#x7684;&#x4E2D;&#x5FC3;&#x5904;
            for (int k = 0; k < kernal.rows; k++) {
                for (int l = 0; l < kernal.cols; l++) {
                    //cout << kernal.at<double>(k, l) << endl;
                    //cout << double(test.at<uchar>(k + i, l + j)) << endl;
                    pixSum += kernal.at<double>(k, l) * double(test.at<uchar>(k + i, l + j));
                }
            }
            dst.at<uchar>(i, j) = uchar(pixSum);

        }
    }

    return dst;

}</uchar></uchar></double></uchar></double>

因为使用的是3X3 的卷积核,所以模糊的不明显

高斯滤波 c++实现

高斯滤波 c++实现

代码

#include<opencv2 opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;

Mat gray(Mat& image) {
    Mat dst = Mat::zeros(image.size(), CV_8UC1);
    for (int i = 0; i < image.rows; i++) {
        for (int j = 0; j < image.cols; j++)
        {
            dst.at<uchar>(i, j) = 0.114*image.at<vec3b>(i, j)[0] + 0.587*image.at<vec3b>(i, j)[1] + 0.299*image.at<vec3b>(i, j)[2];
            //&#x5C06;&#x5F69;&#x8272;&#x56FE;&#x50CF;&#x7684;&#x4E09;&#x4E2A;&#x901A;&#x9053;&#x7684;&#x503C;&#xFF0C;&#x6BCF;&#x4E2A;&#x4E58;&#x4EE5;&#x5BF9;&#x5E94;&#x7684;&#x6BD4;&#x4F8B;&#xFF0C;&#x8FDB;&#x884C;&#x76F8;&#x52A0;&#xFF0C;opencv B G R
        }
    }
    return dst;
}

Mat Padding(Mat& image,int padNum = 1) {
    Mat dst = Mat::zeros(image.size[0]+2*padNum, image.size[1] + 2*padNum, CV_8UC1);
    cout << "dst size" << dst.size << endl;
    for (int i = 0; i < image.rows; i++) {
        for (int j = 0; j < image.cols; j++)
        {
            dst.at<uchar>(i + 1, j + 1) = image.at<uchar>(i, j);
        }
    }

    return  dst;

}

Mat  convolution(Mat &image, Mat &kernal) {

    Mat dst = Mat ::zeros(image.size(),image.type());
    // padding &#x586B;&#x5145;
    Mat test = Padding(image);// 6*6 &#x586B;&#x5145;&#x4E00;&#x5C42; &#x53D8; 8*8

    //cout << "conv test" << endl;
    for (int i = 0; i < image.rows; i++) {
        for (int j = 0; j < image.cols; j++)
        {
            double pixSum = 0;

            //&#x8FD9;&#x4E2A;&#x50CF;&#x7D20;&#x5C31;&#x5728;&#x5377;&#x79EF;&#x6838;&#x7684;&#x4E2D;&#x5FC3;&#x5904;
            for (int k = 0; k < kernal.rows; k++) {
                for (int l = 0; l < kernal.cols; l++) {
                    //cout << kernal.at<double>(k, l) << endl;
                    //cout << double(test.at<uchar>(k + i, l + j)) << endl;
                    pixSum += kernal.at<double>(k, l) * double(test.at<uchar>(k + i, l + j));
                }
            }
            dst.at<uchar>(i, j) = uchar(pixSum);

        }
    }

    return dst;

}

/*
Mat GaussianBlur(Mat& image){
    //&#x5B9E;&#x8D28;&#x5C31;&#x662F;&#x7528;&#x9AD8;&#x65AF;&#x6838;&#x5B9E;&#x73B0;&#x4E00;&#x4E2A;&#x5377;&#x79EF;&#x64CD;&#x4F5C;

}
*/

int main(int argc, char* argv[])
{
    //load pics

    string imgPath = "E:\\&#x7814;&#x7A76;&#x751F;\\&#x6570;&#x5B57;&#x56FE;&#x50CF;&#x5904;&#x7406;\\c++\\&#x5B57;&#x7B26;&#x8BC6;&#x522B;\\Project1\\beauty.jpg";
    Mat srcImg = imread(imgPath);//RGB,JPG,PNG,TIFF&#x683C;&#x5F0F;

    if (srcImg.empty()) {
        cout << "can't load pic" << endl;
        exit(-1);
    }
    //show pics
    //imshow("air plane",srcImg);

    //&#x8F6C;&#x7070;&#x5EA6;&#x5316;
    Mat image_gray = gray(srcImg);
    imshow("gray img", image_gray);

    //3*3 &#x7684;&#x5377;&#x79EF;&#x6838; &#xFF0C; padding = 1
    Mat kernal = (Mat_<double>(3, 3) << 1, 2, 1,2, 4, 2,1,2, 1);

    kernal = kernal / 16;

    //&#x5377;&#x79EF;&#x5B9E;&#x73B0;&#x9AD8;&#x65AF;&#x6EE4;&#x6CE2;
    Mat imgconv = convolution(image_gray, kernal);
    imshow("img conv", imgconv);
    waitKey(0);//wait function

    return 0;
}</double></uchar></uchar></double></uchar></double></uchar></uchar></vec3b></vec3b></vec3b></uchar></iostream></opencv2>

与opencv对比

高斯滤波 c++实现

高斯滤波 c++实现

模糊效果好像差不多

int main(int argc, char* argv[])
{
    //load pics

    string imgPath = "E:\\&#x7814;&#x7A76;&#x751F;\\&#x6570;&#x5B57;&#x56FE;&#x50CF;&#x5904;&#x7406;\\c++\\&#x5B57;&#x7B26;&#x8BC6;&#x522B;\\Project1\\beauty.jpg";
    Mat srcImg = imread(imgPath,0);//RGB,JPG,PNG,TIFF&#x683C;&#x5F0F;

    if (srcImg.empty()) {
        cout << "can't load pic" << endl;
        exit(-1);
    }
    //show pics
    imshow("src",srcImg);
    Mat  dst;
    GaussianBlur(srcImg,dst,Size(3,3),0,0);
    imshow("opencv gsblur", dst);

    waitKey(0);//wait function

    return 0;
}

Original: https://blog.csdn.net/weixin_54721788/article/details/123593829
Author: zoodD顶真
Title: 高斯滤波 c++实现

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/701122/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球