题
我在实施方面有问题 洪水填充。
任务是要求用户单击图像的白色部分(指示种子点),他想用黑色填充。
该操作应在二进制图像上完成。
我在用着 cimg 图书馆。
我 不能 利用 递归 算法。
我想出了一些东西,但它无法正常工作(差距仅在种子点中变成黑色)。我根本不熟悉队列,所以也许问题在于他们的实施。
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);
}
解决方案
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();
您只是弹出了当前的X,Y坐在堆栈中,而无需查看它们是什么。
2)
p = image(x-1, y);
if((p == c) && (x > 0))
您是说像其他方向一样检查它是否是白色的?
3)呼叫者以黑色和白色的方式通过,如果图像的一部分为蓝色,会发生什么?最好是传递填充颜色(黑色),无论您在哪里白色,都可以用黑色代替。
其他提示
你不知道你正在与之合作 x
和 y
一直以来 a.pop()
什么都没返回吗? std::queue::pop
仅弹出队列的前部,但不会返回。您必须事先查询它 std::queue::front
. 。所以添加
x = a.front().first;
y = a.front().second;
就在之前 a.pop()
内部循环。
顺便说一下,您可能还想设置 image(x, y)
(有可能 kopia(x, y)
) 至 c
在推动初始对之前,在Else Block的开头,尽管它也可能是由邻居的迭代设置的。
另外,CIMG中有一个内置功能可以执行您想要的操作:cimg :: draw_fill()。
不隶属于 StackOverflow