前言java
在上一篇opencv-android-图像平滑处理文章中,简单介绍了几种图像平滑,也就是图像模糊的方法,使用了几个简单的滤波器,这都属于图像的滤波操做。android
opencv针对图像的处理提供了imgproc模块,好比图像滤波、几何变换,特征识别等等,本文针对opencv的图像滤波作一个全面的分析。c++
滤波方法一览算法
opencv的图像滤波中主要有如下方法,用于对2D图像执行线性/非线性的滤波操做。数组
对上述方法根据功能作简单的分类。bash
源图像(通常为矩形)中每一个位置(x,y)的像素的邻域像素都会被用来计算其结果像素值。使用线性滤波器时,结果像素值时邻域像素的加权和;使用形态学操做时,结果像素值时邻域像素的最大值或者最小值。计算的结果存储在输出图像相应的位置(x,y),输出图像和源图像的大小相同,并且下面这些方法都支持多通道数组,每一个通道都会独立处理,因此输出图像和源图像具备相同的通道数。函数
另外,与简单的算术方法不一样,上述方法须要外推一些不存在的像素的值。例如使用高斯3X3滤波器平滑图像,每一行最左侧的像素计算时须要用到左侧的像素值,可是其左侧没有像素了,因此能够另不存在的像素都是零,或者让其与最左侧的像素相同,opencv能够指定外推方法。学习
方法详解动画
bilateralFilterui
方法声明:
c++
void cv::bilateralFilter ( InputArray src,
OutputArray dst,
int d,
double sigmaColor,
double sigmaSpace,
int borderType = BORDER_DEFAULT
)
复制代码
java
public static void bilateralFilter(Mat src, Mat dst, int d, double sigmaColor, double sigmaSpace) {
bilateralFilter_1(src.nativeObj, dst.nativeObj, d, sigmaColor, sigmaSpace);
return;
}
private static native void bilateralFilter_0(long src_nativeObj, long dst_nativeObj, int d, double sigmaColor, double sigmaSpace, int borderType);
private static native void bilateralFilter_1(long src_nativeObj, long dst_nativeObj, int d, double sigmaColor, double sigmaSpace);
复制代码
给图像应用双边滤波,能够在保留边界的同时很好的减小噪声,可是执行速度比其余滤波器要慢。
该过滤器不是原地工做的。
Sigma 值:简单的话,能够将两个sigma值设为相同。当值比较小(<10)时,看起来没什么效果;当比较大(>150)时,效果比较强,图像看起来像动画片。
Filter size(d):比较大(d>5)时,计算比较慢。因此在实时应用场景下,推荐使用d=5;在离线应用强力过滤噪声时能够将d=9 。
blur
方法声明:
c++
void cv::blur ( InputArray src,
OutputArray dst,
Size ksize,
Point anchor = Point(-1,-1),
int borderType = BORDER_DEFAULT
)
复制代码
java
public static void blur(Mat src, Mat dst, Size ksize) {
blur_2(src.nativeObj, dst.nativeObj, ksize.width, ksize.height);
return;
}
private static native void blur_0(long src_nativeObj, long dst_nativeObj, double ksize_width, double ksize_height, double anchor_x, double anchor_y, int borderType);
private static native void blur_1(long src_nativeObj, long dst_nativeObj, double ksize_width, double ksize_height, double anchor_x, double anchor_y);
private static native void blur_2(long src_nativeObj, long dst_nativeObj, double ksize_width, double ksize_height);
复制代码
使用归一化块滤波器模糊图像,方法平滑图像使用的kernel以下:
调用方法blur(src, dst, ksize, anchor, borderType)
等价于调用方法boxFilter(src, dst, src.type(), anchor, true, borderType)
boxFilter
方法声明:
c++
void cv::boxFilter ( InputArray src,
OutputArray dst,
int ddepth,
Size ksize,
Point anchor = Point(-1,-1),
bool normalize = true,
int borderType = BORDER_DEFAULT
)
复制代码
java
//
// C++: void cv::boxFilter(Mat src, Mat& dst, int ddepth, Size ksize, Point anchor = Point(-1,-1), bool normalize = true, int borderType = BORDER_DEFAULT)
//
//javadoc: boxFilter(src, dst, ddepth, ksize, anchor, normalize, borderType)
public static void boxFilter(Mat src, Mat dst, int ddepth, Size ksize, Point anchor, boolean normalize, int borderType) {
boxFilter_0(src.nativeObj, dst.nativeObj, ddepth, ksize.width, ksize.height, anchor.x, anchor.y, normalize, borderType);
return;
}
//javadoc: boxFilter(src, dst, ddepth, ksize, anchor, normalize)
public static void boxFilter(Mat src, Mat dst, int ddepth, Size ksize, Point anchor, boolean normalize) {
boxFilter_1(src.nativeObj, dst.nativeObj, ddepth, ksize.width, ksize.height, anchor.x, anchor.y, normalize);
return;
}
//javadoc: boxFilter(src, dst, ddepth, ksize, anchor)
public static void boxFilter(Mat src, Mat dst, int ddepth, Size ksize, Point anchor) {
boxFilter_2(src.nativeObj, dst.nativeObj, ddepth, ksize.width, ksize.height, anchor.x, anchor.y);
return;
}
//javadoc: boxFilter(src, dst, ddepth, ksize)
public static void boxFilter(Mat src, Mat dst, int ddepth, Size ksize) {
boxFilter_3(src.nativeObj, dst.nativeObj, ddepth, ksize.width, ksize.height);
return;
}
// C++: void cv::boxFilter(Mat src, Mat& dst, int ddepth, Size ksize, Point anchor = Point(-1,-1), bool normalize = true, int borderType = BORDER_DEFAULT)
private static native void boxFilter_0(long src_nativeObj, long dst_nativeObj, int ddepth, double ksize_width, double ksize_height, double anchor_x, double anchor_y, boolean normalize, int borderType);
private static native void boxFilter_1(long src_nativeObj, long dst_nativeObj, int ddepth, double ksize_width, double ksize_height, double anchor_x, double anchor_y, boolean normalize);
private static native void boxFilter_2(long src_nativeObj, long dst_nativeObj, int ddepth, double ksize_width, double ksize_height, double anchor_x, double anchor_y);
private static native void boxFilter_3(long src_nativeObj, long dst_nativeObj, int ddepth, double ksize_width, double ksize_height);
复制代码
使用 box 滤波器模糊图像,使用的核以下:
非归一化的box滤波器在计算像素邻域的各类积分特性颇有用,例如图像导数的协方差矩阵(用于密集光流算法等)。若是计算可变大小窗口里的像素总和,须要使用积分。
buildPyramid
只有C++的实现,暂未提供其余语言接口。
方法声明:
c++
void cv::buildPyramid ( InputArray src,
OutputArrayOfArrays dst,
int maxlevel,
int borderType = BORDER_DEFAULT
)
复制代码
该方法构造一个图像矢量,并经过从 dst[0] == src 开始递归地将 pyrDown(向下采样)应用与先前构建地金字塔图层来构建图像的高斯金字塔。
dilate
方法声明:
c++
void cv::dilate ( InputArray src,
OutputArray dst,
InputArray kernel,
Point anchor = Point(-1,-1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar & borderValue = morphologyDefaultBorderValue()
)
复制代码
java
public static void dilate(Mat src, Mat dst, Mat kernel) {
dilate_4(src.nativeObj, dst.nativeObj, kernel.nativeObj);
return;
}
// C++: void cv::dilate(Mat src, Mat& dst, Mat kernel, Point anchor = Point(-1,-1), int iterations = 1, int borderType = BORDER_CONSTANT, Scalar borderValue = morphologyDefaultBorderValue())
private static native void dilate_0(long src_nativeObj, long dst_nativeObj, long kernel_nativeObj, double anchor_x, double anchor_y, int iterations, int borderType, double borderValue_val0, double borderValue_val1, double borderValue_val2, double borderValue_val3);
private static native void dilate_1(long src_nativeObj, long dst_nativeObj, long kernel_nativeObj, double anchor_x, double anchor_y, int iterations, int borderType);
private static native void dilate_2(long src_nativeObj, long dst_nativeObj, long kernel_nativeObj, double anchor_x, double anchor_y, int iterations);
private static native void dilate_3(long src_nativeObj, long dst_nativeObj, long kernel_nativeObj, double anchor_x, double anchor_y);
private static native void dilate_4(long src_nativeObj, long dst_nativeObj, long kernel_nativeObj);
复制代码
使用指定的 structuring element 膨胀图像,structuring element用来肯定采用最大值的像素邻域的形状。
该方法支持就地模式。膨胀能够屡次(迭代)应用。对于多通道图像,每一个通道被单独处理。
erode
方法声明
c++
void cv::erode ( InputArray src,
OutputArray dst,
InputArray kernel,
Point anchor = Point(-1,-1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar & borderValue = morphologyDefaultBorderValue()
)
复制代码
java
public static void erode(Mat src, Mat dst, Mat kernel) {
erode_4(src.nativeObj, dst.nativeObj, kernel.nativeObj);
return;
}
// C++: void cv::erode(Mat src, Mat& dst, Mat kernel, Point anchor = Point(-1,-1), int iterations = 1, int borderType = BORDER_CONSTANT, Scalar borderValue = morphologyDefaultBorderValue())
private static native void erode_0(long src_nativeObj, long dst_nativeObj, long kernel_nativeObj, double anchor_x, double anchor_y, int iterations, int borderType, double borderValue_val0, double borderValue_val1, double borderValue_val2, double borderValue_val3);
private static native void erode_1(long src_nativeObj, long dst_nativeObj, long kernel_nativeObj, double anchor_x, double anchor_y, int iterations, int borderType);
private static native void erode_2(long src_nativeObj, long dst_nativeObj, long kernel_nativeObj, double anchor_x, double anchor_y, int iterations);
private static native void erode_3(long src_nativeObj, long dst_nativeObj, long kernel_nativeObj, double anchor_x, double anchor_y);
private static native void erode_4(long src_nativeObj, long dst_nativeObj, long kernel_nativeObj);
复制代码
使用指定的 structuring element 腐蚀图像,structuring element用来肯定采用最小值的像素邻域的形状。
该方法支持就地模式。腐蚀能够屡次(迭代)应用。对于多通道图像,每一个通道被单独处理。
filter2D
方法声明:
c++
void cv::filter2D ( InputArray src,
OutputArray dst,
int ddepth,
InputArray kernel,
Point anchor = Point(-1,-1),
double delta = 0,
int borderType = BORDER_DEFAULT
)
复制代码
java
public static void sepFilter2D(Mat src, Mat dst, int ddepth, Mat kernelX, Mat kernelY) {
sepFilter2D_3(src.nativeObj, dst.nativeObj, ddepth, kernelX.nativeObj, kernelY.nativeObj);
return;
}
// C++: void cv::sepFilter2D(Mat src, Mat& dst, int ddepth, Mat kernelX, Mat kernelY, Point anchor = Point(-1,-1), double delta = 0, int borderType = BORDER_DEFAULT)
private static native void sepFilter2D_0(long src_nativeObj, long dst_nativeObj, int ddepth, long kernelX_nativeObj, long kernelY_nativeObj, double anchor_x, double anchor_y, double delta, int borderType);
private static native void sepFilter2D_1(long src_nativeObj, long dst_nativeObj, int ddepth, long kernelX_nativeObj, long kernelY_nativeObj, double anchor_x, double anchor_y, double delta);
private static native void sepFilter2D_2(long src_nativeObj, long dst_nativeObj, int ddepth, long kernelX_nativeObj, long kernelY_nativeObj, double anchor_x, double anchor_y);
private static native void sepFilter2D_3(long src_nativeObj, long dst_nativeObj, int ddepth, long kernelX_nativeObj, long kernelY_nativeObj);
复制代码
使用核(kernel)对图像进行卷积。
该方法能够对图像应用任意的线性滤波器,支持就地操做,当滤波范围部分超出图像时,该方法根据指定的像素外推模式向边界外像素插入值。
该方法实际上时计算的相关性,不是卷积,也就是说,内核不是围绕锚点镜像的,若是须要真正进行卷积,则使用 flip 对内核进行反转,并设置新的锚点为 (kernel.cols - anchor.x - 1, kernel.rows - anchor.y - 1)
:
针对特别大的核(11x11,或者更大),该方法使用基于 DFT-based 的算法;对于小核使用直接算法。
GaussianBlur
方法声明:
c++
void cv::GaussianBlur ( InputArray src,
OutputArray dst,
Size ksize,
double sigmaX,
double sigmaY = 0,
int borderType = BORDER_DEFAULT
)
复制代码
java
public static void GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX, double sigmaY, int borderType) {
GaussianBlur_0(src.nativeObj, dst.nativeObj, ksize.width, ksize.height, sigmaX, sigmaY, borderType);
return;
}
// C++: void cv::GaussianBlur(Mat src, Mat& dst, Size ksize, double sigmaX, double sigmaY = 0, int borderType = BORDER_DEFAULT)
private static native void GaussianBlur_0(long src_nativeObj, long dst_nativeObj, double ksize_width, double ksize_height, double sigmaX, double sigmaY, int borderType);
private static native void GaussianBlur_1(long src_nativeObj, long dst_nativeObj, double ksize_width, double ksize_height, double sigmaX, double sigmaY);
private static native void GaussianBlur_2(long src_nativeObj, long dst_nativeObj, double ksize_width, double ksize_height, double sigmaX);
复制代码
使用高斯滤波器模糊图像,使用高斯内核与图像作卷积,支持就地模式。
getGaborKernel()
方法声明:
c++
Mat cv::getGaborKernel ( Size ksize,
double sigma,
double theta,
double lambd,
double gamma,
double psi = CV_PI *0.5,
int ktype = CV_64F
)
复制代码
java
//javadoc: getGaborKernel(ksize, sigma, theta, lambd, gamma, psi, ktype)
public static Mat getGaborKernel(Size ksize, double sigma, double theta, double lambd, double gamma, double psi, int ktype) {
Mat retVal = new Mat(getGaborKernel_0(ksize.width, ksize.height, sigma, theta, lambd, gamma, psi, ktype));
return retVal;
}
//javadoc: getGaborKernel(ksize, sigma, theta, lambd, gamma, psi)
public static Mat getGaborKernel(Size ksize, double sigma, double theta, double lambd, double gamma, double psi) {
Mat retVal = new Mat(getGaborKernel_1(ksize.width, ksize.height, sigma, theta, lambd, gamma, psi));
return retVal;
}
//javadoc: getGaborKernel(ksize, sigma, theta, lambd, gamma)
public static Mat getGaborKernel(Size ksize, double sigma, double theta, double lambd, double gamma) {
Mat retVal = new Mat(getGaborKernel_2(ksize.width, ksize.height, sigma, theta, lambd, gamma));
return retVal;
}
// C++: Mat cv::getGaborKernel(Size ksize, double sigma, double theta, double lambd, double gamma, double psi = CV_PI*0.5, int ktype = CV_64F)
private static native long getGaborKernel_0(double ksize_width, double ksize_height, double sigma, double theta, double lambd, double gamma, double psi, int ktype);
private static native long getGaborKernel_1(double ksize_width, double ksize_height, double sigma, double theta, double lambd, double gamma, double psi);
private static native long getGaborKernel_2(double ksize_width, double ksize_height, double sigma, double theta, double lambd, double gamma);
复制代码
返回一个 Gabor 滤波器系数,详细的 gabor 滤波器参见 Gabor Filter
getGaussianKernel()
方法声明:
c++
Mat cv::getGaussianKernel ( int ksize,
double sigma,
int ktype = CV_64F
)
复制代码
java
//javadoc: getGaussianKernel(ksize, sigma, ktype)
public static Mat getGaussianKernel(int ksize, double sigma, int ktype) {
Mat retVal = new Mat(getGaussianKernel_0(ksize, sigma, ktype));
return retVal;
}
//javadoc: getGaussianKernel(ksize, sigma)
public static Mat getGaussianKernel(int ksize, double sigma) {
Mat retVal = new Mat(getGaussianKernel_1(ksize, sigma));
return retVal;
}
// C++: Mat cv::getGaussianKernel(int ksize, double sigma, int ktype = CV_64F)
private static native long getGaussianKernel_0(int ksize, double sigma, int ktype);
private static native long getGaussianKernel_1(int ksize, double sigma);
复制代码
返回一个高斯滤波器系数。
该方法计算并返回ksize×1高斯滤波器系数矩阵:
生成的两种kernel均可以传递给 sepFilter2D,方法会自动识别 平滑kernel(对称,权重和为1),而后相应的处理。也可使用相对高层次的高斯模糊(GaoussianBlur)。
sigma = 0.3*((ksize-1)*0.5 - 1) + 0.8
getStructuringElement()
方法声明:
c++
Mat cv::getStructuringElement ( int shape,
Size ksize,
Point anchor = Point(-1,-1)
)
复制代码
java
public static Mat getStructuringElement(int shape, Size ksize) {
Mat retVal = new Mat(getStructuringElement_1(shape, ksize.width, ksize.height));
return retVal;
}
// C++: Mat cv::getStructuringElement(int shape, Size ksize, Point anchor = Point(-1,-1))
private static native long getStructuringElement_0(int shape, double ksize_width, double ksize_height, double anchor_x, double anchor_y);
private static native long getStructuringElement_1(int shape, double ksize_width, double ksize_height);
复制代码
为形态操做返回指定大小和形状的structuring element,进一步传递给 erode,dilate,morphologyEx。可是也能够本身构造一个任意的二进制掩码,并将其用做structuring element。
拉普拉斯算子
方法声明:
c++
void cv::Laplacian ( InputArray src,
OutputArray dst,
int ddepth,
int ksize = 1,
double scale = 1,
double delta = 0,
int borderType = BORDER_DEFAULT
)
复制代码
java
public static void Laplacian(Mat src, Mat dst, int ddepth) {
Laplacian_4(src.nativeObj, dst.nativeObj, ddepth);
return;
}
private static native void Laplacian_0(long src_nativeObj, long dst_nativeObj, int ddepth, int ksize, double scale, double delta, int borderType);
private static native void Laplacian_1(long src_nativeObj, long dst_nativeObj, int ddepth, int ksize, double scale, double delta);
private static native void Laplacian_2(long src_nativeObj, long dst_nativeObj, int ddepth, int ksize, double scale);
private static native void Laplacian_3(long src_nativeObj, long dst_nativeObj, int ddepth, int ksize);
private static native void Laplacian_4(long src_nativeObj, long dst_nativeObj, int ddepth);
复制代码
该方法经过Sobel算子计算源图像二阶x、y导数,而后相加得出源图像的拉普拉斯算子:
须要注意的是,当 ksize>1 时用上述公式计算拉普拉斯算子;当 ksize=1 时,拉普拉斯算子经过使用3x3的窗口对图片进行滤波获得。
中值模糊
方法声明:
c++
void cv::medianBlur ( InputArray src,
OutputArray dst,
int ksize
)
复制代码
java
public static void medianBlur(Mat src, Mat dst, int ksize) {
medianBlur_0(src.nativeObj, dst.nativeObj, ksize);
return;
}
private static native void medianBlur_0(long src_nativeObj, long dst_nativeObj, int ksize);
复制代码
使用ksize X ksize 大小的窗口的中值滤波器对图像作平滑处理,图像的各个通道单独处理。该方法支持就地操做。
中值滤波器内部使用 BORDER_REPLICATE 的外推模式复制边界像素。
morphologyDefaultBorderValue()
方法声明
c++
static Scalar cv::morphologyDefaultBorderValue()
复制代码
java 中没有直接调用该方法的接口,使用膨胀、腐蚀操做时,内部自动调用c++方法对相应参数进行赋值。
返回图像膨胀和腐蚀的 magic 边界值。当膨胀时,会自动转换为 Scalar::all(-DBL_MAX)。
morphologyEx
方法声明:
c++
void cv::morphologyEx ( InputArray src,
OutputArray dst,
int op,
InputArray kernel,
Point anchor = Point(-1,-1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar & borderValue = morphologyDefaultBorderValue()
)
复制代码
java
//javadoc: morphologyEx(src, dst, op, kernel, anchor, iterations, borderType, borderValue)
public static void morphologyEx(Mat src, Mat dst, int op, Mat kernel, Point anchor, int iterations, int borderType, Scalar borderValue) {
morphologyEx_0(src.nativeObj, dst.nativeObj, op, kernel.nativeObj, anchor.x, anchor.y, iterations, borderType, borderValue.val[0], borderValue.val[1], borderValue.val[2], borderValue.val[3]);
return;
}
//javadoc: morphologyEx(src, dst, op, kernel, anchor, iterations, borderType)
public static void morphologyEx(Mat src, Mat dst, int op, Mat kernel, Point anchor, int iterations, int borderType) {
morphologyEx_1(src.nativeObj, dst.nativeObj, op, kernel.nativeObj, anchor.x, anchor.y, iterations, borderType);
return;
}
//javadoc: morphologyEx(src, dst, op, kernel, anchor, iterations)
public static void morphologyEx(Mat src, Mat dst, int op, Mat kernel, Point anchor, int iterations) {
morphologyEx_2(src.nativeObj, dst.nativeObj, op, kernel.nativeObj, anchor.x, anchor.y, iterations);
return;
}
//javadoc: morphologyEx(src, dst, op, kernel, anchor)
public static void morphologyEx(Mat src, Mat dst, int op, Mat kernel, Point anchor) {
morphologyEx_3(src.nativeObj, dst.nativeObj, op, kernel.nativeObj, anchor.x, anchor.y);
return;
}
//javadoc: morphologyEx(src, dst, op, kernel)
public static void morphologyEx(Mat src, Mat dst, int op, Mat kernel) {
morphologyEx_4(src.nativeObj, dst.nativeObj, op, kernel.nativeObj);
return;
}
// C++: void cv::morphologyEx(Mat src, Mat& dst, int op, Mat kernel, Point anchor = Point(-1,-1), int iterations = 1, int borderType = BORDER_CONSTANT, Scalar borderValue = morphologyDefaultBorderValue())
private static native void morphologyEx_0(long src_nativeObj, long dst_nativeObj, int op, long kernel_nativeObj, double anchor_x, double anchor_y, int iterations, int borderType, double borderValue_val0, double borderValue_val1, double borderValue_val2, double borderValue_val3);
private static native void morphologyEx_1(long src_nativeObj, long dst_nativeObj, int op, long kernel_nativeObj, double anchor_x, double anchor_y, int iterations, int borderType);
private static native void morphologyEx_2(long src_nativeObj, long dst_nativeObj, int op, long kernel_nativeObj, double anchor_x, double anchor_y, int iterations);
private static native void morphologyEx_3(long src_nativeObj, long dst_nativeObj, int op, long kernel_nativeObj, double anchor_x, double anchor_y);
private static native void morphologyEx_4(long src_nativeObj, long dst_nativeObj, int op, long kernel_nativeObj);
复制代码
基于膨胀、腐蚀对图像作加强形态变换。
全部操做均可以就地进行,多个通道会被独立处理。
须要注意的是,iteration 的值表示的是腐蚀、膨胀应用的次数,例如图像的开操做,iteration是2,等价于 erode -> erode -> dilate -> dilate,而不是 erode -> dilate -> erode -> dilate。
pyrDown()
方法声明:
c++
void cv::pyrDown ( InputArray src,
OutputArray dst,
const Size & dstsize = Size(),
int borderType = BORDER_DEFAULT
)
复制代码
java
public static void pyrDown(Mat src, Mat dst) {
pyrDown_2(src.nativeObj, dst.nativeObj);
return;
}
private static native void pyrDown_0(long src_nativeObj, long dst_nativeObj, double dstsize_width, double dstsize_height, int borderType);
private static native void pyrDown_1(long src_nativeObj, long dst_nativeObj, double dstsize_width, double dstsize_height);
private static native void pyrDown_2(long src_nativeObj, long dst_nativeObj);
复制代码
使用向下采样模糊图像。
默认状况下,输出图像的大小为 Size((src.cols+1)/2, (src.rows+1)/2)
。可是如论何时都要知足以下条件:
该方法为建立图像的高斯金字塔执行向下采样的步骤。
首先使用以下kernel对图像进行卷积
而后,舍弃偶数行和列来对图像进行下采样。
pyrMeanShiftFiltering()
方法声明:
c++
void cv::pyrMeanShiftFiltering ( InputArray src,
OutputArray dst,
double sp,
double sr,
int maxLevel = 1,
TermCriteria termcrit = TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 5, 1)
)
复制代码
java
//javadoc: pyrMeanShiftFiltering(src, dst, sp, sr, maxLevel, termcrit)
public static void pyrMeanShiftFiltering(Mat src, Mat dst, double sp, double sr, int maxLevel, TermCriteria termcrit) {
pyrMeanShiftFiltering_0(src.nativeObj, dst.nativeObj, sp, sr, maxLevel, termcrit.type, termcrit.maxCount, termcrit.epsilon);
return;
}
//javadoc: pyrMeanShiftFiltering(src, dst, sp, sr, maxLevel)
public static void pyrMeanShiftFiltering(Mat src, Mat dst, double sp, double sr, int maxLevel) {
pyrMeanShiftFiltering_1(src.nativeObj, dst.nativeObj, sp, sr, maxLevel);
return;
}
//javadoc: pyrMeanShiftFiltering(src, dst, sp, sr)
public static void pyrMeanShiftFiltering(Mat src, Mat dst, double sp, double sr) {
pyrMeanShiftFiltering_2(src.nativeObj, dst.nativeObj, sp, sr);
return;
}
private static native void pyrMeanShiftFiltering_0(long src_nativeObj, long dst_nativeObj, double sp, double sr, int maxLevel, int termcrit_type, int termcrit_maxCount, double termcrit_epsilon);
private static native void pyrMeanShiftFiltering_1(long src_nativeObj, long dst_nativeObj, double sp, double sr, int maxLevel);
private static native void pyrMeanShiftFiltering_2(long src_nativeObj, long dst_nativeObj, double sp, double sr);
复制代码
执行图像 meanshift分割的滤波阶段。
这个函数严格来讲并非图像的分割,而是图像在色彩层面的平滑滤波,它能够中和色彩分布相近的颜色,平滑色彩细节,侵蚀掉面积较小的颜色区域。(引自:Opencv均值漂移pyrMeanShiftFiltering彩色图像分割流程剖析)
可以去除局部类似的纹理,同时保留边缘等差别较大的特征。(引自:学习OpenCV2——MeanShift之图形分割)
对于每一个像素(x,y),该方法迭代的进行meanshift,像素的邻域不只考虑空间,还考虑色彩,即从 空间-色彩 的超空间中选取像素的邻域。
其中,能够不是 (R,G,B) 颜色空间,只要是3份量构成的颜色空间便可。
在邻域中找到平均空间值(X',Y')和平均颜色向量(R',G',B'),做为下一个迭代的邻域中心:
迭代结束后,初始像素的颜色份量(即迭代开始的像素)设置为最终值(最后一次迭代的平均颜色):
在图像高斯金字塔上,当maxLevel>0时,上述过程最早从maxLevel+1图层开始。计算结束后,结果传递给大一级的图层,并只在与上层图层相比,颜色差别大于sr的像素上再次运行迭代,可以使得颜色区域的边界更加清晰。须要注意的是,在金字塔上运行的结果与对整个原始图像(即maxLevel==0时)直接运行meanshift过程获得的结果不一样。
pyrUp()
方法声明:
c++
void cv::pyrUp ( InputArray src,
OutputArray dst,
const Size & dstsize = Size(),
int borderType = BORDER_DEFAULT
)
复制代码
java
//javadoc: pyrUp(src, dst, dstsize, borderType)
public static void pyrUp(Mat src, Mat dst, Size dstsize, int borderType) {
pyrUp_0(src.nativeObj, dst.nativeObj, dstsize.width, dstsize.height, borderType);
return;
}
//javadoc: pyrUp(src, dst, dstsize)
public static void pyrUp(Mat src, Mat dst, Size dstsize) {
pyrUp_1(src.nativeObj, dst.nativeObj, dstsize.width, dstsize.height);
return;
}
//javadoc: pyrUp(src, dst)
public static void pyrUp(Mat src, Mat dst) {
pyrUp_2(src.nativeObj, dst.nativeObj);
return;
}
// C++: void cv::pyrUp(Mat src, Mat& dst, Size dstsize = Size(), int borderType = BORDER_DEFAULT)
private static native void pyrUp_0(long src_nativeObj, long dst_nativeObj, double dstsize_width, double dstsize_height, int borderType);
private static native void pyrUp_1(long src_nativeObj, long dst_nativeObj, double dstsize_width, double dstsize_height);
private static native void pyrUp_2(long src_nativeObj, long dst_nativeObj);
复制代码
对图像向上采样,而后进行模糊处理。
默认状况下,输出图像的大小为Size(src.cols\*2, (src.rows\*2)
。可是,不管什么状况,都应该知足如下条件:
该方法能够执行高斯金字塔建立的向上采样步骤,也能够用于拉普拉斯金子塔的建立。
首先经过注入0值行、0值列对源图像进行向上采样,即放大图像;而后将向下采样使用的kernel乘以4,做为新kernel对进行卷积,对放大的图像进行卷积。
Scharr()
方法声明:
c++
void cv::Scharr ( InputArray src,
OutputArray dst,
int ddepth,
int dx,
int dy,
double scale = 1,
double delta = 0,
int borderType = BORDER_DEFAULT
)
复制代码
java
//javadoc: Scharr(src, dst, ddepth, dx, dy, scale, delta, borderType)
public static void Scharr(Mat src, Mat dst, int ddepth, int dx, int dy, double scale, double delta, int borderType) {
Scharr_0(src.nativeObj, dst.nativeObj, ddepth, dx, dy, scale, delta, borderType);
return;
}
//javadoc: Scharr(src, dst, ddepth, dx, dy, scale, delta)
public static void Scharr(Mat src, Mat dst, int ddepth, int dx, int dy, double scale, double delta) {
Scharr_1(src.nativeObj, dst.nativeObj, ddepth, dx, dy, scale, delta);
return;
}
//javadoc: Scharr(src, dst, ddepth, dx, dy, scale)
public static void Scharr(Mat src, Mat dst, int ddepth, int dx, int dy, double scale) {
Scharr_2(src.nativeObj, dst.nativeObj, ddepth, dx, dy, scale);
return;
}
//javadoc: Scharr(src, dst, ddepth, dx, dy)
public static void Scharr(Mat src, Mat dst, int ddepth, int dx, int dy) {
Scharr_3(src.nativeObj, dst.nativeObj, ddepth, dx, dy);
return;
}
// C++: void cv::Scharr(Mat src, Mat& dst, int ddepth, int dx, int dy, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT)
private static native void Scharr_0(long src_nativeObj, long dst_nativeObj, int ddepth, int dx, int dy, double scale, double delta, int borderType);
private static native void Scharr_1(long src_nativeObj, long dst_nativeObj, int ddepth, int dx, int dy, double scale, double delta);
private static native void Scharr_2(long src_nativeObj, long dst_nativeObj, int ddepth, int dx, int dy, double scale);
private static native void Scharr_3(long src_nativeObj, long dst_nativeObj, int ddepth, int dx, int dy);
复制代码
使用 Scharr 运算计算图像的x-或者y-的一阶导数。调用方法Scharr(src, dst, ddepth, dx, dy, scale, delta, borderType)
等价于调用方法Sobel(src, dst, ddepth, dx, dy, CV_SCHARR, scale, delta, borderType)
sepFilter2D()
方法声明:
c++
void cv::sepFilter2D ( InputArray src,
OutputArray dst,
int ddepth,
InputArray kernelX,
InputArray kernelY,
Point anchor = Point(-1,-1),
double delta = 0,
int borderType = BORDER_DEFAULT
)
复制代码
java
//javadoc: sepFilter2D(src, dst, ddepth, kernelX, kernelY, anchor, delta, borderType)
public static void sepFilter2D(Mat src, Mat dst, int ddepth, Mat kernelX, Mat kernelY, Point anchor, double delta, int borderType) {
sepFilter2D_0(src.nativeObj, dst.nativeObj, ddepth, kernelX.nativeObj, kernelY.nativeObj, anchor.x, anchor.y, delta, borderType);
return;
}
//javadoc: sepFilter2D(src, dst, ddepth, kernelX, kernelY, anchor, delta)
public static void sepFilter2D(Mat src, Mat dst, int ddepth, Mat kernelX, Mat kernelY, Point anchor, double delta) {
sepFilter2D_1(src.nativeObj, dst.nativeObj, ddepth, kernelX.nativeObj, kernelY.nativeObj, anchor.x, anchor.y, delta);
return;
}
//javadoc: sepFilter2D(src, dst, ddepth, kernelX, kernelY, anchor)
public static void sepFilter2D(Mat src, Mat dst, int ddepth, Mat kernelX, Mat kernelY, Point anchor) {
sepFilter2D_2(src.nativeObj, dst.nativeObj, ddepth, kernelX.nativeObj, kernelY.nativeObj, anchor.x, anchor.y);
return;
}
//javadoc: sepFilter2D(src, dst, ddepth, kernelX, kernelY)
public static void sepFilter2D(Mat src, Mat dst, int ddepth, Mat kernelX, Mat kernelY) {
sepFilter2D_3(src.nativeObj, dst.nativeObj, ddepth, kernelX.nativeObj, kernelY.nativeObj);
return;
}
// C++: void cv::sepFilter2D(Mat src, Mat& dst, int ddepth, Mat kernelX, Mat kernelY, Point anchor = Point(-1,-1), double delta = 0, int borderType = BORDER_DEFAULT)
private static native void sepFilter2D_0(long src_nativeObj, long dst_nativeObj, int ddepth, long kernelX_nativeObj, long kernelY_nativeObj, double anchor_x, double anchor_y, double delta, int borderType);
private static native void sepFilter2D_1(long src_nativeObj, long dst_nativeObj, int ddepth, long kernelX_nativeObj, long kernelY_nativeObj, double anchor_x, double anchor_y, double delta);
private static native void sepFilter2D_2(long src_nativeObj, long dst_nativeObj, int ddepth, long kernelX_nativeObj, long kernelY_nativeObj, double anchor_x, double anchor_y);
private static native void sepFilter2D_3(long src_nativeObj, long dst_nativeObj, int ddepth, long kernelX_nativeObj, long kernelY_nativeObj);
复制代码
对图像使用可分离的线性滤波器。首先使用一维kernel(kernelX)对源图像的每一行进行过滤;而后使用一维kernel(kernelY)对结果的每一列进行过滤;最后根据delta对结果进行位移,存储在输出图像中。
Sobel()
方法声明:
c++
void cv::Sobel ( InputArray src,
OutputArray dst,
int ddepth,
int dx,
int dy,
int ksize = 3,
double scale = 1,
double delta = 0,
int borderType = BORDER_DEFAULT
)
复制代码
java
//javadoc: Sobel(src, dst, ddepth, dx, dy, ksize, scale, delta, borderType)
public static void Sobel(Mat src, Mat dst, int ddepth, int dx, int dy, int ksize, double scale, double delta, int borderType) {
Sobel_0(src.nativeObj, dst.nativeObj, ddepth, dx, dy, ksize, scale, delta, borderType);
return;
}
//javadoc: Sobel(src, dst, ddepth, dx, dy, ksize, scale, delta)
public static void Sobel(Mat src, Mat dst, int ddepth, int dx, int dy, int ksize, double scale, double delta) {
Sobel_1(src.nativeObj, dst.nativeObj, ddepth, dx, dy, ksize, scale, delta);
return;
}
//javadoc: Sobel(src, dst, ddepth, dx, dy, ksize, scale)
public static void Sobel(Mat src, Mat dst, int ddepth, int dx, int dy, int ksize, double scale) {
Sobel_2(src.nativeObj, dst.nativeObj, ddepth, dx, dy, ksize, scale);
return;
}
//javadoc: Sobel(src, dst, ddepth, dx, dy, ksize)
public static void Sobel(Mat src, Mat dst, int ddepth, int dx, int dy, int ksize) {
Sobel_3(src.nativeObj, dst.nativeObj, ddepth, dx, dy, ksize);
return;
}
//javadoc: Sobel(src, dst, ddepth, dx, dy)
public static void Sobel(Mat src, Mat dst, int ddepth, int dx, int dy) {
Sobel_4(src.nativeObj, dst.nativeObj, ddepth, dx, dy);
return;
}
// C++: void cv::Sobel(Mat src, Mat& dst, int ddepth, int dx, int dy, int ksize = 3, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT)
private static native void Sobel_0(long src_nativeObj, long dst_nativeObj, int ddepth, int dx, int dy, int ksize, double scale, double delta, int borderType);
private static native void Sobel_1(long src_nativeObj, long dst_nativeObj, int ddepth, int dx, int dy, int ksize, double scale, double delta);
private static native void Sobel_2(long src_nativeObj, long dst_nativeObj, int ddepth, int dx, int dy, int ksize, double scale);
private static native void Sobel_3(long src_nativeObj, long dst_nativeObj, int ddepth, int dx, int dy, int ksize);
private static native void Sobel_4(long src_nativeObj, long dst_nativeObj, int ddepth, int dx, int dy);
复制代码
使用扩展sobel运算计算图像的一阶、二阶、三阶、混合导数。
在全部状况下,只有一个除外,ksize×ksize分离内核用于计算导数。当ksize = 1,3×1或1×3内核使用(也就是说,没有进行高斯平滑)。ksize = 1只能用于x或y的二阶导数。
另外还有一个特殊值,当ksize = CV_SCHARR (-1)
时,相应的3x3 Scharr滤波器可能比 3x3的sobel滤波器更准确。对于x导数和y导数的转置,Schar窗口以下:
该方法经过将图像与适当的kernel卷积来计算图像的导数:
Sobel算子结合了高斯平滑和微分,因此结果或多或少能抵抗噪声。
一般,函数被调用(xorder = 1, yorder = 0, ksize = 3)或(xorder = 0, yorder = 1, ksize = 3)来计算第一个x或y图像的导数。
第一种状况的kernel:
第二种状况的kernel:
spatialGradient()
方法声明:
c++
void cv::spatialGradient ( InputArray src,
OutputArray dx,
OutputArray dy,
int ksize = 3,
int borderType = BORDER_DEFAULT
)
复制代码
java
//javadoc: spatialGradient(src, dx, dy, ksize, borderType)
public static void spatialGradient(Mat src, Mat dx, Mat dy, int ksize, int borderType) {
spatialGradient_0(src.nativeObj, dx.nativeObj, dy.nativeObj, ksize, borderType);
return;
}
//javadoc: spatialGradient(src, dx, dy, ksize)
public static void spatialGradient(Mat src, Mat dx, Mat dy, int ksize) {
spatialGradient_1(src.nativeObj, dx.nativeObj, dy.nativeObj, ksize);
return;
}
//javadoc: spatialGradient(src, dx, dy)
public static void spatialGradient(Mat src, Mat dx, Mat dy) {
spatialGradient_2(src.nativeObj, dx.nativeObj, dy.nativeObj);
return;
}
// C++: void cv::spatialGradient(Mat src, Mat& dx, Mat& dy, int ksize = 3, int borderType = BORDER_DEFAULT)
private static native void spatialGradient_0(long src_nativeObj, long dx_nativeObj, long dy_nativeObj, int ksize, int borderType);
private static native void spatialGradient_1(long src_nativeObj, long dx_nativeObj, long dy_nativeObj, int ksize);
private static native void spatialGradient_2(long src_nativeObj, long dx_nativeObj, long dy_nativeObj);
复制代码
使用Sobel运算计算x和y的一阶图像导数。
等价于调用:
Sobel( src, dx, CV_16SC1, 1, 0, 3 );
Sobel( src, dy, CV_16SC1, 0, 1, 3 );
复制代码
sqrBoxFilter()
方法声明:
c++
void cv::sqrBoxFilter ( InputArray src,
OutputArray dst,
int ddepth,
Size ksize,
Point anchor = Point(-1, -1),
bool normalize = true,
int borderType = BORDER_DEFAULT
)
复制代码
java
//javadoc: sqrBoxFilter(_src, _dst, ddepth, ksize, anchor, normalize, borderType)
public static void sqrBoxFilter(Mat _src, Mat _dst, int ddepth, Size ksize, Point anchor, boolean normalize, int borderType) {
sqrBoxFilter_0(_src.nativeObj, _dst.nativeObj, ddepth, ksize.width, ksize.height, anchor.x, anchor.y, normalize, borderType);
return;
}
//javadoc: sqrBoxFilter(_src, _dst, ddepth, ksize, anchor, normalize)
public static void sqrBoxFilter(Mat _src, Mat _dst, int ddepth, Size ksize, Point anchor, boolean normalize) {
sqrBoxFilter_1(_src.nativeObj, _dst.nativeObj, ddepth, ksize.width, ksize.height, anchor.x, anchor.y, normalize);
return;
}
//javadoc: sqrBoxFilter(_src, _dst, ddepth, ksize, anchor)
public static void sqrBoxFilter(Mat _src, Mat _dst, int ddepth, Size ksize, Point anchor) {
sqrBoxFilter_2(_src.nativeObj, _dst.nativeObj, ddepth, ksize.width, ksize.height, anchor.x, anchor.y);
return;
}
//javadoc: sqrBoxFilter(_src, _dst, ddepth, ksize)
public static void sqrBoxFilter(Mat _src, Mat _dst, int ddepth, Size ksize) {
sqrBoxFilter_3(_src.nativeObj, _dst.nativeObj, ddepth, ksize.width, ksize.height);
return;
}
// C++: void cv::sqrBoxFilter(Mat _src, Mat& _dst, int ddepth, Size ksize, Point anchor = Point(-1, -1), bool normalize = true, int borderType = BORDER_DEFAULT)
private static native void sqrBoxFilter_0(long _src_nativeObj, long _dst_nativeObj, int ddepth, double ksize_width, double ksize_height, double anchor_x, double anchor_y, boolean normalize, int borderType);
private static native void sqrBoxFilter_1(long _src_nativeObj, long _dst_nativeObj, int ddepth, double ksize_width, double ksize_height, double anchor_x, double anchor_y, boolean normalize);
private static native void sqrBoxFilter_2(long _src_nativeObj, long _dst_nativeObj, int ddepth, double ksize_width, double ksize_height, double anchor_x, double anchor_y);
private static native void sqrBoxFilter_3(long _src_nativeObj, long _dst_nativeObj, int ddepth, double ksize_width, double ksize_height);
复制代码
计算与滤波器重叠像素值的归一化平方和。