opencv 之自定义线性滤波

opencv 之自定义线性滤波

通过函数滤波

通过API进行滤波处理,滤波算法基本固定,灵活性不大,得到的图片效果只能在一定范围内进行动态调整。例如高斯模糊、均值模糊等利用的滤波算法


自定义滤波算法

图像处理中最基本的就是卷积处理,利用算子在图片不停的移动计算产生我们想要的目的图像。自定义滤波算法的首要做法就是定义算子(卷积核)

常见的算子:
Robert算子
[ 1 0 0 − 1 ] \left [ \begin{matrix} 1 & 0 \\ 0 & -1 \end{matrix} \right] [1001]
该算子左上角像素点减去右下角像素点,算子和为0,得出图片较暗,突出斜方向图片细节。
[ 0 1 − 1 0 ] \left [ \begin{matrix} 0 & 1 \\ -1 & 0 \end{matrix} \right] [0110]
该算子右上角像素点减去左下角像素点,算子和为0,得出图片较暗,突出斜方向图片细节。


Sobel算子
G x = [ − 1 0 1 − 2 0 2 − 1 0 1 ] Gx= \left [ \begin{matrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{matrix} \right] Gx=121000121
该算子左边像素点减去右边像素点,算子和为0,得出图片较暗,突出水平方向图片细节,本行所在算子乘以2倍,边缘信息更强。
G y = [ − 1 − 2 − 1 0 0 0 1 2 1 ] Gy= \left [ \begin{matrix} -1 & -2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1 \end{matrix} \right] Gy=101202101
该算子下边像素点减去上边像素点,算子和为0,得出图片较暗,突出垂直方向图片细节,本列所在算子乘以2倍,边缘信息更强。


拉普拉斯算子:
[ 0 − 1 0 − 1 4 − 1 0 − 1 0 ] \left [ \begin{matrix} 0 & -1 & 0 \\ -1 & 4 & -1 \\ 0 & -1 & 0 \end{matrix} \right] 010141010
该算子中央像素点的四倍值减去周围像素点,算子和为0,得出图片较暗,突出边缘信息,亮度大的更大,亮度小的更小。


代码

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

#define Pic_Path "/home/image/Pictures/" 
#define Pic_Name "model.jpg" 

using namespace std;
using namespace cv;
int main(int argc, char **argv)
{
    string pic = string(Pic_Path) + string(Pic_Name);
    cout << pic << endl;
	
    
    Mat src; 
    src = imread(pic.c_str());
    cv::namedWindow("原始图片",cv::WINDOW_AUTOSIZE);
    cv::imshow("原始图片",src);
  #if 0
    //正向 robert
    Mat dst_x;
    Mat kernel_x = (cv::Mat_<int>(2,2)<<1,0,0,-1);
    cv::filter2D(src,dst_x,src.depth(),kernel_x,cv::Point(-1,-1),0,0);
    cv::namedWindow("正斜罗伯特",cv::WINDOW_AUTOSIZE);
    cv::imshow("正斜罗伯特",dst_x);
    
    
    //逆向 robert
    Mat dst_y;
    Mat kernel_y = (cv::Mat_<int>(2,2)<<0,1,-1,0);
    cv::filter2D(src,dst_y,src.depth(),kernel_y,cv::Point(-1,-1),0,0);
    cv::namedWindow("反斜罗伯特",cv::WINDOW_AUTOSIZE);
    cv::imshow("反斜罗伯特",dst_y);
  
    Mat dst_level;
    Mat kernel_level = (cv::Mat_<int>(3,3)<<-1,0,1,-2,0,2,-1,0,1);
    cv::filter2D(src,dst_level,src.depth(),kernel_level,cv::Point(-1,-1),0,0);
    cv::namedWindow("水平索贝尔",cv::WINDOW_AUTOSIZE);
    cv::imshow("水平索贝尔",dst_level);

    
    Mat dst_ver;
    Mat kernel_ver = (cv::Mat_<int>(3,3)<<-1,-2,-1,0,0,0,1,2,1);
    cv::filter2D(src,dst_ver,src.depth(),kernel_ver,cv::Point(-1,-1),0,0);
    cv::namedWindow("垂直索贝尔",cv::WINDOW_AUTOSIZE);
    cv::imshow("垂直索贝尔",dst_ver);
   
    
    Mat dst_lapulas;
    Mat kernel_lapulas = (cv::Mat_<int>(3,3)<<0,-1,0,-1,4,-1,0,-1,0);
    cv::filter2D(src,dst_lapulas,src.depth(),kernel_lapulas,cv::Point(-1,-1),0,0);
    cv::namedWindow("拉普拉斯",cv::WINDOW_AUTOSIZE);
    cv::imshow("拉普拉斯",dst_lapulas);
     #endif
    Mat dst;
    int c = 0;
    int index = 0;
    int ksize = 0;
    while(true)
    {
            c=waitKey(500);    //500毫秒
            if(c==27)          //判断键值是否为esc
                break;
            ksize = 4+(index%5)*2+1;     //定义模糊卷积核尺寸
            
            //生成卷积核 1填充 并除以面积  进行归一化处理 实质是均值滤波 size不断变化而已
            Mat mykernel = Mat::ones(Size(ksize, ksize), CV_32F) / (float)(ksize * ksize);
            
            //填充
            filter2D(src, dst, -1, mykernel, Point(-1, -1));
            index++;
            imshow("自定义算子",dst);
    }
    
    waitKey(0);
    cv::destroyAllWindows();
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值