HullDemo.java 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import java.awt.BorderLayout;
  2. import java.awt.Container;
  3. import java.awt.Image;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. import java.util.Random;
  7. import javax.swing.BoxLayout;
  8. import javax.swing.ImageIcon;
  9. import javax.swing.JFrame;
  10. import javax.swing.JLabel;
  11. import javax.swing.JPanel;
  12. import javax.swing.JSlider;
  13. import javax.swing.event.ChangeEvent;
  14. import javax.swing.event.ChangeListener;
  15. import org.opencv.core.Core;
  16. import org.opencv.core.CvType;
  17. import org.opencv.core.Mat;
  18. import org.opencv.core.MatOfInt;
  19. import org.opencv.core.MatOfPoint;
  20. import org.opencv.core.Point;
  21. import org.opencv.core.Scalar;
  22. import org.opencv.core.Size;
  23. import org.opencv.highgui.HighGui;
  24. import org.opencv.imgcodecs.Imgcodecs;
  25. import org.opencv.imgproc.Imgproc;
  26. class Hull {
  27. private Mat srcGray = new Mat();
  28. private JFrame frame;
  29. private JLabel imgSrcLabel;
  30. private JLabel imgContoursLabel;
  31. private static final int MAX_THRESHOLD = 255;
  32. private int threshold = 100;
  33. private Random rng = new Random(12345);
  34. public Hull(String[] args) {
  35. /// Load source image
  36. String filename = args.length > 0 ? args[0] : "../data/stuff.jpg";
  37. Mat src = Imgcodecs.imread(filename);
  38. if (src.empty()) {
  39. System.err.println("Cannot read image: " + filename);
  40. System.exit(0);
  41. }
  42. /// Convert image to gray and blur it
  43. Imgproc.cvtColor(src, srcGray, Imgproc.COLOR_BGR2GRAY);
  44. Imgproc.blur(srcGray, srcGray, new Size(3, 3));
  45. // Create and set up the window.
  46. frame = new JFrame("Convex Hull demo");
  47. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  48. // Set up the content pane.
  49. Image img = HighGui.toBufferedImage(src);
  50. addComponentsToPane(frame.getContentPane(), img);
  51. // Use the content pane's default BorderLayout. No need for
  52. // setLayout(new BorderLayout());
  53. // Display the window.
  54. frame.pack();
  55. frame.setVisible(true);
  56. update();
  57. }
  58. private void addComponentsToPane(Container pane, Image img) {
  59. if (!(pane.getLayout() instanceof BorderLayout)) {
  60. pane.add(new JLabel("Container doesn't use BorderLayout!"));
  61. return;
  62. }
  63. JPanel sliderPanel = new JPanel();
  64. sliderPanel.setLayout(new BoxLayout(sliderPanel, BoxLayout.PAGE_AXIS));
  65. sliderPanel.add(new JLabel("Canny threshold: "));
  66. JSlider slider = new JSlider(0, MAX_THRESHOLD, threshold);
  67. slider.setMajorTickSpacing(20);
  68. slider.setMinorTickSpacing(10);
  69. slider.setPaintTicks(true);
  70. slider.setPaintLabels(true);
  71. slider.addChangeListener(new ChangeListener() {
  72. @Override
  73. public void stateChanged(ChangeEvent e) {
  74. JSlider source = (JSlider) e.getSource();
  75. threshold = source.getValue();
  76. update();
  77. }
  78. });
  79. sliderPanel.add(slider);
  80. pane.add(sliderPanel, BorderLayout.PAGE_START);
  81. JPanel imgPanel = new JPanel();
  82. imgSrcLabel = new JLabel(new ImageIcon(img));
  83. imgPanel.add(imgSrcLabel);
  84. Mat blackImg = Mat.zeros(srcGray.size(), CvType.CV_8U);
  85. imgContoursLabel = new JLabel(new ImageIcon(HighGui.toBufferedImage(blackImg)));
  86. imgPanel.add(imgContoursLabel);
  87. pane.add(imgPanel, BorderLayout.CENTER);
  88. }
  89. private void update() {
  90. /// Detect edges using Canny
  91. Mat cannyOutput = new Mat();
  92. Imgproc.Canny(srcGray, cannyOutput, threshold, threshold * 2);
  93. /// Find contours
  94. List<MatOfPoint> contours = new ArrayList<>();
  95. Mat hierarchy = new Mat();
  96. Imgproc.findContours(cannyOutput, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
  97. /// Find the convex hull object for each contour
  98. List<MatOfPoint> hullList = new ArrayList<>();
  99. for (MatOfPoint contour : contours) {
  100. MatOfInt hull = new MatOfInt();
  101. Imgproc.convexHull(contour, hull);
  102. Point[] contourArray = contour.toArray();
  103. Point[] hullPoints = new Point[hull.rows()];
  104. List<Integer> hullContourIdxList = hull.toList();
  105. for (int i = 0; i < hullContourIdxList.size(); i++) {
  106. hullPoints[i] = contourArray[hullContourIdxList.get(i)];
  107. }
  108. hullList.add(new MatOfPoint(hullPoints));
  109. }
  110. /// Draw contours + hull results
  111. Mat drawing = Mat.zeros(cannyOutput.size(), CvType.CV_8UC3);
  112. for (int i = 0; i < contours.size(); i++) {
  113. Scalar color = new Scalar(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256));
  114. Imgproc.drawContours(drawing, contours, i, color);
  115. Imgproc.drawContours(drawing, hullList, i, color );
  116. }
  117. imgContoursLabel.setIcon(new ImageIcon(HighGui.toBufferedImage(drawing)));
  118. frame.repaint();
  119. }
  120. }
  121. public class HullDemo {
  122. public static void main(String[] args) {
  123. // Load the native OpenCV library
  124. System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
  125. // Schedule a job for the event dispatch thread:
  126. // creating and showing this application's GUI.
  127. javax.swing.SwingUtilities.invokeLater(new Runnable() {
  128. @Override
  129. public void run() {
  130. new Hull(args);
  131. }
  132. });
  133. }
  134. }