前言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);
複製代碼
計算與濾波器重疊像素值的歸一化平方和。