我正在尝试制作一个循环,我可以执行以下操作: -
x x x y y y y y
x x x y y y y y
x x x y y y y y
y y y y y y y y
y y y y y y y y
(顺便提一下,上面是8x5网格。)
y y y x x x y y
y y y x x x y y
y y y x x x y y
y y y y y y y y
y y y y y y y y
我试过这样做: -
for(int j=0;j<image.rows;j++)
{
for (int i=0;i<image.cols;i++)
{
for (int y=0; y < 9; y++) {
sum = image.at<uchar>(j,i) + sum;
change = sum/9;
}
image.at<uchar>(j,i) = change;
}
}
但它不起作用。
答案 0 :(得分:2)
你是逐个像素地迭代图像,但为了做你想做的事,你需要按3x3像素的组进行迭代:
for(int j = 0; j < image.rows; j += 3)
{
for (int i = 0; i < image.cols; i += 3)
{
uchar sum = 0;
for(int x = 0; x < 3; ++x) {
for(int y = 0; y < 3; ++y) {
sum += image.at<uchar>(j + x,i + y);
}
}
sum /= 9;
for(int x = 0; x < 3; ++x) {
for(int y = 0; y < 3; ++y) {
image.at<uchar>(j + x,i + y) = sum ;
}
}
}
}
您还需要处理图像尺寸不是3的倍数的情况。
答案 1 :(得分:2)
@zakinster已经为您提供了一个很好的解决方案,但我建议您使用OpenCV的功能来执行平均值或设置值的计算等操作,而不是使用循环。这将创建更短,更易读的解决方案。此外,当图像不是3的倍数时,你必须确保算法能够工作。对于这种情况,通常的C ++技巧是使用(x / 3 * 3)而不是x。
代码应如下所示:
for(int j=0; j<image.rows/3*3; j+=3)
for(int i=0; i<image.cols/3*3; i+=3)
{
Mat tmp(image,Rect(i,j,3,3));
tmp.setTo(mean(tmp));
}
相同代码的更短但可读性更低的版本:
for(int j=0; j<image.rows/3*3; j+=3)
for(int i=0; i<image.cols/3*3; i+=3)
image(Rect(i,j,3,3)).setTo(mean(image(Rect(i,j,3,3))));
答案 2 :(得分:1)
change = sum*(1/9);
1/9是整数除法,因此它将为零。请改用change = sum/9.0
。
答案 3 :(得分:0)
代码的问题在于你对变量y的内部循环永远不会改变值i或j。因此,第一次进入此循环时,您基本上将图像中的(0,0)处的值乘以9,然后除以9.
你将不得不找出一种基于y对i和j进行变换的方法,可能是编辑这一行:
sum = image.at<uchar>(j, i) + sum;
这样它可以处理用x标记的单元格。
然后,您需要修改在外部循环中更新i和j的方式。看起来您需要将j递增3才能跳过刚刚处理的块。
这将涉及一些想法,你需要考虑如何处理网格尺寸不是三的倍数的情况,但我首先要让内循环首先工作。