我一直在玩opencv,我不明白floodfill是如何工作的。我有一个较大的图像和一个"模板"图像,试图找到所有匹配项(在这种情况下,我知道应该有两个匹配项)。我的想法是找到第一个匹配,使用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}
所以基本上,我第一次使用floodfill时效果很好,我能够找到第二个匹配,但当我第三次运行"循环"而不是"无匹配"时,我又获得了第一分,这意味着我的第一个floodfil消失了??
我承认,即使在阅读了我在网上能找到的关于floodfill的所有内容后,我仍然非常不确定它应该如何工作,我觉得我在它的定义中搞砸了,但我不知道在哪里。
感谢任何帮助,谢谢
您需要初始化Mask,这是floodFill方法的第二个参数。它应该设置为零。因为该算法不能遍历非零像素。此外,您还需要考虑矩阵的大小。它应该比图像宽2个像素,高2个像素。
这可能为时已晚,但您可以使用Core.rectangle绘制匹配模板的矩形。当然,由于你找到了多个匹配,你需要多次抽签。因此,最好将"loc"保存为循环每次迭代的点向量,然后在循环完成时绘制。