1 import java.awt.BorderLayout;
2 import java.awt.Container;
3 import java.awt.Image;
4 import java.awt.event.WindowAdapter;
5 import java.awt.event.WindowEvent;
6 import java.util.List;
7 
8 import javax.swing.BoxLayout;
9 import javax.swing.ImageIcon;
10 import javax.swing.JFrame;
11 import javax.swing.JLabel;
12 import javax.swing.JPanel;
13 import javax.swing.JSlider;
14 import javax.swing.SwingWorker;
15 import javax.swing.event.ChangeEvent;
16 import javax.swing.event.ChangeListener;
17 
18 import org.opencv.core.Core;
19 import org.opencv.core.Mat;
20 import org.opencv.core.Scalar;
21 import org.opencv.highgui.HighGui;
22 import org.opencv.imgproc.Imgproc;
23 import org.opencv.videoio.VideoCapture;
24 
25 public class ThresholdInRange {
26     private static int MAX_VALUE = 255;
27     private static int MAX_VALUE_H = 360/2;
28     private static final String WINDOW_NAME = "Thresholding Operations using inRange demo";
29     private static final String LOW_H_NAME = "Low H";
30     private static final String LOW_S_NAME = "Low S";
31     private static final String LOW_V_NAME = "Low V";
32     private static final String HIGH_H_NAME = "High H";
33     private static final String HIGH_S_NAME = "High S";
34     private static final String HIGH_V_NAME = "High V";
35     private JSlider sliderLowH;
36     private JSlider sliderHighH;
37     private JSlider sliderLowS;
38     private JSlider sliderHighS;
39     private JSlider sliderLowV;
40     private JSlider sliderHighV;
41     private VideoCapture cap;
42     private Mat matFrame = new Mat();
43     private JFrame frame;
44     private JLabel imgCaptureLabel;
45     private JLabel imgDetectionLabel;
46     private CaptureTask captureTask;
47 
ThresholdInRange(String[] args)48     public ThresholdInRange(String[] args) {
49         int cameraDevice = 0;
50         if (args.length > 0) {
51             cameraDevice = Integer.parseInt(args[0]);
52         }
53         //! [cap]
54         cap = new VideoCapture(cameraDevice);
55         //! [cap]
56         if (!cap.isOpened()) {
57             System.err.println("Cannot open camera: " + cameraDevice);
58             System.exit(0);
59         }
60         if (!cap.read(matFrame)) {
61             System.err.println("Cannot read camera stream.");
62             System.exit(0);
63         }
64 
65         //! [window]
66         // Create and set up the window.
67         frame = new JFrame(WINDOW_NAME);
68         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
69         frame.addWindowListener(new WindowAdapter() {
70             @Override
71             public void windowClosing(WindowEvent windowEvent) {
72                 captureTask.cancel(true);
73             }
74         });
75         // Set up the content pane.
76         Image img = HighGui.toBufferedImage(matFrame);
77         addComponentsToPane(frame.getContentPane(), img);
78         // Use the content pane's default BorderLayout. No need for
79         // setLayout(new BorderLayout());
80         // Display the window.
81         frame.pack();
82         frame.setVisible(true);
83         //! [window]
84 
85         captureTask = new CaptureTask();
86         captureTask.execute();
87     }
88 
89     //! [while]
90     private class CaptureTask extends SwingWorker<Void, Mat> {
91         @Override
doInBackground()92         protected Void doInBackground() {
93             Mat matFrame = new Mat();
94 
95             while (!isCancelled()) {
96                 if (!cap.read(matFrame)) {
97                     break;
98                 }
99                 publish(matFrame.clone());
100             }
101             return null;
102         }
103 
104         @Override
process(List<Mat> frames)105         protected void process(List<Mat> frames) {
106             Mat frame = frames.get(frames.size() - 1);
107             Mat frameHSV = new Mat();
108             Imgproc.cvtColor(frame, frameHSV, Imgproc.COLOR_BGR2HSV);
109             Mat thresh = new Mat();
110             Core.inRange(frameHSV, new Scalar(sliderLowH.getValue(), sliderLowS.getValue(), sliderLowV.getValue()),
111                     new Scalar(sliderHighH.getValue(), sliderHighS.getValue(), sliderHighV.getValue()), thresh);
112             update(frame, thresh);
113         }
114     }
115     //! [while]
116 
addComponentsToPane(Container pane, Image img)117     private void addComponentsToPane(Container pane, Image img) {
118         if (!(pane.getLayout() instanceof BorderLayout)) {
119             pane.add(new JLabel("Container doesn't use BorderLayout!"));
120             return;
121         }
122 
123         JPanel sliderPanel = new JPanel();
124         sliderPanel.setLayout(new BoxLayout(sliderPanel, BoxLayout.PAGE_AXIS));
125 
126         //! [trackbar]
127         sliderPanel.add(new JLabel(LOW_H_NAME));
128         sliderLowH = new JSlider(0, MAX_VALUE_H, 0);
129         sliderLowH.setMajorTickSpacing(50);
130         sliderLowH.setMinorTickSpacing(10);
131         sliderLowH.setPaintTicks(true);
132         sliderLowH.setPaintLabels(true);
133         sliderPanel.add(sliderLowH);
134 
135         sliderPanel.add(new JLabel(HIGH_H_NAME));
136         sliderHighH = new JSlider(0, MAX_VALUE_H, MAX_VALUE_H);
137         sliderHighH.setMajorTickSpacing(50);
138         sliderHighH.setMinorTickSpacing(10);
139         sliderHighH.setPaintTicks(true);
140         sliderHighH.setPaintLabels(true);
141         sliderPanel.add(sliderHighH);
142 
143         sliderPanel.add(new JLabel(LOW_S_NAME));
144         sliderLowS = new JSlider(0, MAX_VALUE, 0);
145         sliderLowS.setMajorTickSpacing(50);
146         sliderLowS.setMinorTickSpacing(10);
147         sliderLowS.setPaintTicks(true);
148         sliderLowS.setPaintLabels(true);
149         sliderPanel.add(sliderLowS);
150 
151         sliderPanel.add(new JLabel(HIGH_S_NAME));
152         sliderHighS = new JSlider(0, MAX_VALUE, MAX_VALUE);
153         sliderHighS.setMajorTickSpacing(50);
154         sliderHighS.setMinorTickSpacing(10);
155         sliderHighS.setPaintTicks(true);
156         sliderHighS.setPaintLabels(true);
157         sliderPanel.add(sliderHighS);
158 
159         sliderPanel.add(new JLabel(LOW_V_NAME));
160         sliderLowV = new JSlider(0, MAX_VALUE, 0);
161         sliderLowV.setMajorTickSpacing(50);
162         sliderLowV.setMinorTickSpacing(10);
163         sliderLowV.setPaintTicks(true);
164         sliderLowV.setPaintLabels(true);
165         sliderPanel.add(sliderLowV);
166 
167         sliderPanel.add(new JLabel(HIGH_V_NAME));
168         sliderHighV = new JSlider(0, MAX_VALUE, MAX_VALUE);
169         sliderHighV.setMajorTickSpacing(50);
170         sliderHighV.setMinorTickSpacing(10);
171         sliderHighV.setPaintTicks(true);
172         sliderHighV.setPaintLabels(true);
173         sliderPanel.add(sliderHighV);
174         //! [trackbar]
175 
176         //! [low]
177         sliderLowH.addChangeListener(new ChangeListener() {
178             @Override
179             public void stateChanged(ChangeEvent e) {
180                 JSlider source = (JSlider) e.getSource();
181                 int valH = Math.min(sliderHighH.getValue()-1, source.getValue());
182                 sliderLowH.setValue(valH);
183             }
184         });
185         //! [low]
186         //! [high]
187         sliderHighH.addChangeListener(new ChangeListener() {
188             @Override
189             public void stateChanged(ChangeEvent e) {
190                 JSlider source = (JSlider) e.getSource();
191                 int valH = Math.max(source.getValue(), sliderLowH.getValue()+1);
192                 sliderHighH.setValue(valH);
193             }
194         });
195         //! [high]
196         sliderLowS.addChangeListener(new ChangeListener() {
197             @Override
198             public void stateChanged(ChangeEvent e) {
199                 JSlider source = (JSlider) e.getSource();
200                 int valS = Math.min(sliderHighS.getValue()-1, source.getValue());
201                 sliderLowS.setValue(valS);
202             }
203         });
204         sliderHighS.addChangeListener(new ChangeListener() {
205             @Override
206             public void stateChanged(ChangeEvent e) {
207                 JSlider source = (JSlider) e.getSource();
208                 int valS = Math.max(source.getValue(), sliderLowS.getValue()+1);
209                 sliderHighS.setValue(valS);
210             }
211         });
212         sliderLowV.addChangeListener(new ChangeListener() {
213             @Override
214             public void stateChanged(ChangeEvent e) {
215                 JSlider source = (JSlider) e.getSource();
216                 int valV = Math.min(sliderHighV.getValue()-1, source.getValue());
217                 sliderLowV.setValue(valV);
218             }
219         });
220         sliderHighV.addChangeListener(new ChangeListener() {
221             @Override
222             public void stateChanged(ChangeEvent e) {
223                 JSlider source = (JSlider) e.getSource();
224                 int valV = Math.max(source.getValue(), sliderLowV.getValue()+1);
225                 sliderHighV.setValue(valV);
226             }
227         });
228 
229         pane.add(sliderPanel, BorderLayout.PAGE_START);
230         JPanel framePanel = new JPanel();
231         imgCaptureLabel = new JLabel(new ImageIcon(img));
232         framePanel.add(imgCaptureLabel);
233         imgDetectionLabel = new JLabel(new ImageIcon(img));
234         framePanel.add(imgDetectionLabel);
235         pane.add(framePanel, BorderLayout.CENTER);
236     }
237 
update(Mat imgCapture, Mat imgThresh)238     private void update(Mat imgCapture, Mat imgThresh) {
239         //! [show]
240         imgCaptureLabel.setIcon(new ImageIcon(HighGui.toBufferedImage(imgCapture)));
241         imgDetectionLabel.setIcon(new ImageIcon(HighGui.toBufferedImage(imgThresh)));
242         frame.repaint();
243         //! [show]
244     }
245 
main(String[] args)246     public static void main(String[] args) {
247         // Load the native OpenCV library
248         System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
249 
250         // Schedule a job for the event dispatch thread:
251         // creating and showing this application's GUI.
252         javax.swing.SwingUtilities.invokeLater(new Runnable() {
253             @Override
254             public void run() {
255                 new ThresholdInRange(args);
256             }
257         });
258     }
259 }
260