0

我有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();
}
};

结果是(例如)

在此处输入图像描述

但它的工作速度非常慢(几秒钟。图片上的区域 - 它正在绘制 11 秒。字母周围的区域 - 43 秒)。而且我认为它会慢慢地逐个像素地绘制,但它会等待几秒钟然后我看到结果。

我的电脑是

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

它应该工作这么慢还是有问题?

4

2 回答 2

6

这是使用 OpenGL 的一种糟糕的方式。

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

于 2013-10-14T18:24:57.023 回答
4

它应该工作这么慢还是有问题?

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

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

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

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

  3. 您的程序似乎太面向对象了。在图像处理例程的最内层循环中使用newand并不是一个好主意。stack

于 2013-10-14T18:25:42.083 回答