我正在写一个最大过滤器。这将用每个像素RGB通道替换周围9个像素的最大通道强度

时间:2014-09-26 18:13:57

标签: c

这是我正在使用的代码。当我运行它时,除了最后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++;
        }
        }
    }

    }

1 个答案:

答案 0 :(得分:1)

我可以看到该代码存在的几个问题 - 难以理解并不是最不重要的!

我认为你的主要问题是循环(正如你可能的话)运行h/3 * w/3次,对于图像中的每个3x3块一次。但pnum索引每个块的运行时间仅增加3,最多约为h*w/3,而不是预期的h*w。这意味着只有您图像的前三分之一会受到过滤器的影响。 (而且我怀疑你的绘画已经完成了自下而上&#39;,这就是为什么你看到最低部分的变化。我记得.bmp文件的结构是这样的,但也许还有其他的。)

廉价&#39;修复将是在正确的位置添加2*w,但没有人会再次理解该代码。我建议您改写索引,并在每个循环中从pnumi明确计算j。为了便于阅读,可以改进这一点,但相当清楚。

还有一件小事:你有像

这样的代码
if ((data[pnum].r) > tempRed){tempRed = (data[pnum + k].r);}

右侧和左侧的索引不同:这可能也会给您带来与您的预期不同的结果。

正如Jongware所指出的那样,写入输入数组总是很危险的 - 我相信你的代码是为了避免这个问题,只需查看每个3x3块一次,但他对单独输出数组的建议是非常明智的 - 你可能不想要你的代码给出的阻塞(你让每个3x3块都是一种颜色,不是吗?),他的建议会让你避免这种情况。