Convolution 卷积<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
卷积是本章所讨论的很多转换的基础。抽象的说,这个术语意味着我们对图像的每一个部分所做的操作。从这个意义上讲,我们在第五章所看到的许多操作可以被理解成普通卷积的特殊情况。一个特殊的卷积所实现的功能是由所用的卷积核的形式决定的。这个核本质上是一个大小固定,由数值参数构成的数组,数组的标定点通常位于数组的中心。数组的大小被称为核支撑。单就技术而言,核支撑实际上仅仅由核数组的非零部分组成。
图6-1描述了以数组中心为定标点的3×3卷积核。若要计算一个特定点的卷积值,首先将核的标定点定位到图像的第一个像素点,核的其余元素覆盖图像中其相对应的局部像素点。对于每一个核点,我们可以得到这个点的核的值以及图像中相应图像点的值。将这些值相乘并求和,并将这个结果放置在与输入图像标定点所相对应的位置。 通过在整个图像上扫描卷积核,对图像的每个点重复此操作。
图6-1. Sobel 微分的3×3核,可以注意到标定点在核的中心
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="图片_x0020_1" style="VISIBILITY: visible; WIDTH: 119.25pt; HEIGHT: 119.25pt" alt="getfile?item=NjNmNTZnOWRpLzkvdGFwZ203ZWNzODByLzE1MTBpczZnLm01cG4vZ2kx" type="#_x0000_t75" o:spid="_x0000_i1025"><imagedata o:title="getfile?item=NjNmNTZnOWRpLzkvdGFwZ203ZWNzODByLzE1MTBpczZnLm01cG4vZ2kx" src="file:///D:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msoclip1/02/clip_image001.png"></imagedata><textbox style="mso-rotate-with-shape: t"></textbox></shape>
当然我们可以用方程来表示这个过程,如果我们定义图像为I(x,y),核为G(i,j) (其中 0 < i < Mi –1 和 0 < j < Mj –1),标定点位于相应核的(ai,aj)坐标上,则卷积H(x,y)定义为:
<shape id="图片_x0020_2" style="VISIBILITY: visible; WIDTH: 315.75pt; HEIGHT: 39.75pt" alt="getfile?item=NjNmNTZnOWRpLzkvdGFwZ203ZWNzODByLzE1MTBpczZnLm03cG4vZ2kx" type="#_x0000_t75" o:spid="_x0000_i1026"><imagedata o:title="getfile?item=NjNmNTZnOWRpLzkvdGFwZ203ZWNzODByLzE1MTBpczZnLm03cG4vZ2kx" src="file:///D:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msoclip1/02/clip_image003.png"></imagedata><textbox style="mso-rotate-with-shape: t"></textbox></shape>
注意到运算次数,至少第一眼看似乎等于图像的像素数乘以核的像素数[63]。这需要很大的计算量并且也不是仅仅用其中的一些for循环以及许多指针再分配就能做的事情。类似这种情况,你最好让OpenCV来做这个工作以利用OpenCV已编程实现的最优方法。其函数为cvFilter2D ();
[63]这里我们说“第一眼看”的意思是在频域中也可能进行卷积操作。在这种情况下,对于一个N×N的图像和一个M×M的核(N>M),计算复杂度将会按照N2 log(N)成比例增加,而不是在空间域内预计的N2M2。这是因为频域的计算量同核的大小是相对独立的,对于大核更加有效。OpenCV会根据核的大小自动决定是否做频域内的卷积。
void cvFilter2D(
const CvArr* src,
CvArr* dst,
const CvMat* kernel,
CvPoint anchor = cvPoint(-1,-1)
);
这里我们创建一个适当大小的矩阵,将系数连同原图像和目标图像一起传递给cvFilter2D()。我们还可以有选择地输入一个CvPoint指出核的中心位置,但默认值(cvPoint(-1,-1))就会被认为是核的中心。如果定义了标定点,核的大小可以是任意偶数尺寸,否则大小就是奇数。
原图像src和目标图像dst大小应该是相同的,有些人可能认为考虑到卷积核的额外的长和宽,原图像src应该大于目标图像dst。但是在OpenCV里原图像src和目标图像dst的大小是可以一样的,因为在默认情况下,在卷积之前,OpenCV通过复制原图像src的边界创建了虚拟像素,这样以便于目标图像dst边界的像素可以被填充。复制是通过input(–dx, y) = input(0, y), input(w + dx, y) = input(w – 1, y)等实现的,还有一些可以替换此默认行为的方法,我们将在下一节讨论。
提示一下,这里我们所讨论的卷积核的系数应该是浮点类型的,这就意味着我们必须用CV_32F来初始化矩阵。
做卷积时自然出现的一个问题是如何处理卷积边界。例如,在使用刚才所讨论的卷积核时,当卷积点在图像边缘时会发生什么?许多使用cvFilter2D()的OpenCV内置函数必须用各种方式来解决这个问题。同样在你做卷积时,有必要知道如何有效解决这个问题。这个解决方法就是使用cvCopyMakeBorder()函数,它可以将特定的图像轻微变大,然后以各种方式自动填充图像边界。
void cvCopyMakeBorder(
const CvArr* src,
CvArr* dst,
CvPoint offset,
int bordertype,
CvScalar value = cvScalarAll(0)
);
Offset变量告诉cvCopyMakeBorder()将原图像的副本放到目标图像中什么位置。典型情况是,如果核为N×N(N为奇数)时,那么边界在每一侧的宽度都应是 (N – 1)/2,即这幅图像比原图像宽或高N – 1。在这种情况下,可以把Offset设置为cvPoint((N-1)/2,(N-1)/2),使得边界在每一侧都是偶数。[64]
[64]当然,标定点在中心、N×N并且N是奇数时的情形是最简单的。在一般情况下,如果核是N×M并且标定点在(ax,ay),那么目标图像将比原图像宽N-1,高M-1个像素。Offset的值仅仅是(ax,ay)。
Bordertype既可以是IPL_BORDER_CONSTANT,也可以是IPL_BORDER_REPLICATE(见图6-2)。在第一种情况下,value变量被认为是所有在边界的像素应该设置的值。在第二种情况下,原始图像边缘的行和列被复制到大图像的边缘。注意到测试的模板图像边缘是比较精细的(注意图6-2右上角的图像)。在测试的模板图像中,除了在圆图案边缘附近的像素变白外,有一个像素宽的黑色边界。这里定义了另外两种边界类型,IPL_BORDER_REFLECT 和IPL_BORDER_WRAP,目前还没有被OpenCV所实现,但以后可能会在OpenCV中实现。
图6-2 扩大的图像边界,左边一列显示的是IPL_BORDER_CONSTANT,边界是用零值填充的,右面一列是IPL_BORDER_REPLICATE,在水平和垂直两个方向复制边界像素。
<shape id="图片_x0020_3" style="VISIBILITY: visible; WIDTH: 200.25pt; HEIGHT: 151.5pt" alt="getfile?item=NjNmNTZnOWRpLzkvdGFwZ203ZWNzODByLzE1MTBpczZnLm05cG4vZ2kx" type="#_x0000_t75" o:spid="_x0000_i1027"><imagedata o:title="getfile?item=NjNmNTZnOWRpLzkvdGFwZ203ZWNzODByLzE1MTBpczZnLm05cG4vZ2kx" src="file:///D:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msoclip1/02/clip_image005.png"></imagedata><textbox style="mso-rotate-with-shape: t"></textbox></shape>
我们在前面已经提到,当调用OpenCv库函数中的卷积功能时,cvCopyMakeBorder()函数就会被调用。在大多数情况下,边界类型为IPL_BORDER_REPLICATE,但有时并不希望用它。所以在另一种场合,可能用到cvCopyMakeBorder()。你可以创造一幅具有比想要得到的边界稍微大一些的图像,无论调用任何常规操作,接下来就可以剪切到对原图像所感兴趣的部分。这样一来, OpenCV的自动加边就不会影响所关心的像素。
分享到:
相关推荐
这里是OpenCV2.4.13中已经...2、opencv_createsamples.exe 3、opencv_haartraining.exe 4、opencv_performance.exe 5、opencv_traincascade.exe 以及所有的dll动态库,这些程序在Win7系统64位机上测试可以通过。
OpenCV-2.2.0.tar.bz2 兼容性很好的哦,安装在linux中
《Learning.OpenCV.3.2016.12.pdf》是计算机视觉领域的经典入门教程,专注于使用C++和OpenCV 3库进行图像处理和分析。OpenCV(开源计算机视觉库)是一个强大的工具集,它包含了一系列用于图像处理、特征检测、对象...
opencv-4100.jar
opencv-453的4.5.3版本,仓库 失败的可以下载,然后通过maven命令安装到本地仓库,直接应用即可. 1.安装命令: -Dfile具体maven安装路径 mvn install:install-file -Dfile=D:\software\Apache\apache-maven-3.6.2\other\...
Learning OpenCV puts you right in the middle of the rapidly expanding field of computer vision. Written by the creators of OpenCV, the widely used free open-source library, this book introduces you to...
OpenCV(开源计算机视觉库)是一个强大的跨平台计算机视觉库,它包含了大量的图像处理和计算机视觉算法,广泛应用于机器学习、图像分析、人脸识别等领域。在Java编程环境中,OpenCV提供了`opencv_java.so`动态链接库...
opencv 3.4.3 包含四个文件:opencv_ffmpeg.dll、 opencv_ffmpeg_64.dll、 ffmpeg/ffmpeg_version.cmake、 -ippicv_2017u3_win_ia32_general_20180518.zip 以 md5-文件名 的方式重命名 直接用就可以
liunx opencv java320.so System.getProperty("java.library.path") 获取到library路径然后把so文件放到该目录下
opencv-4.5.3.zip
Java版的opencv包,this can help you learn more about opencv in java.
OpenCV(开源计算机视觉库)是计算机视觉领域广泛使用的库,它包含了大量的图像处理和计算机视觉算法。在OpenCV中,`opencv_createsamples.exe`和`opencv_haartraining.exe`是两个重要的工具,用于训练自定义的Haar...
这是OpenCV源代码结构的一部分,`3rdparty`目录通常存放所有依赖的第三方库,而`ffmpeg`子目录则是专门为FFmpeg准备的。 编译OpenCV 3.10时,一般会涉及以下步骤: 1. 下载OpenCV源代码:从OpenCV官方仓库或镜像...
opencv-4.5.5.zip
linux CentOs下基于Jdk8使用Cmake进行编译的opencv4.8.0版本so文件和jar文件
#include "opencv2/core/core_c.h" #include "opencv2/core/core.hpp" 所以这下要做的事儿比较明白了,就是把%opencv2.2%/vs2010/include也在属性页里添加到VC++目录->include那栏里,这样就能够找到这俩头文件了。 ...
《Learning OpenCV_3rd》是一本针对计算机视觉领域中广泛使用的开源库——OpenCV的权威入门教程。这本书专门针对OpenCV的第三版进行了详细讲解,涵盖了从基础概念到高级应用的各种主题,旨在帮助读者快速掌握这个...
编译opencv3.1.0时所需文件,将此文件复制到对应文件夹中。
《Learning OpenCV》和《Learning OpenCV 3》是由Gary Bradski等专家撰写的关于计算机视觉领域的经典著作,这两本书是学习OpenCV库的理想资源,特别是对于那些希望通过C++进行编程来实现计算机视觉功能的人来说。...