I have the follow image:
I'm trying to create a loop that will take into account the colour of each pixel, and flood fill from any white points it finds.
At the moment, I have this code:
for(int y=0; y<image.rows; y++)
{
for(int x=0; x<image.cols; x++)
{
image.at<cv::Vec3b>(y,x);
if(image.at<cv::Vec3b>(y,x)[0] == 255 && image.at<cv::Vec3b>(y,x)[1] == 255 && image.at<cv::Vec3b>(y,x)[2] == 255)
{
/*image.at<cv::Vec3b>(y,x)[0] = 155;
image.at<cv::Vec3b>(y,x)[1] = 0;
image.at<cv::Vec3b>(y,x)[2] = 0;*/
int filling = cv::floodFill(image, cv::Point(y,x), 255, (cv::Rect*)0, cv::Scalar(), 200);
//cout << "x:" << x << " y:" << y;
}
}
}
As you can see, it loops over each pixel, and if it is white, it flood fills from there. I also left some old code in the loop which recoloured each individual pixel and worked, but when I try to flood fill my image, it leaves me with something like this:
It ends up flood filling the image over 4000 times, which takes a long time, and doesn't even fill the whole area.
Any ideas what I've done wrong? Or is there a better way to do this?
Your problem is that you always flood fill from (0, 0) instead of from the white pixel you find at (x, y). Also using `at<>() is a really slow way of sequentially scanning an image.
Corrected code:
cv::Vec3b white(255, 255, 255);
for(int y=0; y<image.rows; y++)
{
cv::Vec3b* row = image.ptr<cv::Vec3b>(y)
for(int x=0; x<image.cols; x++)
{
if(row[x] == white)
{
cv::floodFill(image, cv::Point(x,y), cv::Scalar(255,0,0), (cv::Rect*)0, cv::Scalar(), cv::Scalar(200,200,200));
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With