Pregunta

Tengo un problema con la implementación de llenado de inundación.
La tarea es pedirle al usuario que haga clic en la parte blanca de la imagen (que indica el punto de semilla), quiere llenarse de negro.
La operación debe realizarse en las imágenes binarias.
Estoy usando Cimg biblioteca.
yo no poder usar recursivo algoritmo.
Se me ocurrieron algo, pero no funciona correctamente (la brecha se vuelve negra solo en el punto de semilla). No estoy familiarizado con las colas en absoluto, por lo que tal vez el problema esté en su implementación.

void floodfill(int x, int y, int c, int b, CImg <unsigned char>image)
{
    //c-black
    //b-white
    CImg<unsigned char> kopia(image.width(),image.height());

    for (int p=1; p<image.height()-1; p++)
    {
        for (int q=1; q<image.width()-1; q++)
        {
            kopia(p,q)=255; //setting kopia2 all white
        }
    }

    queue <pair<int,int> > a;
    int p;
    if(image(x, y) == c)
    {
        cout<<"Already black"<<endl;
        return;
    }
    else
    {
        a.push(make_pair(x, y));
        while(!a.empty())
        {
            a.pop();
            p=image(x+1, y);
            if((p == b) && (x < image.width()))
            {
                a.push(make_pair(x+1, y));
                kopia(x+1, y)=c;
                image(x+1, y)=c;
            }
            p = image(x-1, y);
            if((p == c) && (x > 0))
            {
                a.push(make_pair(x-1, y));
                kopia(x-1, y)=c;
                image(x-1, y)=c;
            }
            p=image(x, y+1);
            if((p == b) && (y < image.height()))
            {
                a.push(make_pair(x, y+1));
                kopia(x, y+1)=c;
                image(x, y+1)=c;
            }
            p=image(x, y-1);
            if((p == b) && (y > 0))
            {
                a.push(make_pair(x, y-1));
                kopia(x, y-1)=c;
                image(x, y-1)=c;
            }
        }
        saving(kopia);
    }
}

void hole (CImg <unsigned char>image)
{
    CImgDisplay image_disp(image,"Click a point");

    int c_x=0; //coordinates
    int c_y=0;

    while (!image_disp.is_closed())
    {
        image_disp.wait();
        if (image_disp.button())
        {
            c_x=image_disp.mouse_x();  //reads coordinates indicated by user
            c_y=image_disp.mouse_y();
        }
    }

    floodfill(c_x, c_y,0,255,image);
}
¿Fue útil?

Solución

1)

    while(!a.empty())
    {
        x = a.front().first; //fixed as per ChristianRau's code
        y = a.front().second; //fixed as per ChristianRau's code
        a.pop();

Acabas de sacar la actual X, Y coordina la pila sin mirar lo que eran.

2)

        p = image(x-1, y);
        if((p == c) && (x > 0))

¿Quiso verificar si era blanco, como lo hizo con las otras instrucciones?

3) La persona que llama pasa en blanco y negro, ¿qué sucede si parte de la imagen es azul? Mejor sería pasar en el color de relleno (negro), y donde sea que tenga blanco, reemplácelo con no negro.

Otros consejos

¿No te das cuenta de que estás trabajando con lo mismo? x y y todo el tiempo y que a.pop() ¿No devuelve nada? std::queue::pop Solo aparece el frente de la cola, pero no lo devuelve. Tienes que consultarlo de antemano usando std::queue::front. Así que solo agrega

x = a.front().first;
y = a.front().second;

justo antes de a.pop() Dentro del bucle While.

Y por cierto, es posible que también desee establecer image(x, y) (y tal vez kopia(x, y)) a c Al comienzo del bloque de Else antes de presionar el par inicial, aunque también podría establecerse por las iteraciones de sus vecinos.

Además, hay una función incorporada en CIMG que hace lo que desea: CIMG :: Draw_fill ().

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top