使用 opencv 手动应用中值滤波器,与 medianBlur 函数的区别
Apply median filter manually with opencv, differences with medianBlur function
当我像这样应用中值过滤器时:
Mat medianFilter;
medianBlur(histEqu, medianFilter, 3);
如果我应用中值过滤器,我希望得到相同的结果:
Mat manualMedianFiler;
float factor = 1 / 9.0;
Mat kernelMedian = (Mat_<float>(3, 3) <<
factor, factor, factor,
factor, factor, factor,
factor, factor, factor);
filter2D(histEqu, manualMedianFiler, CV_8U, kernelMedian, Point(-1,-1), 0, 4);
结果矩阵相似,但不相等。
难道我做错了什么?应用中值滤波器的正确方法是什么?
您的manualMedianFilter
不是中值过滤器,而是均值过滤器并且对应于cv::boxFilter
。
作为对@Miki 回答的补充,我提醒您,中值滤波器是给定 N 个样本(在本例中取自围绕中心像素的 3x3 正方形)对它们的值进行排序并取中间的一个。所以给定 (1, 7, 2, 2, 1, 9, 22, 4, 5) 排序后你得到 (1, 1, 2, 2, 4, 5, 7, 9, 22) 并且中位数是 4,而平均值是 (1 + 7 + 2 + 2 + 1 + 9 + 22 + 4 + 5) / 9 = 53/9 -> 5.8.
简而言之:中值滤波器不是线性的。
在想要去除尖峰的地方首选中值滤波器。
这里有一个简单的例子:
void MedianFilter()
{
Mat image= imread("C:\Users\User\Desktop\10.jpg", 1);
Mat image1;
cvtColor(image, image1, COLOR_BGR2GRAY);
imshow("testx", image1);
uchar * data = image1.data;
vector<int> values;
for (auto index = 0; index < (image1.rows*image1.cols); index++)
{
for (size_t i = 0; i < 13; i++) \ 13 is the element to get the median from...
{
values.push_back(data[index + i]);
}
std::sort(values.begin(), values.end());
image1.data[index] = values[6]; // 6 is the median of 13 plus the index number (0-6) ...
values.clear();
}
imshow("test", image1);
waitKey(0);
}
当我像这样应用中值过滤器时:
Mat medianFilter;
medianBlur(histEqu, medianFilter, 3);
如果我应用中值过滤器,我希望得到相同的结果:
Mat manualMedianFiler;
float factor = 1 / 9.0;
Mat kernelMedian = (Mat_<float>(3, 3) <<
factor, factor, factor,
factor, factor, factor,
factor, factor, factor);
filter2D(histEqu, manualMedianFiler, CV_8U, kernelMedian, Point(-1,-1), 0, 4);
结果矩阵相似,但不相等。 难道我做错了什么?应用中值滤波器的正确方法是什么?
您的manualMedianFilter
不是中值过滤器,而是均值过滤器并且对应于cv::boxFilter
。
作为对@Miki 回答的补充,我提醒您,中值滤波器是给定 N 个样本(在本例中取自围绕中心像素的 3x3 正方形)对它们的值进行排序并取中间的一个。所以给定 (1, 7, 2, 2, 1, 9, 22, 4, 5) 排序后你得到 (1, 1, 2, 2, 4, 5, 7, 9, 22) 并且中位数是 4,而平均值是 (1 + 7 + 2 + 2 + 1 + 9 + 22 + 4 + 5) / 9 = 53/9 -> 5.8.
简而言之:中值滤波器不是线性的。
在想要去除尖峰的地方首选中值滤波器。
这里有一个简单的例子:
void MedianFilter()
{
Mat image= imread("C:\Users\User\Desktop\10.jpg", 1);
Mat image1;
cvtColor(image, image1, COLOR_BGR2GRAY);
imshow("testx", image1);
uchar * data = image1.data;
vector<int> values;
for (auto index = 0; index < (image1.rows*image1.cols); index++)
{
for (size_t i = 0; i < 13; i++) \ 13 is the element to get the median from...
{
values.push_back(data[index + i]);
}
std::sort(values.begin(), values.end());
image1.data[index] = values[6]; // 6 is the median of 13 plus the index number (0-6) ...
values.clear();
}
imshow("test", image1);
waitKey(0);
}