关闭

opencv学习笔记(二十)cvFilter2D()卷积以及卷积边界的处理

7445人阅读 评论(0) 收藏 举报

20.1**cvFilter2D()卷积:**

void cvFilter2D(
const CvArr* src,
CvArr* dst,
const CvMat* kernel,
CvPoint anchor=cvPoint(-1,-1)
);
src
输入图像

dst
输出图像

kernel
卷积核, 单通道浮点矩阵。 如果想要应用不同的核于不同的通道,先用 cvSplit 函数分解图像到单个色彩通道上,然后单独处理。

anchor
核的锚点表示一个被滤波的点在核内的位置。 锚点应该处于核内部。默认值 (-1,-1) 表示锚点在核中心。

这里我们创建一个适当大小的矩阵,将系数连同源图像和目标图像一起传递给cvFilter2D()。我们还可以有选择地输人一个CvPoint指出核的中心位置,默认值(cvPoint (-1, -1))会设参考点为核的中心。如果定义了参考点,核的大小可以是偶数,否则只能是奇数。
源图像src和目标图像dst大小应该相同,有些人可能认为考虑到卷积核的额外的长和宽,源图像src应该大于目标图像dst。但是在OpenCV里源图像src和目标图像dst的大小是可以一样的,因为在默认情况下,在卷积之前,OpenCV通过复制源图像src的边界创建了虚拟像素,这样以便于目标图像dst边界的像素可以被填充。
这里我们所讨论的卷积核的系数应该是浮点类型的,这就意味着我们必须用CV_32F来初始化矩阵。

20.2卷积模板及程序实例:

下面这篇文章详细介绍了卷积的应用:
http://blog.sina.com.cn/s/blog_6ac784290101e47s.html
常用卷积模板
这里写图片描述

20.3OpenCV图像卷积(图像滤波)的程序代码:

#include "cv.h"
#include "highgui.h"
int main(int argc,char**argv) 
{ 
    IplImage* src, *dst;   
    float low[9] ={ 1.0/16, 2.0/16, 1.0/16, 2.0/16, 4.0/16, 2.0/16, 1.0/16, 2.0/16, 1.0/16 };//低通滤波核
    float high[9]={-1,-1,-1,-1,9,-1,-1,-1,-1};
    //高通滤波核——这个模板自己设,这里用的是常用的核。
    CvMat km = cvMat( 3, 3, CV_32FC1, low);  
    //构造单通道浮点矩阵,将图像IplImage结构转换为图像数组
    //上面这个矩阵就是在cvFilter2D里面要用到的核
    src = cvLoadImage( "b.jpg" ); 
    dst = cvCreateImage( cvGetSize(src), IPL_DEPTH_8U, 3 );
    cvFilter2D( src, dst, &km, cvPoint( -1, -1 ) );  
    //设参考点为核的中心
    cvNamedWindow( "src", CV_WINDOW_AUTOSIZE );
    cvNamedWindow( "filtering", CV_WINDOW_AUTOSIZE );
    cvShowImage( "src", src );  
    cvShowImage( "filtering", dst ); 
    cvWaitKey(0); 
    cvReleaseImage( &src ); 
    cvReleaseImage( &dst ); 
    return 0; 
} 

20.4低通滤波和高通滤波:

低通滤波:边缘平滑
高通滤波:边缘提取与增强

滤波是信号处理机图像处理中的一个基本操作。滤波去除图像中的噪声,提取感兴趣的特征,允许图像重采样。
图像中的频域和空域:空间域指用图像的灰度值来描述一幅图像;而频域指用图像灰度值的变化来描述一幅图像。而低通滤波器和高通滤波器的概念就是在频域中产生的。
低通滤波器指去除图像中的高频成分,而高通滤波器指去除图像中的低频成分。

20.5卷积边界

对于卷积,一个很自然的问题是如何处理卷积边界。例如,在使用刚才所讨论的卷积核时,当卷积点在图像边界时会发生什么?许多使用cvFilter2D()的OpenCV内置函数必须用各种方式来解决这个问题。同样在做卷积时,有必要知道如何有效解决这个问题。
这个解决方法就是使用cvCopyMakeBorder()函数,它可以将特定的图像轻微变大,然后以各种方式自动填充图像边界。
复制图像并且制作边界。

20.5.1cvCopyMakeBorder()
定义:
void cvCopyMakeBorder(
const CvArr* src,
CvArr* dst,
CvPoint offset,
int bordertype,
CvScalar value=cvScalarAll(0)
);
参数:
src
输入图像。

dst
输出图像。(根据offset而相应改变大小)

offset
输入图像(或者其ROI)欲拷贝到的输出图像长方形的左上角坐标(或者左下角坐标,如果以左下角为原点)。长方形的尺寸要和原图像的尺寸的ROI分之一匹配。
——指的是输出图像上指定哪个点为原点坐标,拷贝图像。例子中选择了cvPoint(5,5),cvPoint(25,25)这两个点分别为图像的原点,则输出图像要对应的扩大cvSize(img->width+10,img->height+10),cvSize(img->width+50,img->height+50)。
——这里输出图像至少要在边界上加上原点坐标值,当然最好是两倍(不然就是只有两条边会有边框)。所以才是+10和50。

bordertype已拷贝的原图像长方形的边界的类型:
IPL_BORDER_CONSTANT——填充边界为固定值,值由函数最后一个参数指定。(默认黑色填充)
IPL_BORDER_REPLICATE——边界用上下行或者左右列来复制填充。(其他两种IPL边界类型, IPL_BORDER_REFLECT 和IPL_BORDER_WRAP现已不支持)。

value如果边界类型为IPL_BORDER_CONSTANT的话,那么此为边界像素的值。

我们在前面已经提到,当调用OpenCV库函数中的卷积功能时,cvCopyMakeBorder()函数就会被调用。在大多数情况下,边界类型为
IPL_BORDER_REPLICATE,但有时并不希望用它。所以在另一种场合,可能用到cvCopyMakeBorder()。你可以创建一幅具有比想要得到的边界稍微大一些的图像,无论调用任何常规操作,接下来就可以剪切到对源图像所感兴趣的部分。这样一来,OpenCV的自动加边就不会影响所关心的像素。

20.5.2程序实例

#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include <iostream>
int main(int argc,char** argv)
{
    IplImage* src=cvLoadImage("b.jpg");
    IplImage* dst1=cvCreateImage(cvSize(src->width+40,src->height+40),src->depth,src->nChannels);
    //因为cvPoint(20,20),所以长宽必须是+(20*2=)40
    IplImage* dst2=cvCreateImage(cvSize(src->width+40,src->height+40),src->depth,src->nChannels);
    cvZero(dst1);
    cvZero(dst2);
    cvCopyMakeBorder(src,dst1,cvPoint(20,20),IPL_BORDER_REPLICATE); //用边界像素的值填充
    cvCopyMakeBorder(src,dst2,cvPoint(20,20),IPL_BORDER_CONSTANT); //用黑色填充
    cvNamedWindow("dst1");
    cvNamedWindow("dst2");
    cvShowImage("src",src);
    cvShowImage("dst1",dst1);
    cvShowImage("dst2",dst2);
    cvWaitKey(0);
    cvDestroyWindow("src");
    cvDestroyWindow("dst1");
    cvDestroyWindow("dst2");
    cvReleaseImage(&src);
    cvReleaseImage(&dst1);
    cvReleaseImage(&dst2);
    return 0;
}
0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

opencv学习(七)之图像卷积运算函数filter2D()

在其官方文档中,filter2D()函数在掩模板介绍中一笔带过,我认为该函数应该进行详细介绍。 对于使用掩模板矩阵(kernel)计算每个像素值,结合函数filter2D()函数,其定义如下:CV_...
  • keith_bb
  • keith_bb
  • 2016-11-09 18:08
  • 7687

Python下opencv使用笔记(五)(图像的平滑与滤波)

对于图形的平滑与滤波,但从滤波角度来讲,一般主要的目的都是为了实现对图像噪声的消除,增强图像的效果。 首先介绍二维卷积运算,图像的滤波可以看成是滤波模板与原始图像对应部分的的卷积运算。关于卷积运算,...
  • on2way
  • on2way
  • 2015-07-10 11:31
  • 14516

Opencv中cvFilter2D卷积函数的计算过程分析

接上一篇,介绍了矩阵卷积的计算方法,我们选择了用0来补全,但是在Opencv中的CVFilter2D函数是用边缘拷贝的方式。 CvFilter2D函数 void cvFilter2D( con...
  • qq_32846595
  • qq_32846595
  • 5天前 16:31
  • 11

Opencv卷积滤波cvFilter2D-高通与低通

原文: http://blog.sina.com.cn/s/blog_6df50e1a01019z95.html 1.使用模板处理图像相关概念        模板:矩阵方块,其数学含义是一种卷积运算...
  • jacke121
  • jacke121
  • 2017-01-09 19:30
  • 548

第六章 - 图像变换 - 卷积(cvFilter2D) - 卷积边界(cvCopyMakeBorder)

cvCopyMakeBorder()函数可以复制图像并制作边界,将特定图像轻微变大,然后以各种方式自动填充图像边界,当Bordertype=IPL_BORDER_REPLICATE时,原始图像边缘的行...
  • u011450295
  • u011450295
  • 2014-08-22 15:06
  • 361

opencv学习(七)之图像卷积运算函数filter2D()

在其官方文档中,filter2D()函数在掩模板介绍中一笔带过,我认为该函数应该进行详细介绍。 对于使用掩模板矩阵(kernel)计算每个像素值,结合函数filter2D()函数,其定义如下:CV_...
  • keith_bb
  • keith_bb
  • 2016-11-09 18:08
  • 7687

opencv学习笔记--卷积和核

卷积 高度概括地说,卷积是在每一个图像块与某个算子(核)之间进行的运算。 核是什么? 核说白了就是一个固定大小的数值数组。该数组带有一个 锚点 ,一般位于数组中央。 如...
  • x670127565
  • x670127565
  • 2017-07-09 20:58
  • 168

Opencv学习笔记——自建滤波器cvFilter2D

利用Opencv自带的cvFilter2D来对图像进行卷积计算,具体代码如下:
  • acm2014
  • acm2014
  • 2014-10-18 15:17
  • 1532

图像变换 - 卷积(cvFilter2D)

最常见的图像变换(image transform,即将一幅图像转变成图像数据)就是傅里叶变换(Fourier transform),即将图像转换成源图像数据的另一种表示,而卷积是大多数变换的基础。 ...
  • jackinzhou
  • jackinzhou
  • 2012-08-23 16:49
  • 5268

[TensorFlow 学习笔记-04]卷积函数之tf.nn.conv2d

[版权说明] TensorFlow 学习笔记参考:  李嘉璇 著 TensorFlow技术解析与实战 黄文坚 唐源 著 TensorFlow实战郑泽宇  顾思宇 著 TensorFlow实战Goog...
  • caicaiatnbu
  • caicaiatnbu
  • 2017-05-28 13:08
  • 2047
    个人资料
    • 访问:43247次
    • 积分:907
    • 等级:
    • 排名:千里之外
    • 原创:49篇
    • 转载:0篇
    • 译文:0篇
    • 评论:6条
    文章分类
    最新评论