洪水填充算法运行缓慢

时间:2013-10-14 18:11:44

标签: opengl

我有flood fill算法的代码。

void floodFill() {
    float target[3] = { 1.0, 1.0, 0.0 };
    float border[3] = { 1.0, 1.0, 1.0 };
    float clearp[3] = { 0.0, 0.0, 0.0 };
    std::stack<pixel*> colored;
    if (!stack.empty()) // stack contains first pixel
        colored.push(stack.top());

    while(!colored.empty()) {

        pixel *p = colored.top();
        drawPixel(p->x, p->y, target);
        colored.pop();

        //up
        float pix[3];
        glReadPixels(p->x, p->y + KOEF, 1, 1, GL_RGB, GL_FLOAT, pix);
        if (!compare(pix,border) && compare(pix,clearp)) {
            pixel *pn = new pixel();
            pn->x = p->x;
            pn->y = p->y + KOEF;
            colored.push(pn);
        }
        //down
        glReadPixels(p->x, p->y - KOEF, 1, 1, GL_RGB, GL_FLOAT, pix);
        if (!compare(pix,border) && compare(pix,clearp)) {
            pixel *pn = new pixel();
            pn->x = p->x;
            pn->y = p->y - KOEF;
            colored.push(pn);
        }

        //left
        glReadPixels(p->x - KOEF, p->y, 1, 1, GL_RGB, GL_FLOAT, pix);
        if (!compare(pix,border) && compare(pix,clearp)) {
            pixel *pn = new pixel();
            pn->x = p->x - KOEF;
            pn->y = p->y;
            colored.push(pn);
        }

        //right
        glReadPixels(p->x + KOEF, p->y, 1, 1, GL_RGB, GL_FLOAT, pix);
        if (!compare(pix,border) && compare(pix,clearp)) {
            pixel *pn = new pixel();
            pn->x = p->x + KOEF;
            pn->y = p->y;
            colored.push(pn);
        }

    }
}

我使用这种方法绘制像素

void drawPixel(float x, float y, float *t) {
glRasterPos2i(x, y); 
glDrawPixels(1, 1, GL_RGB, GL_FLOAT, t);
for(int i = 0; i < KOEF; i++) {

    glRasterPos2i(x, y + i); 
    glDrawPixels(1, 1, GL_RGB, GL_FLOAT, t);

    glRasterPos2i(x + i, y); 
    glDrawPixels(1, 1, GL_RGB, GL_FLOAT, t);

    glRasterPos2i(x + i, y + i); 
    glDrawPixels(1, 1, GL_RGB, GL_FLOAT, t);
}
};

要填充某个区域,我会通过鼠标单击选择第一个像素,然后调用方法floodFill

void mouse(int button, int state, int x, int y) {

if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
    pixel *p = new pixel();
    p->x = x;
    p->y = HEIGHT - y;
    if (!stack.empty())
        stack.pop();
    stack.push(p); // first pixel

    floodFill();
}
};

结果是(例如)

enter image description here

但是效果很慢(几秒钟。照片上的区域 - 它画了11秒。字母周围的区域 - 43秒)。而且我认为它会慢慢地逐像素地绘制,但是它等待了几秒钟,然后我看到了结果。

我的电脑是

intel core 2 duo p8600 2.4 GHz
nvidia 9600m gt 512 mb
windows x86 
ram 4 GB(3)`

它是否应该如此缓慢或存在问题?

2 个答案:

答案 0 :(得分:6)

这是使用OpenGL的可怕的方式。

将洪水填充到主机内存中,将生成的位图上传到OpenGL纹理,然后使用该纹理渲染四边形。

答案 1 :(得分:4)

  

它是否应该如此缓慢或存在问题?

不,不应该。因为Photoshop可以让它更快: - )

看起来有一些与效率相关的问题。

  1. 您不应将OpenGL调用用于单像素操作。您最好制作图像的缓冲副本,处理(填充),然后复制。

  2. 为什么使用这些奇怪的浮点坐标而不是普通的整数像素索引? 那么不使用浮动颜色呢?浮点运算比整数运算慢,浮点值需要进一步转换为内部图像格式。

  3. 你的程序似乎太过于OOP-ish的目的。在图像处理例程的最内层循环中使用newstack并不是一个好主意。