I've been playing around with opencv and I cant understand how floodfill works. I have one larger image and one "template" image, trying to find all matches (in this case I know that there should be two matches). My idea is to find the first match, use floodfill to fill it with w/e pixels and run template matching again and so on. Here is my code
import org.opencv.core.*;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.*;
public class Main {
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat template = Imgcodecs.imread("imgs/template.jpg");
Mat image = Imgcodecs.imread("imgs/imagetwo.jpg");
int result_cols = image.cols() - template.cols() + 1;
int result_rows = image.rows() - template.rows() + 1;
Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1);
Imgproc.matchTemplate(image, template, result, Imgproc.TM_CCOEFF);
Core.normalize(result, result, 0.9, 1, Core.NORM_MINMAX, -1);
Core.MinMaxLocResult res = Core.minMaxLoc(result);
Point loc = res.maxLoc;
double x = res.maxLoc.x;
System.out.println(loc);
Imgproc.rectangle(image, loc, new Point(loc.x + template.width(), loc.y + template.height()), new Scalar(0));
Imgproc.floodFill(image, new Mat(), loc, new Scalar(0, 255, 0));
Imgproc.matchTemplate(image, template, result, Imgproc.TM_CCOEFF);
Core.normalize(result, result, 0.8, 1, Core.NORM_MINMAX, -1);
res = Core.minMaxLoc(result);
if (res.maxVal >= 0.9) {
loc = res.maxLoc;
} else {
System.out.println("No matches");
}
System.out.println(loc);
Imgproc.rectangle(image, loc, new Point(loc.x + template.width(), loc.y + template.height()), new Scalar(0));
Imgproc.floodFill(image, new Mat(), loc, new Scalar(0, 255, 0));
Imgproc.matchTemplate(image, template, result, Imgproc.TM_CCOEFF);
Core.normalize(result, result, 0.8, 1, Core.NORM_MINMAX, -1);
res = Core.minMaxLoc(result);
if (res.maxVal >= 0.9) {
loc = res.maxLoc;
} else {
System.out.println("No matches");
}
System.out.println(loc);
}
}
And the result I am getting:
{151.0, 167.0}
{142.0, 167.0}
{151.0, 167.0}
So basically floodfill works fine the first time I use it and I am able to find the second match, but when I run the "loop" for the third time instead of getting "No matches" I get first Point again, which means my first floodfill is gone??
I'll admit that even after reading all I could find online about floodfill I'm still very uncertain on how it's supposed to work and I feel that I messed up somewhere in it's definition but I have no idea where.
Any help is appreciated,
Thanks.
解决方案
You need to initialize the Mask, which is the second parameter of the floodFill method. It is supposed to be set up to zero. Because the algorithm can't go across the non zero pixels. Additionally you need to consider the size of the matrix. It should be 2 pixels wider and 2 pixels taller than the image.