У меня есть следующее изображение:
Я пытаюсь создать цикл, который будет учитывать цвет каждого пикселя и заливать заливку из любых найденных белых точек.
На данный момент у меня есть этот код:
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;
}
}
}
Как вы можете видеть, он зацикливается на каждом пикселе, и если он белый, он заливает его оттуда. Я также оставил в цикле какой-то старый код, который перекрашивал каждый отдельный пиксель и работал, но когда я пытаюсь заполнить мое изображение флудом, оно оставляет меня примерно таким:
В результате заливка заполняет изображение более 4000 раз, что занимает много времени и даже не заполняет всю область.
Есть идеи, что я сделал не так? Или есть лучший способ сделать это?
Ваша проблема в том, что вы всегда заливаете заливку из (0, 0), а не из белого пикселя, который вы находите в (x, y). Также используя `at<> () — это очень медленный способ последовательного сканирования изображения.
Исправленный код:
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));
}
}
}