import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Image;
import java.util.Arrays;
导入 java.util.List;
导入 javax.swing.BoxLayout;
导入 javax.swing.ImageIcon;
导入 javax.swing.JFrame;
导入 javax.swing.JLabel;
导入 javax.swing.JPanel;
导入 javax.swing.JSlider;
导入 javax.swing.event.ChangeEvent;
导入 javax.swing.event.ChangeListener;
导入 org.opencv.core.Core;
导入 org.opencv.core.CvType;
导入 org.opencv.core.Mat;
导入 org.opencv.core.MatOfFloat;
导入 org.opencv.core.MatOfInt;
导入 org.opencv.core.Point;
导入 org.opencv.core.Scalar;
导入 org.opencv.highgui.HighGui;
导入 org.opencv.imgcodecs.Imgcodecs;
导入 org.opencv.imgproc.Imgproc;
类 CalcBackProject1 {
私有 Mat hue;
私有 Mat histImg = 新 Mat();
私有 JFrame frame;
私有 JLabel imgLabel;
私有 JLabel backprojLabel;
私有 JLabel histImgLabel;
静态 最终 int MAX_SLIDER = 180;
私有 int bins = 25;
公有 CalcBackProject1(String[] args) {
如果 (args.length != 1) {
System.err.println("您必须提供一个参数,对应于图像的路径。");
System.exit(0);
}
Mat src = Imgcodecs.imread(args[0]);
如果 (src.empty()) {
System.err.println("空图像: " + args[0]);
System.exit(0);
}
Mat hsv = 新 Mat();
Imgproc.cvtColor(src, hsv, Imgproc.COLOR_BGR2HSV);
hue = 新 Mat(hsv.size(), hsv.depth());
Core.mixChannels(Arrays.asList(hsv), Arrays.asList(hue), 新 MatOfInt(0, 0));
frame = 新 JFrame("反向投影 1 演示");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Image img = HighGui.toBufferedImage(src);
addComponentsToPane(frame.getContentPane(), img);
frame.pack();
frame.setVisible(真);
}
私有 无效 addComponentsToPane(Container pane, Image img) {
如果 (!(pane.getLayout() instanceof BorderLayout)) {
pane.add(新 JLabel("容器不使用 BorderLayout!"));
return;
}
JPanel sliderPanel = 新 JPanel();
sliderPanel.setLayout(新 BoxLayout(sliderPanel, BoxLayout.PAGE_AXIS));
sliderPanel.add(新 JLabel("* 色调箱: "));
JSlider slider = 新 JSlider(0, MAX_SLIDER, bins);
slider.setMajorTickSpacing(25);
slider.setMinorTickSpacing(5);
slider.setPaintTicks(真);
slider.setPaintLabels(真);
slider.addChangeListener(新 ChangeListener() {
@Override
公有 无效 stateChanged(ChangeEvent e) {
JSlider source = (JSlider) e.getSource();
bins = source.getValue();
update();
}
});
sliderPanel.add(slider);
pane.add(sliderPanel, BorderLayout.PAGE_START);
JPanel imgPanel = 新 JPanel();
imgLabel = 新 JLabel(新 ImageIcon(img));
imgPanel.add(imgLabel);
backprojLabel = 新 JLabel();
imgPanel.add(backprojLabel);
histImgLabel = 新 JLabel();
imgPanel.add(histImgLabel);
pane.add(imgPanel, BorderLayout.CENTER);
}
私有 无效 update() {
int histSize = Math.max(bins, 2);
浮点型[] hueRange = {0, 180};
Mat hist = 新 Mat();
List<Mat> hueList = Arrays.asList(hue);
Imgproc.calcHist(hueList, 新 MatOfInt(0), 新 Mat(), hist, 新 MatOfInt(histSize), 新 MatOfFloat(hueRange), 假);
Core.normalize(hist, hist, 0, 255, Core.NORM_MINMAX);
Mat backproj = 新 Mat();
Imgproc.calcBackProject(hueList, 新 MatOfInt(0), hist, backproj, 新 MatOfFloat(hueRange), 1);
Image backprojImg = HighGui.toBufferedImage(backproj);
backprojLabel.setIcon(新 ImageIcon(backprojImg));
int w = 400, h = 400;
int binW = (int) Math.round((双精度型) w / histSize);
histImg = Mat.zeros(h, w, CvType.CV_8UC3);
浮点型[] histData = 新 浮点型[(int) (hist.total() * hist.channels())];
hist.get(0, 0, histData);
为了 (int i = 0; i < bins; i++) {
Imgproc.rectangle(histImg,
新 点(i * binW, h),
新 点((i + 1) * binW, h - Math.round(histData[i] * h / 255.0)),
新 标量(0, 0, 255), Imgproc.FILLED);
}
Image histImage = HighGui.toBufferedImage(histImg);
histImgLabel.setIcon(新 ImageIcon(histImage));
frame.repaint();
frame.pack();
}
}
公有 类 CalcBackProjectDemo1 {
公有 静态 无效 主(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
javax.swing.SwingUtilities.invokeLater(新 Runnable() {
@Override
公有 无效 run() {
新 CalcBackProject1(args);
}
});
}
}
Point2i Point
定义 types.hpp:209
Scalar_< double > Scalar
定义 types.hpp:702