我一直在玩opencv,我无法理解洪水填充的工作原理。我有一个更大的图像和一个“模板”图像,试图找到所有匹配(在这种情况下,我知道应该有两个匹配)。我的想法是找到第一个匹配,使用floodfill用w / e像素填充它并再次运行模板匹配等等。这是我的代码
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);
}
}
我得到的结果是:
{151.0, 167.0}
{142.0, 167.0}
{151.0, 167.0}
所以基本上洪水填充工作正常我第一次使用它并且我能够找到第二个匹配,但是当我第三次运行“循环”而不是得到“不匹配”时,我再次获得第一个Point,意味着我的第一次淹水已经消失了?
我会承认,即使阅读了所有我能在网上找到关于洪水填充的内容,我仍然非常不确定它应该如何工作,我觉得我搞砸了它的定义,但我不知道在哪里。
感谢任何帮助, 感谢。
答案 0 :(得分:2)
您需要初始化Mask,这是floodFill方法的第二个参数。它应该被设置为零。因为该算法不能跨越非零像素。此外,您需要考虑矩阵的大小。它应该比图像宽2像素,高2像素。
答案 1 :(得分:0)
可能现在为时已晚,但您可以使用Core.rectangle绘制匹配模板的矩形。当然,因为你找到了多个匹配,你需要多次绘制。所以,最好将“loc”保存到循环的每次迭代的Points向量中,然后在循环完成后绘制。