zoukankan      html  css  js  c++  java
  • OpenCV-C++ 自定义线性滤波

    这一节主要介绍卷积的概念,以及常见的算子,在最后简单介绍自定义卷积核,并利用filter2D这个API执行图像模糊

    卷积概念

    • 卷积是图像处理中一个操作,是kernel在图像的每个像素上的操作;
    • kernel本质上一个固定大小的矩阵数组,其中心点称为锚点;

    [H(x,y) = sum_{i=0}^{M_i-1}sum_{j=0}^{M_j-1}I(x+i-a_i, y+j-a_j)K(i, j) ]

    卷积核也被称为算子;

    下面的算子可以获取图像的边缘信息;不同的算子边缘方向信息不同;

    自定义卷积模糊

    实际上就是自定义卷积核;

    完整程序如下:

    #include <iostream>
    #include <opencv2/opencv.hpp>
    
    using namespace std;
    using namespace cv;
    
    int main(){
        // 读取图像
        Mat src = imread("/home/chen/dataset/lena.jpg");
        if (src.empty()){
            cout << "could not load image." << endl;
            return -1;
        }
        namedWindow("src", WINDOW_AUTOSIZE);
        imshow("src", src); 
    
        // Robert算子
        Mat kernelRobert_x = (Mat_<int>(2, 2) << 1, 0, 0, -1);
        Mat dstRobert_x;
        filter2D(src, dstRobert_x, -1, kernelRobert_x, Point(-1, -1), 0.0);
        namedWindow("dstRobert_x", WINDOW_AUTOSIZE);
        imshow("dstRobert_x", dstRobert_x);
    
        Mat kernelRobert_y = (Mat_<int>(2, 2) << 0, 1, -1, 0);
        Mat dstRobert_y;
        filter2D(src, dstRobert_y, -1, kernelRobert_y, Point(-1, -1), 0.0);
        namedWindow("dstRobert_y", WINDOW_AUTOSIZE);
        imshow("dstRobert_y", dstRobert_y);
    
        // Sobel算子
        Mat kernelSobel_x = (Mat_<int>(3, 3) << -1, 0, 1, -2, 0, 2, -1, 0, 1);
        Mat dstSobel_x;
        filter2D(src, dstSobel_x, -1, kernelSobel_x, Point(-1, -1), 0.0);
        namedWindow("dstSobel_x", WINDOW_AUTOSIZE);
        imshow("dstSobel_x", dstSobel_x);
    
        Mat kernelSobel_y = (Mat_<int>(3, 3) << -1, -2, -1, 0, 0, 0, 1, 2, 1);
        Mat dstSobel_y;
        filter2D(src, dstSobel_y, -1, kernelSobel_y, Point(-1, -1), 0.0);
        namedWindow("dstSobel_y", WINDOW_AUTOSIZE);
        imshow("dstSobel_y", dstSobel_y);
    
        // 拉普拉斯算子
        Mat kernelLa = (Mat_<int>(3, 3) << 0, -1, 0, -1, 4, -1, 0, -1, 0);
        Mat dstLa;
        filter2D(src, dstLa, -1, kernelLa, Point(-1, -1), 0.0);
        namedWindow("dstLa", WINDOW_AUTOSIZE);
        imshow("dstLa", dstLa);
        
        // 自定义卷积核
        int c = 0;
        int ksize = 0;
        int index = 0;
        Mat dst;
        namedWindow("dst", WINDOW_AUTOSIZE);
        while(true){
            c = waitKey(500);
            if ((char)c == 27){
                break;
            }
            ksize = 4 + (index % 5)*2 + 1;
            Mat kernel = Mat::ones(Size(ksize, ksize), CV_32F) / (float)(ksize*ksize);
            filter2D(src, dst, -1, kernel, Point(-1, -1), 0.0);
            imshow("dst", dst);
    
            index++;
    
        }
        waitKey(0);
    
        return 0;
    }
    


  • 相关阅读:
    C++函数模板的显示调用与隐式调用
    git显示颜色配置
    STL容器元素应满足的条件
    vector缩减容量
    PAT (Basic Level) Practise:1036. 跟奥巴马一起编程
    Core Java Volume I — 4.10. Class Design Hints
    Core Java Volume I — 4.7. Packages
    蓝牙(Profile)构成
    Android开发之Java必备基础
    主机控制器接口(HCI)
  • 原文地址:https://www.cnblogs.com/chenzhen0530/p/14655612.html
Copyright © 2011-2022 走看看