概念:
adaptiveThreshold(),即对矩阵采用自适应阈值操作;
函数原型如下:
The function can process the image in-place.
@param src Source 8-bit single-channel image.
@param dst Destination image of the same size and the same type as src.
@param maxValue Non-zero value assigned to the pixels for which the condition is satisfied
@param adaptiveMethod Adaptive thresholding algorithm to use, see #AdaptiveThresholdTypes.
The #BORDER_REPLICATE | #BORDER_ISOLATED is used to process boundaries.
@param thresholdType Thresholding type that must be either #THRESH_BINARY or #THRESH_BINARY_INV,
see #ThresholdTypes.
@param blockSize Size of a pixel neighborhood that is used to calculate a threshold value for the
pixel: 3, 5, 7, and so on.
@param C Constant subtracted from the mean or weighted mean (see the details below). Normally, it
is positive(正数) but may be zero or negative (负数)as well.
@sa threshold, blur, GaussianBlur
*/
CV_EXPORTS_W void adaptiveThreshold( InputArray src, OutputArray dst,
double maxValue, int adaptiveMethod,
int thresholdType, int blockSize, double C );
主要参数:
scr::8位单通道的图片。
maxValue:给像素赋的满足条件的非零值。
adaptiveMethod:即 #ADAPTIVE_THRESH_MEAN_C (均值)
ADAPTIVE_THRESH_GAUSSIAN_C( 高斯)
enum AdaptiveThresholdTypes {
/** the threshold value \f$T(x,y)\f$ is a mean of the \f$\texttt{blockSize} \times
\texttt{blockSize}\f$ neighborhood of \f$(x, y)\f$ minus C */
ADAPTIVE_THRESH_MEAN_C = 0,
/** the threshold value \f$T(x, y)\f$ is a weighted sum (cross-correlation with a Gaussian
window) of the \f$\texttt{blockSize} \times \texttt{blockSize}\f$ neighborhood of \f$(x, y)\f$
minus C . The default sigma (standard deviation) is used for the specified blockSize . See
#getGaussianKernel*/
ADAPTIVE_THRESH_GAUSSIAN_C = 1
};
thresholdType:虽然在OpenCV的thresholdType有多个值可以选择,但是在这里只能选择:#THRESH_BINARY or #THRESH_BINARY_INV
其余的类型可以在固定阈值函数Threshold()中使用;
enum ThresholdTypes {
THRESH_BINARY = 0, //!< \f[\texttt{dst} (x,y) = \fork{\texttt{maxval}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\f]
THRESH_BINARY_INV = 1, //!< \f[\texttt{dst} (x,y) = \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{maxval}}{otherwise}\f]
THRESH_TRUNC = 2, //!< \f[\texttt{dst} (x,y) = \fork{\texttt{threshold}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f]
THRESH_TOZERO = 3, //!< \f[\texttt{dst} (x,y) = \fork{\texttt{src}(x,y)}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\f]
THRESH_TOZERO_INV = 4, //!< \f[\texttt{dst} (x,y) = \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f]
THRESH_MASK = 7,
THRESH_OTSU = 8, //!< flag, use Otsu algorithm to choose the optimal threshold value
THRESH_TRIANGLE = 16 //!< flag, use Triangle algorithm to choose the optimal threshold value
};
C:它是一个从均值或加权均值提取的常数,可以是负数或者是零。这个参数实际上是一个偏移值调整量,用均值和高斯计算阈值后,再减或加这个值就是最终阈值。到底选用均值还是高斯计算的值,取决于#adaptiveMethod;
常量C具体用法:
此参数自适应阈值化计算大概过程是为每一个象素点单独计算的阈值,即每个像素点的阈值都是不同的,就是将该像素点周围B*B区域内的像素加权平均,然后减去一个常数C,从而得到该点的阈值。B由参数6指定,常数C由参数7指定。
ADAPTIVE_THRESH_MEAN_C,为局部邻域块的平均值,该算法是先求出块中的均值,再减去常数C。
ADAPTIVE_THRESH_GAUSSIAN_C,为局部邻域块的高斯加权和。该算法是在区域中(x, y)周围的像素根据高斯函数按照他们离中心点的距离进行加权计算,再减去常数C。
实例
#include<iostream>
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
Mat scrImage, dstImage;
int constValue;
void valueChage(int, void*)
{
adaptiveThreshold(scrImage, dstImage, 255,
ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 3, constValue);
imshow("【效果图】", dstImage);
}
int main()
{
system("color 3F");
scrImage = imread("C:\\Users\\Desktop\\5.jpg", 0);
if (!scrImage.data)
{
cout << "open erorr\n";
return -1;
}
scrImage.create(scrImage.size(), scrImage.type());
namedWindow("【效果图】");
constValue = 10;
int count = 50;
createTrackbar("常量C", "【效果图】", &constValue, count, valueChage);
valueChage(constValue, 0);
imshow("【原图】", scrImage);
while ((char)waitKey(0) == 27)
{
break;
}
return 0;
}
结果:
C=1
C=2
C=4
C=7
C=28
可见通过改变C的取值,可以去除一些细节,例如噪声;