enum ThresholdType
{
THRESHOLD_LIGHT, //明
THRESHOLD_DARK, //暗
THRESHOLD_EQUAL, //等于
THRESHOLD_NOT_EQUAL //不等于
};
//功能:通过局部均值和标准差分析对图像进行阈值处理
//参数:
// src:输入图像
// mask:掩膜
// dst:输出图像
// maskW:掩膜宽度,用于均值和偏差计算(maskW >= 1)
// maskH:掩膜高度,用于均值和偏差计算(maskH >= 1)
// StdDevScale:灰度值标准差的因数
// AbsThreshold:与平均值的最小灰度值差异
// type:
// g(x,y):是输入Image中位置(x,y)处的灰度值
// m(x,y):对应的平均灰度值
// d(x,y):围绕该像素的遮罩中的相应标准偏差
// THRESHOLD_LIGHT(明): g(x,y) ≥ m(x,y) + d(x,y)
// THRESHOLD_DARK(暗): g(x,y) ≤ m(x,y) - d(x,y)
// THRESHOLD_EQUAL(等于): m(x,y) - d(x,y) ≤ g(x,y) ≤ m(x,y) + d(x,y)
// THRESHOLD_NOT_EQUAL(不等于): m(x,y) - d(x,y) > g(x,y) || g(x,y) > m(x,y) + d(x,y)
//返回值:无
void var_threshold(Mat src, Mat mask, Mat &dst,
int maskW, int maskH, float StdDevScale,
float AbsThreshold, ThresholdType type)
{
dst = Mat(src.size(), CV_8UC1, Scalar(0));
int width = maskW;
int height = maskH;
if (maskW % 2 == 0)
width++;
if (maskH % 2 == 0)
height++;
int rows = src.rows;
int cols = src.cols;
int minW = width / 2;
int minH = height / 2;
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
if (mask.at<uchar>(row, col) > 0)
{
vector<float> grays;
float sum = 0;
int i, j;
if (row - minH < 0)
i = 0;
else
i = row - minH;
for (; i <= row + minH && i < rows; i++)
{
if (col - minW < 0)
j = 0;
else
j = col - minW;
for (; j <= col + minW && j < cols; j++)
{
if (mask.at<uchar>(i, j) > 0)
{
int gray = src.at<uchar>(i, j);
grays.push_back(gray);
sum += gray;
}
}
}
float average = sum / grays.size();
float stdValue = StdDeviation(grays, average);
float limit = 0;
if (StdDevScale >= 0)
{
limit = std::max(StdDevScale * stdValue, AbsThreshold);
}
else if (StdDevScale < 0)
{
limit = std::min(StdDevScale * stdValue, AbsThreshold);
}
int g_src = src.at<uchar>(row, col);
if (type == THRESHOLD_LIGHT)
{
if (g_src >= average + limit)
dst.at<uchar>(row, col) = 255;
}
else if (type == THRESHOLD_DARK)
{
if (g_src <= average - limit)
dst.at<uchar>(row, col) = 255;
}
else if (type == THRESHOLD_EQUAL)
{
if (g_src >= average - limit && g_src <= average + limit)
dst.at<uchar>(row, col) = 255;
}
else if (type == THRESHOLD_NOT_EQUAL)
{
if (g_src < average - limit || g_src > average + limit)
dst.at<uchar>(row, col) = 255;
}
}
}
}
}
//功能:求标准差
//参数:
// numbers:求标准差的数组
// average:该数组的平均值
//返回值:求得的标准差
float StdDeviation(vector<float> numbers, float average)
{
int count = numbers.size();
float sum = 0;
for (int i = 0; i < count; i++)
sum += (numbers[i] - average) * (numbers[i] - average);
if (0 == count)
{
return 0;
}
return sqrt(sum / count);
}
OpenCV实现halcon的var_threshold函数
于 2021-06-30 16:44:21 首次发布