opencv:图像卷积

Posted wbyixx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了opencv:图像卷积相关的知识,希望对你有一定的参考价值。

卷积基本概念

技术图片

C++代码实现卷积

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

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
    Mat src = imread("f:/images/lena.jpg");
    if (src.empty())
    {
        printf("Could not find the image!
");
        return -1;
    }

    namedWindow("input", WINDOW_AUTOSIZE);
    imshow("input", src);

    int h = src.rows;
    int w = src.cols;
    Mat result = src.clone();
    for (int row = 1; row < h - 1; row++) {
        for (int col = 1; col < w - 1; col++) {
            // 3x3卷积核
            int sb =
                src.at<Vec3b>(row, col)[0] +
                src.at<Vec3b>(row - 1, col - 1)[0] +
                src.at<Vec3b>(row - 1, col)[0] +
                src.at<Vec3b>(row - 1, col + 1)[0] +
                src.at<Vec3b>(row, col - 1)[0] +
                src.at<Vec3b>(row, col + 1)[0] +
                src.at<Vec3b>(row + 1, col - 1)[0] +
                src.at<Vec3b>(row + 1, col)[0] +
                src.at<Vec3b>(row + 1, col + 1)[0];
            int sg =
                src.at<Vec3b>(row, col)[1] +
                src.at<Vec3b>(row - 1, col - 1)[1] +
                src.at<Vec3b>(row - 1, col)[1] +
                src.at<Vec3b>(row - 1, col + 1)[1] +
                src.at<Vec3b>(row, col - 1)[1] +
                src.at<Vec3b>(row, col + 1)[1] +
                src.at<Vec3b>(row + 1, col - 1)[1] +
                src.at<Vec3b>(row + 1, col)[1] +
                src.at<Vec3b>(row + 1, col + 1)[1];
            int sr =
                src.at<Vec3b>(row, col)[2] +
                src.at<Vec3b>(row - 1, col - 1)[2] +
                src.at<Vec3b>(row - 1, col)[2] +
                src.at<Vec3b>(row - 1, col + 1)[2] +
                src.at<Vec3b>(row, col - 1)[2] +
                src.at<Vec3b>(row, col + 1)[2] +
                src.at<Vec3b>(row + 1, col - 1)[2] +
                src.at<Vec3b>(row + 1, col)[2] +
                src.at<Vec3b>(row + 1, col + 1)[2];
            result.at<Vec3b>(row, col)[0] = sb / 9;
            result.at<Vec3b>(row, col)[1] = sg / 9;
            result.at<Vec3b>(row, col)[2] = sr / 9;
        }
    }

    imshow("result", result);

    waitKey(0);
    destroyAllWindows();

    return 0;
}

blur函数

    Mat dst;
    /*
       blur参数:
            src:输入
            dst:输出
            ksize:卷积核大小
            anchor:锚定点,默认(-1,-1),中心位置(默认是卷积核大小除以2的位置)
            borderType:边缘处理方式,默认为BORDER_DEFAULT=4
    */
    blur(src, dst, Size(3, 3), Point(-1, -1), BORDER_DEFAULT);
    imshow("dst", dst);

卷积边缘处理

卷积处理的时候,边缘像素的填充方法:
技术图片

边缘在卷积开始前就填充好(知道卷积核大小之后)

技术图片

边缘填充 copyMakeBorder

    // 边缘填充 copyMakeBorder
    int border = 8;
    Mat border_m;
    copyMakeBorder(src, border_m, border, border, border, border, BORDER_WRAP, Scalar(0, 0, 255));
    imshow("border fill demo", border_m);

以上是关于opencv:图像卷积的主要内容,如果未能解决你的问题,请参考以下文章

opencv 4 -- 图像平滑与滤波--核心卷积操作

如何标记从卷积神经网络的分割算法生成的图像片段?

OpenCV 卷积边缘处理问题

OpenCV 完整例程54. OpenCV 实现图像二维卷积

OpenCV 完整例程52. 图像的相关与卷积运算

OpenCV 完整例程53. Scipy 实现图像二维卷积