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_createsamples.exe和opencv_haartraining.exe 下载
OpenCV-2.2.0.tar.bz2 兼容性很好的哦,安装在linux中
openv有两个训练exe,一个是opencv_haartraining.exe,一个是opencv_traincascade.exe,后者是前者的新版本,一般我们都使用后者,或者有三个特征:HAAR、HOG、LBP.
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-3.0.0.exe,vs2013版本亲测可用。
OpenCV 的opencv_createsamples.exe和opencv_haartraining.exe两个可执行文件及相关文件
Opencv 2.4.3的opencv_createsamples.exe和opencv_haartraining.exe
Packt.Learning.OpenCV.3.Application.2016
opencv-4.5.5.zip
计算机视觉入门经典,新版的Learning OpenCV,基于C++和OpenCV 3的教程 全彩色文字版非扫描。英文原版高清PDF可打印。
liunx opencv java320.so System.getProperty("java.library.path") 获取到library路径然后把so文件放到该目录下
Java版的opencv包,this can help you learn more about opencv in java.
这是opencv2.4.9中用于训练人脸检测器的可执行文件opencv_createsamples.exe和opencv_haartraining.exe,它们是用于32位的计算机中的。
MAC下java调用opencv-java的独立静态库文件 包含 opencv_454.jar libopencv_java454.dylib
Unleash the power of computer vision with Python using OpenCV About This Book Create impressive applications with OpenCV and Python Familiarize yourself with advanced machine learning concepts ...
cmake 编译opencv 缺失opencv_ffmpeg.dll 、 opencv_ffmpeg_64.dll、ffmpeg_version.cmake等问题,只需替换下载替换.cache目录即可 : opencv-4.5.0\.cache
OpenCV-2.4.1.tar,源代码