import java.awt.GridLayout;
import java.awt.Image;
import java.util.Hashtable;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
class MatchTemplateDemoRun implements ChangeListener {
Boolean use_mask = false;
Mat img = new Mat(), templ = new Mat();
Mat mask = new Mat();
int match_method;
JLabel imgDisplay = new JLabel(), resultDisplay = new JLabel();
public void run(String[] args) {
if (args.length < 2) {
System.out.println("参数不够");
System.out.println("程序参数:\n<图像名称> <模板名称> [<蒙版名称>]");
System.exit(-1);
}
img = Imgcodecs.imread(args[0], Imgcodecs.IMREAD_COLOR);
templ = Imgcodecs.imread(args[1], Imgcodecs.IMREAD_COLOR);
if (args.length > 2) {
use_mask = true;
mask = Imgcodecs.imread(args[2], Imgcodecs.IMREAD_COLOR);
}
if (img.empty() || templ.empty() || (use_mask && mask.empty())) {
System.out.println("无法读取其中一张图片");
System.exit(-1);
}
matchingMethod();
createJFrame();
}
private void matchingMethod() {
Mat result = new Mat();
Mat img_display = new Mat();
img.copyTo(img_display);
int result_cols = img.cols() - templ.cols() + 1;
int result_rows = img.rows() - templ.rows() + 1;
result.create(result_rows, result_cols, CvType.CV_32FC1);
Boolean method_accepts_mask = (Imgproc.TM_SQDIFF == match_method || match_method == Imgproc.TM_CCORR_NORMED);
if (use_mask && method_accepts_mask) {
Imgproc.matchTemplate(img, templ, result, match_method, mask);
} else {
Imgproc.matchTemplate(img, templ, result, match_method);
}
Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());
Core.MinMaxLocResult mmr = Core.minMaxLoc(结果);
如果(match _方法== Imgproc.TM_SQDIFF || match _方法== Imgproc.TM_SQDIFF_NORMED){
matchLoc = mmr.minLoc;
} else {
matchLoc = mmr.maxLoc;
}
Imgproc.rectangle(img_display, matchLoc,
新的点(matchLoc.x + templ.cols(),matchLoc.y + templ.rows()),
新的 标量(0, 0, 0), 2, 8, 0);
Imgproc.rectangle(result, matchLoc,
新的 点(matchLoc.x + templ.cols(), matchLoc.y + templ.rows()),
新的 标量(0, 0, 0), 2, 8, 0);
Image tmpImg = HighGui.toBufferedImage(img_display);
ImageIcon icon = 新的 ImageIcon(tmpImg);
imgDisplay.setIcon(icon);
结果转换成(结果,CvType.CV_8UC1,255.0);
tmpImg = HighGui.toBufferedImage(结果);
icon = 新的 ImageIcon(tmpImg);
resultDisplay.setIcon(icon);
}
@Override
公共 无效状态变化(变更事件 e) {
JSlider 源=(JSlider)e.getSource();
如果(!source.getValueIsAdjusting()){
match _方法= 来源.getValue();
matchingMethod();
}
}
私有的 无效创建JFrame() {
JFrame 框架= 新的 JFrame(标题);
框架.setLayout(新的网格布局(2, 2));
框架.添加(imgDisplay);
JSlider 滑块= 新的 JSlider(JSlider.VERTICAL, min, max, match _方法);
滑块.setPaintTicks(真);
滑块.setPaintLabels(真);
滑块.setMinorTickSpacing(1);
哈希表<整数,JLabel> 标签 表= 新的 哈希 表<>();
标签表.put(新的 Integer(0),新的 JLabel("0 - SQDIFF"));
标签表.put(新的 Integer(1),新的 JLabel("1 - SQDIFF NORMED"));
标签表.put(新的 Integer(2),新的 JLabel("2 - TM CCORR"));
标签表.put(新的 Integer(3),新的 JLabel("3 - TM CCORR NORMED"));
标签表.put(新的 Integer(4),新的 JLabel("4 - TM COEFF"));
labelTable.put(new Integer(5), new JLabel("5 - TM COEFF NORMED : (方法)"));
slider.setLabelTable(labelTable);
slider.addChangeListener(this);
frame.add(slider);
frame.add(resultDisplay);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
public class MatchTemplateDemo {
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
new MatchTemplateDemoRun().run(args);
}
}
void min(InputArray src1, InputArray src2, OutputArray dst)
计算两组数组或一组数组和一组标量的最小值。
void max(InputArray src1, InputArray src2, OutputArray dst)
计算两组数组或一组数组和一组标量的最大值。
Point2i Point
定义 types.hpp:209
Scalar_< double > Scalar
定义 types.hpp:702