这是我正在使用的代码。当我运行它时,除了最后1/4之外,它似乎没有改变图像中的任何内容。那部分变成了纯色。
void maxFilter(pixel * data, int w, int h)
{
GLubyte tempRed;
GLubyte tempGreen;
GLubyte tempBlue;
int i;
int j;
int k;
int pnum = 0;
int pnumWrite = 0;
for(i = 0 ; i < (h - 2); i+=3) {
for(j = 0 ; j < (w - 2); j+=3) {
tempRed = 0;
tempGreen = 0;
tempBlue = 0;
for (k = 0 ; k < 3 ; k++){
if ((data[pnum].r) > tempRed){tempRed = (data[pnum + k].r);}
if ((data[pnum].g) > tempGreen){tempGreen = (data[pnum + k].g);}
if ((data[pnum].b) > tempBlue){tempBlue = (data[pnum + k].b);}
if ((data[(pnum + w)].r) > tempRed){tempRed = (data[(pnum + w)].r);}
if ((data[(pnum + w)].g) > tempGreen){tempGreen = (data[(pnum + w)].g);}
if ((data[(pnum + w)].b) > tempBlue){tempBlue = (data[(pnum + w)].b);}
if ((data[(pnum + 2 * w)].r) > tempRed){tempRed = (data[(pnum + 2 * w)].r);}
if ((data[(pnum + 2 * w)].g) > tempGreen){tempGreen = (data[(pnum + 2 * w)].g);}
if ((data[(pnum + 2 * w)].b) > tempBlue){tempBlue = (data[(pnum + 2 * w)].b);}
pnum++;
}
pnumWrite = pnum - 3;
for (k = 0 ; k < 3 ; k++){
((data[pnumWrite].r) = tempRed);
((data[pnumWrite].g) = tempGreen);
((data[pnumWrite].b) = tempBlue);
((data[(pnumWrite + w)].r) = tempRed);
((data[(pnumWrite + w)].g) = tempGreen);
((data[(pnumWrite + w)].b) = tempBlue);
((data[(pnumWrite + 2 * w)].r) = tempRed);
((data[(pnumWrite + 2 * w)].g) = tempGreen);
((data[(pnumWrite + 2 * w)].b) = tempBlue);
pnumWrite++;
}
}
}
}
答案 0 :(得分:1)
我可以看到该代码存在的几个问题 - 难以理解并不是最不重要的!
我认为你的主要问题是循环(正如你可能的话)运行h/3 * w/3
次,对于图像中的每个3x3块一次。但pnum
索引每个块的运行时间仅增加3
,最多约为h*w/3
,而不是预期的h*w
。这意味着只有您图像的前三分之一会受到过滤器的影响。 (而且我怀疑你的绘画已经完成了自下而上&#39;,这就是为什么你看到最低部分的变化。我记得.bmp文件的结构是这样的,但也许还有其他的。)
廉价&#39;修复将是在正确的位置添加2*w
,但没有人会再次理解该代码。我建议您改写索引,并在每个循环中从pnum
和i
明确计算j
。为了便于阅读,可以改进这一点,但相当清楚。
还有一件小事:你有像
这样的代码if ((data[pnum].r) > tempRed){tempRed = (data[pnum + k].r);}
右侧和左侧的索引不同:这可能也会给您带来与您的预期不同的结果。
正如Jongware所指出的那样,写入输入数组总是很危险的 - 我相信你的代码是为了避免这个问题,只需查看每个3x3块一次,但他对单独输出数组的建议是非常明智的 - 你可能不想要你的代码给出的阻塞(你让每个3x3块都是一种颜色,不是吗?),他的建议会让你避免这种情况。