【发布时间】:2020-04-08 18:58:53
【问题描述】:
我是 OpenCV(C++ 语言)和图像处理的新手。我想,给定一个灰度图像来替换每个像素的值,计算 3x3 邻域中灰度的平均值。
首先我打开图片
Mat img = imread(samples::findFile(argv[1]), IMREAD_GRAYSCALE);
// Example of image
[4 3 9 1,
2 9 8 0,
3 5 2 1,
7 5 8 3]
为了获得角的 3x3 最接近像素(左上、右上、左下和右下)的平均值,我对图像进行了填充:1x1x1x1 恒定边框
Mat imgPadding;
copyMakeBorder(img, imgPadding, 1,1,1,1, BORDER_CONSTANT, Scalar(0));
// Padding example
[0 0 0 0 0 0,
0 4 3 9 1 0,
0 2 9 8 0 0,
0 3 5 2 1 0,
0 7 5 8 3 0,
0 0 0 0 0 0]
现在我在输出图像方面遇到了一些问题。我尝试了各种方式,但没有办法让我找到解决方案。我试过这个,使用mean() function 来获得Rect() method 得到的第 i,j 个 3x3 矩阵的平均灰度值。 for 循环从第一个非填充像素开始,到最后一个非填充像素结束。
Mat imgAvg = Mat::zeros(img.rows, img.cols, img.type());
// initialization of the output Mat object with same input size and type
for (int i = 1; i < imgAvg.rows; i++)
for (int j = 1; j < imgAvg.cols; j++)
imgAvg.at<Scalar>(Point(j - 1, i - 1)) = mean(imgPadding(Rect(j - 1, i - 1, 3, 3)));
但我得到了这个运行时错误
main: malloc.c:2379: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
我也尝试随机缩小范围
for (int i = 1; i < imgAvg.rows - 35; i++)
for (int j = 1; j < imgAvg.cols - 35; j++)
imgAvg.at<Scalar>(Point(j - 1, i - 1)) = mean(imgPadding(Rect(j - 1, i - 1, 3, 3)));
我得到了这个奇怪的输出:screenshot
提前致谢!
编辑:
谢谢大家的回答,我还不知道blur() 功能。
这样我就导入了图片,直接调用了模糊函数
Mat img = imread(samples::findFile(argv[1]), IMREAD_GRAYSCALE);
Mat imgAvg = Mat::zeros(img.rows, img.cols, img.type());
blur(img, imgAvg, Size(3, 3));
但由于我还是初学者,我认为分配给我的练习的目的是编写“手工”代码,我也尝试了这个可行的解决方案
for (int i = 1; i <= imgAvg.rows; i++)
for (int j = 1; j <= imgAvg.cols; j++)
imgAvg.at<uint8_t>(Point(j - 1, i - 1)) = mean(imgPadding(Rect(j - 1, i - 1, 3, 3)))[0];
【问题讨论】:
-
这就是
blur所做的。 -
您的阅读越界,应该是:
i < imgAvg.rows-1和j < imgAvg.cols-1。您有深度 == 1 的图像,一种颜色分量为灰度,值存储在uint8_t类型中。因为cv::mean返回 Scalar,所以您应该在 0 索引处获取它的第一个元素,并将其分配给 uint8_t:imgAvg.at<uint8_t>(..) = mean(...)[0];。 -
@rafix07 这是我正在寻找的解决方案。除了越界错误,我不知道要在模板
imgAvg.at<>()中插入哪种类型。