BaseColumnFilter
单列核的基础滤波器。
[cpp] view plaincopy
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是使用单列核对数据滤波的基础类。滤波不一定是线性滤波,表示如下:

其中 F 是滤波函数,但是用类来表示,因为类可以有其他的,如储存之前处理的数据之类的附加功能。这个类只是定义一个接口并不直接使用。作为替代,OpenCV中有一些函数(你可以添加更多)实现了特定的滤波功能并返回指向派生类的指针。这些指针通过 FilterEngine构造函数。 虽然滤波操作接口使用uchar 类型,具体实施时并限于8位数据。

BaseFilter
对2D图像滤波的基础类。
[cpp] view plaincopy
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
单列核滤波器的基础类。
[cpp] view plaincopy
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 是使用单列核对数据滤波的基础类。滤波不一定是线性的,可以表示如下:

其中 F 是滤波函数。此类只是定义了一个接口并不直接使用。这个类只是定义一个接口并不直接使用。作为替代,OpenCV中有一些函数(你可以添加更多)实现了特定的滤波功能并返回指向派生类的指针。这些指针通过 FilterEngine 构造函数。 虽然滤波操作接口使用uchar类型,具体实施时并限于8位数据。

FilterEngine
通用图像滤波类。
[cpp] view plaincopy
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& _filter2D,
const Ptr& _rowFilter,
const Ptr& _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& _filter2D,
const Ptr& _rowFilter,
const Ptr& _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 filter2D;
Ptr rowFilter;
Ptr columnFilter;
};
类 FilterEngine 可以被用于对任何一个图像进行滤波。它包含了所有必要的缓冲区,计算需要的图像外的“虚”像素推算值等等。通过各种创建 *Filter 的函数(见下文)可以返回指向初始化的 FilterEngine 的实例,之后可以使用这些实例中的高层接口如 filter2D(), erode(),dilate() 等。因此,此类在OpenCV的很多滤波函数中起着关键的作用。
这个类使得滤波和其他函数结合更容易,如色彩空间转换,阈值,算术运算,等操作。将几个操作相结合在一起你可以得到更好的性能,因为数据都留在缓存中。例如以下是对浮点图像执行 Laplace 算子处理的简单例子,Laplacian() 函数可以简化为:
[cpp] view plaincopy
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 Fxx = createSeparableLinearFilter(src.type(),
dst.type(), kd, ks, Point(-1,-1), 0, borderType, borderType, Scalar() );
Ptr 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方法。
[cpp] view plaincopy
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 函数或者构造新的矩阵头:
[cpp] view plaincopy
// 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 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),输出类型是

opencv中imgproc库中函数详解(1)相关推荐

  1. python平方数迭代器_对python中的高效迭代器函数详解

    python中内置的库中有个itertools,可以满足我们在编程中绝大多数需要迭代的场合,当然也可以自己造轮子,但是有现成的好用的轮子不妨也学习一下,看哪个用的顺手~ 首先还是要先import一下: ...

  2. pythonpandas函数详解_对pandas中Series的map函数详解

    Series的map方法可以接受一个函数或含有映射关系的字典型对象. 使用map是一种实现元素级转换以及其他数据清理工作的便捷方式. (DataFrame中对应的是applymap()函数,当然Dat ...

  3. 在oracle中游标的操作,Oracle中的游标和函数详解

    Oracle中的游标和函数详解 1.游标 游标是一种 PL/SQL 控制结构:可以对 SQL 语句的处理进行显示控制,便于对表的行数据 逐条进行处理. 游标并不是一个数据库对象,只是存留在内存中. 操 ...

  4. 转:linux中fork()函数详解

    转:linux中fork()函数详解 https://blog.csdn.net/jason314/article/details/5640969 转载于:https://www.cnblogs.co ...

  5. python中plt定义,对Python中plt的画图函数详解

    1.plt.legend plt.legend(loc=0)#显示图例的位置,自适应方式 说明: 'best' : 0, (only implemented for axes legends)(自适应 ...

  6. Oracle中nvl()与nvl2()函数详解

    Oracle中nvl()与nvl2()函数详解: 函数nvl(expression1,expression2)根据参数1是否为null返回参数1或参数2的值: 函数nvl2(expression1,e ...

  7. bind() c语言,c/c++ 标准库 bind 函数详解

    bind函数定义在头文件 functional 中.可以将 bind 函数看作一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来"适应"原对象的参数列表. bin ...

  8. c语言中bind函数,c/c++ 标准库 bind 函数详解

    bind函数定义在头文件 functional 中.可以将 bind 函数看作一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来"适应"原对象的参数列表. bin ...

  9. linux内核中send与recv函数详解

    Linux send与recv函数详解 1.简介 #include <sys/socket.h> ssize_t recv(int sockfd, void *buff, size_t n ...

  10. python中文件读写--open函数详解

    python中open函数详解 在python中文件的读取分为三步走: 读:打开文件 -> 读文件 -> 关闭文件 (有点像把大象放进冰箱需要几步?的问题) 1.open函数 open函数 ...

最新文章

  1. 反转字符串/列表、改变递归次数限制、else用法...Python 冷知识(四)
  2. java源码阅读LinkedList
  3. 远程控制软件 TeamViewer | Windoes和Linux下teamviewer软件互连
  4. python怎么画波浪_python 实现波浪滤镜特效
  5. 杭电2035--人见人爱A^B
  6. 【图示,简单明了】HttpServlet中getAttribute和getParameter的区别——【javaweb系列学习笔记】
  7. java线程夯住了怎么解决,不明白线程为什么卡住了? 求大神解救
  8. 投篮机投篮有技巧吗_「技巧干货」高手练习投篮的几个技巧,让投篮变得更实用...
  9. 【Vue2.0】—事件处理和事件修饰符(二)
  10. 华为交换机ensp基础命令
  11. unity2D笔记-控制人物相关
  12. vscode php格式化插件
  13. 西科大计算机网络期末复习考点
  14. python3 Json转xmind代码与打开
  15. [Python从零到壹] 四十五.图像增强及运算篇之图像灰度非线性变换详解
  16. spring boot新闻管理系统 毕业设计源码211113
  17. Java之字符类型char
  18. arm汇编和c语言混合编程实验报告,arm实验ARM汇编和C语言混合编程.doc
  19. 文职辅警的技能测试计算机操作是考什么,辅警文职体测都考哪些内容?
  20. flutter permission 问题

热门文章

  1. Linux内核模块简介
  2. c语言对n个数选择排序_选择排序法 -- C语言
  3. 牛刀小试之Django二
  4. SpringBoot使用RabbitMQ消息队列
  5. 5月23日任务 LAMP架构介绍、MySQL、MariaDB介绍、 MySQL安装
  6. iOS多线程编程:线程同步总结 NSCondtion
  7. 未来已来——工作空间WorkSpace和物联网IoT (3)
  8. 京东自建数据中心核心技术解密——运营管理篇
  9. Xcode编译Undefined symbols for architecture xxx 错误总结
  10. web项目中的web.xml元素解析