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;
    }
    


  • 相关阅读:
    部署LVS-DR(直接路由)群集
    快速了解LVS负载均衡群集及部署LVS-NAT(地址转换)群集
    MySQL一些常用的高级SQL语句
    MySQL高可用群集MHA部署及故障测试
    MySQL的主从复制与读写分离
    你知道数据库中数据丢失的严重性吗,快来学习数据库的备份与恢复!!
    快速掌握mysql索引、事务与存储引擎知识以及使用命令
    MySQL数据库常用的一些管理操作
    带大家简单了解MySQL数据库
    剑指offer63-数据流中的中位数**
  • 原文地址:https://www.cnblogs.com/chenzhen0530/p/14655612.html
Copyright © 2011-2022 走看看