OpenCV图像处理之自定义滤波

目录
  • 1 空间滤波
    • 1.1 滤波过程
    • 1.2 相关和卷积
  • 2 OpenCV 函数
    • 2.1 filter2D 函数
    • 2.2 flip 函数
  • 3 代码示例
    • 3.1 偏导数
  • 参考资料
  • 总结

图像处理中,"空间域" 指的是图像平面,因此,空间滤波可定义为:在图像平面内对像素灰度值进行的滤波

1 空间滤波

1.1 滤波过程

如图,Filter 是一个 3x3 滤波核,当它从图像的左上角开始,逐个像素沿水平方向扫描,最后到右下角时,便会产生滤波后的图像

假设输入图像 $f(x, y)$,滤波后的图像为$g(x, y)$,则其中$g(2,2)$ 和 $g(4,4)$ 的计算过程如下:

上图中,以像素 (4,4) 为中心的 3x3 邻域,和滤波核的向量点乘之积,即为 g(4,4)

g(4,4) = 240*0.1111 + 183*0.1111 + 0*0.1111 + 250*0.1111 + 12*0.1111 + 87*0.1111 + 255*0.1111 + 1*0.1111 + 94*0.1111

= 26.6666 + 20.3333 + 0 + 27.7777 + 1.3333 + 9.6666 + 28.3333 + 0 + 10.4444

= 124.55

1.2 相关和卷积

空间滤波中,相关和卷积,是容易混淆的概念,定义如下:

-相关 (Correlation),和上述的滤波过程一样,即 滤波核 逐行扫描图像,并计算每个位置像素点积的过程

-卷积 (Convolution),和 "相关" 过程类似,但 滤波核 要先旋转 180°,然后再执行和 “相关” 一样的操作

(二维中的旋转 180°,等于滤波核沿一个坐标轴翻转,然后再沿另一个坐标轴翻转)

注意:如果滤波核是对称的,则对图像进行相关和卷积的结果是一致的

2 OpenCV 函数

2.1 filter2D 函数

在 OpenCV 中,可自定义滤波核,然后通过 filter2D() 来完成图像滤波

void filter2D(
     InputArray     src,              // 输入图像
     OutputArray    dst,              // 输出图像(大小和通道数,同 src)
     int            ddepth,           // 输出图像的 depth
     InputArray     kernel,           // 滤波核,准确地说,是相关核
     Point  anchor = Point(-1,-1),    // 锚点位置,滤波核尺寸为奇数时,不用指定,一般取默认值 Point(-1,-1);滤波核尺寸为偶数时,需指定锚点位置
     double             delta = 0,    // optional value added to the filtered pixels before storing them in dst
     int borderType = BORDER_DEFAULT  // 边界处理方法
 );

filter2D() 求的是相关,并非卷积,只有当滤波核对称时,filte2D() 才可视为卷积运算,其公式如下:

假定滤波核 kernel 大小为 3x3,以一个像素点 src(4,4) 为例,则有:

dst(4,4) = kernel(0,0)*src(4+0-1, 4+0-1) + kernel(0,1)*src(4+0-1, 4+1-1) + kernel(0,2)*src(4+0-1, 4+2-1)

+ kernel(1,0)*src(4+1-1, 4+0-1) + kernel(1,1)*src(4+1-1, 4+1-1) + kernel(1,2)*src(4+1-1, 4+2-1)

+ kernel(2,0)*src(4+2-1, 4+0-1) + kernel(2,1)*src(4+2-1, 4+1-1) + kernel(2,2)*src(4+2-1, 4+2-1)

滤波核与输入图像的卷积点乘,对应关系如下:

2.2 flip 函数

当滤波核不对称时,要得到真正的卷积运算,还需 flip() 函数来完成 kernel 的二维翻转

如果滤波核的大小为奇数,则 filter2D() 中的锚点位置可设为 Point(-1,-1),此时,默认滤波核的中心为锚点;如果滤波核的大小为偶数,则需要自定义锚点位置

OpenCV 中锚点位置的实现函数normalizeAnchor() 如下:

  void flip(
      InputArray  src,  // input array
      OutputArray dst,  // output array
      int    flipCode   // 0, flip around x-axis; positive value, flip around y-axis; negative value, flip around both axes.
  );

3 代码示例

3.1 偏导数

自定义滤波核,利用 filter2D() 函数,实现图像的一阶和二阶偏导运算

1) 一阶偏导

图像在 x 和 y 方向的一阶偏导如下:

对应滤波核为

2) 二阶偏导

同样,在 x 和 y 方向的二阶偏导如下:

对应滤波核为

3.2 代码示例

#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"

using namespace cv;

int main()
{
    // 读取图像
    Mat src = imread("fangtze.jpg", IMREAD_GRAYSCALE);
    if (src.empty()) {
        return -1;
    }

    Mat kx = (Mat_<float>(1, 2) << -1, 1);  // 1行2列的 dx 滤波核
    Mat ky = (Mat_<float>(2, 1) << -1, 1);  // 2行1列的 dy 滤波核

    Mat kxx = (Mat_<float>(1, 3) << 1, -2, 1);     // 1行3列的 dxx 滤波核
    Mat kyy = (Mat_<float>(3, 1) << 1, -2, 1);     // 3行1列的 dyy 滤波核
    Mat kxy = (Mat_<float>(2, 2) << 1, -1, -1, 1); // 2行2列的 dxy 滤波核

    // 一阶偏导
    Mat dx, dy;
    filter2D(src, dx, CV_32FC1, kx);
    filter2D(src, dy, CV_32FC1, ky);

    // 二阶偏导
    Mat dxx, dyy, dxy;
    filter2D(src, dxx, CV_32FC1, kxx);
    filter2D(src, dyy, CV_32FC1, kyy);
    filter2D(src, dxy, CV_32FC1, kxy);

    // 显示图像
    imshow("dx", dx);

    waitKey();
}

输出的偏导图像如下,第一行从左到右:原图 - dx - dy;第二行从左至右:dxy - dxx -dyy

参考资料

OpenCV Tutorials / imgproc module /Making your own linear filters

Gonzalez,《Digital Image Processing》4th ch3 Intesity Transformations and Spatial Filtering

CS425 Lab: Intensity Transformations and Spatial Filtering

总结

到此这篇关于OpenCV图像处理之自定义滤波的文章就介绍到这了,更多相关OpenCV自定义滤波内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • opencv+python实现均值滤波

    本文实例为大家分享了opencv+python实现均值滤波的具体代码,供大家参考,具体内容如下 原理 均值滤波其实就是对目标像素及周边像素取平均值后再填回目标像素来实现滤波目的的方法,当滤波核的大小是3×3 3\times 33×3时,则取其自身和周围8个像素值的均值来代替当前像素值. 均值滤波也可以看成滤波核的值均为 1 的滤波. 优点:算法简单,计算速度快: 缺点:降低噪声的同时使图像产生模糊,特别是景物的边缘和细节部分. 代码 import cv2 as cv import numpy a

  • OpenCV实现可分离滤波

    自定义滤波 无论是图像卷积还是滤波,在原图像上移动滤波器的过程中每一次的计算结果都不会影响到后面过程的计算结果,因此图像滤波是一个并行的算法,在可以提供并行计算的处理器中可以极大的加快图像滤波的处理速度. 图像滤波还具有可分离性 先对X(Y)方向滤波,再对Y(X)方向滤波的结果与将两个方向的滤波器联合后整体滤波的结果相同.两个方向的滤波器的联合就是将两个方向的滤波器相乘,得到一个矩形的滤波器 void filter2D( InputArray src, OutputArray dst, int

  • opencv 图像滤波(均值,方框,高斯,中值)

    为什么要使用滤波 消除图像中的噪声成分叫作图像的平滑化或滤波操作.信号或图像的能量大部分集中在幅度谱的低频和中频段是很常见的,而在较高频段,感兴趣的信息经常被噪声淹没.因此一个能降低高频成分幅度的滤波器就能够减弱噪声的影响. 如下图,左图带有椒盐噪声,右图为使用中值滤波处理后的图片. 图像滤波的目的有两个:一是抽出对象的特征作为图像识别的特征模式;另一个是为适应图像处理的要求,消除图像数字化时所混入的噪声. python +opencv讲解 均值滤波 含义 如图:如果我们想对红色点进行处理,则它

  • python-opencv 中值滤波{cv2.medianBlur(src, ksize)}的用法

    python-opencv 中值滤波{cv2.medianBlur(src, ksize)} 中值滤波将图像的每个像素用邻域 (以当前像素为中心的正方形区域)像素的 中值 代替 .与邻域平均法类似,但计算的是中值 #用中值法 for y in xrange(1,myh-1): for x in xrange(1,myw-1): lbimg[y,x]=np.median(tmpimg[y-1:y+2,x-1:x+2] 下面调用opencv的函数 # -*- coding: utf-8 -*- #c

  • opencv3/C++图像滤波实现方式

    图像滤波在opencv中可以有多种实现形式 自定义滤波 如使用3×3的掩模: 对图像进行处理. 使用函数filter2D()实现 #include<opencv2/opencv.hpp> using namespace cv; int main() { //函数调用filter2D功能 Mat src,dst; src = imread("E:/image/image/daibola.jpg"); if(!src.data) { printf("can not l

  • opencv实现轮廓高斯滤波平滑

    本文实例为大家分享了opencv实现轮廓高斯滤波平滑的具体代码,供大家参考,具体内容如下 一个小测试的题目: 在图像上点选,找到与点选处相邻的颜色相近的点集合,对该点集合提取轮廓,对该点集合轮廓平滑处理,显示处理结果. #include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; //************************************ //

  • 理想高通滤波实现Python opencv示例

    理想高通滤波实现 python opencv import numpy as np import cv2 from matplotlib import pyplot as plt plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus'] = False I = cv2.imread('capture3.png') cv2.imshow('original',I) (r,g,b) = cv2.spli

  • Java+opencv3.2.0之scharr滤波器

    在opencv中scharr滤波器是配合sobel算子的运算而存在的.当sobel内核为3时,结果可能会产生比较明显的误差,针对这一问题,Opencv提供了scharr函数.该函数只针对大小为3的核,并且运算速率和sobel函数一样快,结果更加精确,但抗噪性不如sobel函数. 使用scharr滤波器计算x或y方向的图像差分,它的参数变量和sobel一样. 函数:Imgproc.Scharr(Mat src, Mat dst, int ddepth, int dx, int dy, double

  • python+opencv实现高斯平滑滤波

    功能: 创建两个滑动条来分别控制高斯核的size和σσ的大小,这个程序是在阈值分割的那个程序上改动的.阈值分割程序在这 注意:由于σ=0σ=0时,opencv会根据窗口大小计算出σσ,所以,从0滑动σσ的滑动条时,会出现先边清晰又变模糊的现象 python+opencv实现阈值分割 python+opencv实现霍夫变换检测直线 (2016-5-10)到OpenCV-Python Tutorials's documentation!可以下载 代码: # -*- coding: utf-8 -*-

  • OpenCV-Python实现图像梯度与Sobel滤波器

    图像梯度 图像梯度计算的是图像变化的速度.对于图像的边缘部分,其灰度值变化较大,梯度值也较大:相反,对于图像中比较平滑的部分,其灰度值变化较小,相应的梯度值也较小.一般情况下,图像的梯度计算是图像的边缘信息. 其实梯度就是导数,但是图像梯度一般通过计算像素值的差来得到梯度的近似值,也可以说是近似导数.该导数可以用微积分来表示. 在微积分中,一维函数的一阶微分的基本定义是这样的: 而图像是一个二维函数f(x,y),其微分当然就是偏微分.因此有: 因为图像是一个离散的二维函数,ϵ不能无限小,我们的图

随机推荐