图像滤波 Image Filtering
译自《The OpenCV Reference Manual Release 2.3》
CHAPTER THREE: IMGPROC. IMAGE PROCESSING 3.1 Image Filtering
转载请注明出处:http://blog.csdn.net/xiaowei_cqu/article/details/7718831
BaseColumnFilter
- class BaseColumnFilter
- {
- public:
- virtual ~BaseColumnFilter();
- // 用以被用户重写
- //
- // 对列的集合进行滤波操作
- // 输入"dstcount + ksize - 1" 行,输出"dstcount" 行,
- // 输入和输出的每行含有"width"个元素,
- // 滤波之后的行写入缓存"dst"中.
- virtual void operator()(const uchar** src, uchar* dst, int dststep,
- int dstcount, int width) = 0;
- // 重置滤波器的状态(IIR滤波器中可能用到)
- virtual void reset();
- int ksize; // 核的孔径
- int anchor; // 定位点坐标
- // 处理过程中一般不使用
- };
类 BaseColumnFilter是使用单列核对数据滤波的基础类。滤波不一定是线性滤波,表示如下:
BaseFilter
- class BaseFilter
- {
- public:
- virtual ~BaseFilter();
- // 用以被用户重写
- //
- // 对列的集合进行滤波操作
- // 输入"dstcount + ksize.height - 1" 行,输出"dstcount" 行,
- // 输入的每行含有"(width + ksize.width-1)*cn"个元素
- // 输出的每行含有"width*cn"个元素,
- // 滤波之后的行写入缓存"dst"中.
- virtual void operator()(const uchar** src, uchar* dst, int dststep,
- int dstcount, int width, int cn) = 0;
- // 重置滤波器的状态(IIR滤波器中可能用到)
- virtual void reset();
- Size ksize;
- Point anchor;
- };
类 BaseFilter 是使用2D核对数据滤波的基础类。滤波不一定是线性的,可以表示如下:
BaseRowFilter
- class BaseRowFilter
- {
- public:
- virtual ~BaseRowFilter();
- // 用以被用户重写
- //
- // 对输入的单列进行滤波操作
- // 输入列有 "width"个元素, 每个元素有 "cn" 个通道.
- // 滤波之后的行写入缓存"dst"中.
- virtual void operator()(const uchar* src, uchar* dst,
- int width, int cn) = 0;
- int ksize, anchor;
- };
类 BaseRowFilter 是使用单列核对数据滤波的基础类。滤波不一定是线性的,可以表示如下:
FilterEngine
- class FilterEngine
- {
- public:
- // 空的构造函数
- FilterEngine();
- // 构造2D的不可分的滤波器(!_filter2D.empty())或者
- // 可分的滤波器 (!_rowFilter.empty() && !_columnFilter.empty())
- // 输入数据类型为 "srcType", 输出类型为"dstType",
- // 中间的数据类型为 "bufType".
- // _rowBorderType 何 _columnBorderType 决定图像边界如何被外推扩充
- // 只有 _rowBorderType and/or _columnBorderType
- // == BORDER_CONSTANT 时 _borderValue 才会被用到
- FilterEngine(const Ptr<BaseFilter>& _filter2D,
- const Ptr<BaseRowFilter>& _rowFilter,
- const Ptr<BaseColumnFilter>& _columnFilter,
- int srcType, int dstType, int bufType,
- int _rowBorderType=BORDER_REPLICATE,
- int _columnBorderType=-1, // 默认使用 _rowBorderType
- const Scalar& _borderValue=Scalar());
- virtual ~FilterEngine();
- // 初始引擎的分割函数
- void init(const Ptr<BaseFilter>& _filter2D,
- const Ptr<BaseRowFilter>& _rowFilter,
- const Ptr<BaseColumnFilter>& _columnFilter,
- int srcType, int dstType, int bufType,
- int _rowBorderType=BORDER_REPLICATE, int _columnBorderType=-1,
- const Scalar& _borderValue=Scalar());
- // 定义图像尺寸"wholeSize"为ROI开始滤波.
- // 返回图像开始的y-position坐标.
- virtual int start(Size wholeSize, Rect roi, int maxBufRows=-1);
- // 另一种需要图像的开始
- virtual int start(const Mat& src, const Rect& srcRoi=Rect(0,0,-1,-1),
- bool isolated=false, int maxBufRows=-1);
- // 处理源图像的另一部分
- // 从"src"到"dst"处理"srcCount" 行
- // 返回处理的行数
- virtual int proceed(const uchar* src, int srcStep, int srcCount,
- uchar* dst, int dstStep);
- // 处理整个ROI的高层调用
- virtual void apply( const Mat& src, Mat& dst,
- const Rect& srcRoi=Rect(0,0,-1,-1),
- Point dstOfs=Point(0,0),
- bool isolated=false);
- bool isSeparable() const { return filter2D.empty(); }
- // 输入图中未被处理的行数
- int remainingInputRows() const;
- // 输入中未被处理的行数
- int remainingOutputRows() const;
- // 源图的开始和结束行
- int startY, endY;
- // 指向滤波器的指针
- Ptr<BaseFilter> filter2D;
- Ptr<BaseRowFilter> rowFilter;
- Ptr<BaseColumnFilter> columnFilter;
- };
类 FilterEngine 可以被用于对任何一个图像进行滤波。它包含了所有必要的缓冲区,计算需要的图像外的“虚”像素推算值等等。通过各种创建 *Filter 的函数(见下文)可以返回指向初始化的 FilterEngine 的实例,之后可以使用这些实例中的高层接口如 filter2D(), erode(),dilate() 等。因此,此类在OpenCV的很多滤波函数中起着关键的作用。
- void laplace_f(const Mat& src, Mat& dst)
- {
- CV_Assert( src.type() == CV_32F );
- dst.create(src.size(), src.type());
- // get the derivative and smooth kernels for d2I/dx2.
- // for d2I/dy2 consider using the same kernels, just swapped
- Mat kd, ks;
- getSobelKernels( kd, ks, 2, 0, ksize, false, ktype );
- // process 10 source rows at once
- int DELTA = std::min(10, src.rows);
- Ptr<FilterEngine> Fxx = createSeparableLinearFilter(src.type(),
- dst.type(), kd, ks, Point(-1,-1), 0, borderType, borderType, Scalar() );
- Ptr<FilterEngine> Fyy = createSeparableLinearFilter(src.type(),
- dst.type(), ks, kd, Point(-1,-1), 0, borderType, borderType, Scalar() );
- int y = Fxx->start(src), dsty = 0, dy = 0;
- Fyy->start(src);
- const uchar* sptr = src.data + y*src.step;
- // allocate the buffers for the spatial image derivatives;
- // the buffers need to have more than DELTA rows, because at the
- // last iteration the output may take max(kd.rows-1,ks.rows-1)
- // rows more than the input.
- Mat Ixx( DELTA + kd.rows - 1, src.cols, dst.type() );
- Mat Iyy( DELTA + kd.rows - 1, src.cols, dst.type() );
- // inside the loop always pass DELTA rows to the filter
- // (note that the "proceed" method takes care of possibe overflow, since
- // it was given the actual image height in the "start" method)
- // on output you can get:
- // * < DELTA rows (initial buffer accumulation stage)
- // * = DELTA rows (settled state in the middle)
- // * > DELTA rows (when the input image is over, generate
- // "virtual" rows using the border mode and filter them)
- // this variable number of output rows is dy.
- // dsty is the current output row.
- // sptr is the pointer to the first input row in the portion to process
- for( ; dsty < dst.rows; sptr += DELTA*src.step, dsty += dy )
- {
- Fxx->proceed( sptr, (int)src.step, DELTA, Ixx.data, (int)Ixx.step );
- dy = Fyy->proceed( sptr, (int)src.step, DELTA, d2y.data, (int)Iyy.step );
- if( dy > 0 )
- {
- Mat dstripe = dst.rowRange(dsty, dsty + dy);
- add(Ixx.rowRange(0, dy), Iyy.rowRange(0, dy), dstripe);
- }
- }
- }
如果你不需要对滤波过程的控制,你可以简单地使用 FilterEngine:: apply方法。
- void FilterEngine::apply(const Mat& src, Mat& dst,
- const Rect& srcRoi, Point dstOfs, bool isolated)
- {
- // check matrix types
- CV_Assert( src.type() == srcType && dst.type() == dstType );
- // handle the "whole image" case
- Rect _srcRoi = srcRoi;
- if( _srcRoi == Rect(0,0,-1,-1) )
- _srcRoi = Rect(0,0,src.cols,src.rows);
- // check if the destination ROI is inside dst.
- // and FilterEngine::start will check if the source ROI is inside src.
- CV_Assert( dstOfs.x >= 0 && dstOfs.y >= 0 &&
- dstOfs.x + _srcRoi.width <= dst.cols &&
- dstOfs.y + _srcRoi.height <= dst.rows );
- // start filtering
- int y = start(src, _srcRoi, isolated);
- // process the whole ROI. Note that "endY - startY" is the total number
- // of the source rows to process
- // (including the possible rows outside of srcRoi but inside the source image)
- proceed( src.data + y*src.step,
- (int)src.step, endY - startY,
- dst.data + dstOfs.y*dst.step +
- dstOfs.x*dst.elemSize(), (int)dst.step );
- }
不同于OpenCV的早期版本,现在的滤波操作支持图像ROI概念,也就是说,在ROI图像之外但在图像之内的像素点可以用于滤波操作。例如,你可以取单个像素作为ROI滤波。通过滤波器之后将范围特定的像素。然而,通过传递FilterEngine::start或FilterEngine::apply 参数 isolated=false 它有可能仍是旧的图像。你可以明确指定传递ROI给 FilterEngine::apply 函数或者构造新的矩阵头:
- // compute dI/dx derivative at src(x,y)
- // method 1:
- // form a matrix header for a single value
- float val1 = 0;
- Mat dst1(1,1,CV_32F,&val1);
- Ptr<FilterEngine> Fx = createDerivFilter(CV_32F, CV_32F,
- 1, 0, 3, BORDER_REFLECT_101);
- Fx->apply(src, Rect(x,y,1,1), Point(), dst1);
- // method 2:
- // form a matrix header for a single value
- float val2 = 0;
- Mat dst2(1,1,CV_32F,&val2);
- Mat pix_roi(src, Rect(x,y,1,1));
- Sobel(pix_roi, dst2, dst2.type(), 1, 0, 3, 1, 0, BORDER_REFLECT_101);
探索中的数据类型。由于它是在 BaseFilter 描述中提到的具体的滤波器,虽然 Base*Filter::operator() 除了UCHAR的指针并其他类型的信息, 但实际它可以处理任何类型的数据。为了保证所有的函数可以运行,使用以下规则:
- 在分离滤波的情况下,首先应用 FilterEngine::rowFilter 。它把输入图像数据(srcType类型)的中间结果存储在内部缓冲区(bufType类型)。然后,这些中间结果作为单通道数据由 FilterEngine:: columnFilter处理,结果存储在输出图像(dstType类型)中。因此,输入 RowFilter 类型是srcType 而输出类型是 bufType。输入 columnFilter 的类型是CV_MAT_DEPTH(bufType)而输出的类型为CV_MAT_DEPTH(dstType)。
- 在非分离滤波的情况下,bufType 必须与 srcType 类型相同。如果需要,源数据会被复制到临时缓冲区之后传递给 FilterEngine:: filter2D 。也就是说,输入filter2D 类型为 scrType(= bufType),输出类型是dstType。
图像滤波 Image Filtering相关推荐
- 图像滤波(Image Filtering)
在具体写图像滤波方法之前,先给出图像滤波的一般性目标阐述和经典应用.图像通常有一个直观(intuition)特征: 图像往往由多块组成,各块内像素相似且过渡缓慢,块与块相邻部分称作边缘(Edge). ...
- 引导图像滤波(Guided Image Filtering)
[Paper] Guided Image Filtering(2013) 引导图像滤波 摘要--在本文中,我们提出了一种新的显式图像滤波器,称为引导滤波器.从局部线性模型导出,引导滤波器通过考虑引导图 ...
- opencv(4)图像滤波
都是一些常用函数,但是可能太常用了,里面的一些关键点,没做过多的研究,今天主要对函数中特殊的地方做出分析 1.cvSmooth 图像滤波 CV_BLUR_NO_SCALE (简单不带尺度变换的模糊) ...
- 在OpenCV中利用卷积进行图像滤波
简 介: 本文首先讨论了卷积核的概念,以及如何用于对图像进行滤波.然后通过他们对图像进行数学运算来实现特定的效果,比如平和和锐化.展示了如何在OpenCV中实现2D滤波. 在等同卷积卷积核之后,我们创 ...
- 计算机视觉基础-图像处理(图像滤波)cpp+python
4.1 简介 图像的实质是一种二维信号,滤波是信号处理中的一个重要概念.在图像处理中,滤波是一种非常常见的技术,它们的原理非常简单,但是其思想却十分值得借鉴,滤波是很多图像算法的前置步骤或基础,掌握图 ...
- 中值滤波Median filtering
背景简述 在概率论中,中值将概率分布的高半部分与低半部分分开,对一个随机变量x 而言,x < M 的概率为0.5.对于有限实数集,其排序后中间的数值即为它的中值.集合的大小通常取奇数,以保证中值 ...
- 三种经典图像滤波方法介绍——双边滤波(Bilateral filter)、导向滤波(Guided Fliter)、滚动导向滤波(RollingGuidedFilter)
文章目录 一.前言 二.双边滤波(Bilateral filter) 2.1 双边滤波的理论介绍及公式推导 2.2 双边滤波的matlab程序实现 三.导向滤波(Guided Fliter) 3.1 ...
- 计算机视觉 Project 1:图像滤波和混合图像
计算机视觉 Project 1:Image Filtering and Hybrid Images 计算机视觉 Project 1:Image Filtering and Hybrid Images ...
- 图像滤波的matlab实现,图像滤波方法及其MATLAB实现
图像滤波方法及其MATLAB实现(论文13000字) 摘要:在数字图像处理中,由于受到成像方法的限制,图像中的边缘.细节特征等重要信息常湮没于噪声信号中,给图像的后继处理如边缘检测.图像分割.图像匹配 ...
最新文章
- c语言头文件中定义inline static相关函数的优劣
- jquery 1.9里面已经删除了toggle(fn1, fn2)函数:
- 设计模式在C语言中的应用--读nginx源码
- Quartz.Net定时任务EF+MVC版的web服务
- java 类的高级特性_java程序-类的高级特性
- 华为年底开源其操作系统 EulerOS,更名为 openEuler
- java 有序map_Java有序的Hash集合:LinkedHashMap
- delete删除重复记录方法
- 使用tail和head读取字节流
- 【过拟合】再也不用担心过拟合的问题了
- 孙鑫mfc学习笔记第十二课
- 【网络流24题】火星探险问题
- 三个学生开发的学术钓鱼软件,成功忽悠了整个学术圈
- WeUI—微信官方UI库
- Premiere Pro Guru: Online Offline Workflows Premiere Pro 大师教程之在线与离线工作流 Lynda课程中文字幕
- 高性能迷你React框架 anu1.2.3 发布
- i春秋-misc3-哒哒哒哒,你知道什么是键盘坐标密码吗?---flag{QAZIJCV}
- 武汉大学信息管理学院莅临法大大交流
- Md5Md5盐值加密
- matlab光波耦合光栅,均匀布拉格光栅的原理及MATLAB反射谱仿真
热门文章
- SpringBoot - Spring Boot 应用剖析
- Spring-AOP @AspectJ进阶之绑定抛出的异常
- Linux-在指定文件类型中递归查找到目标字符串
- 复习笔记(五)——C++多态和虚函数
- python判断字符是否为数字或字母
- 计算机科学与技术年会,2017年全国理论计算机科学学术年会在武汉召开
- halcon算子盘点:Chapter 12:OCR(光字符识别)
- 2012计算机科学排名,2012年美国大学计算机科学专业研究生排名
- centos mysql-5.5.20_centos 下安装mysql5.5.20出现的问题
- 微博 php7,新浪微博PHP版SDK的导致20007错误