blob: 757b46c13faa59b9098ac2ad15e179573d67d151 [file] [log] [blame]
jerrymcb7a06a2013-02-17 22:32:29 +00001package org.frc971;
2
jerrymcd2c3322013-02-18 08:49:01 +00003import java.awt.BorderLayout;
4import java.awt.GridLayout;
jerrymcb7a06a2013-02-17 22:32:29 +00005import java.awt.event.KeyEvent;
6import java.io.File;
7import java.io.IOException;
8
9import javax.imageio.ImageIO;
jerrymcd2c3322013-02-18 08:49:01 +000010import javax.swing.JPanel;
11import javax.swing.JSlider;
jerrymcb7a06a2013-02-17 22:32:29 +000012import javax.swing.WindowConstants;
jerrymcd2c3322013-02-18 08:49:01 +000013import javax.swing.event.ChangeEvent;
14import javax.swing.event.ChangeListener;
jerrymcb7a06a2013-02-17 22:32:29 +000015
16import com.googlecode.javacv.CanvasFrame;
17
18import edu.wpi.first.wpijavacv.WPIColorImage;
jerrym6ebe6452013-02-18 03:00:31 +000019import edu.wpi.first.wpijavacv.WPIImage;
jerrymcb7a06a2013-02-17 22:32:29 +000020
21/* REQUIRED JAVA LIBRARIES:
jerrym38d8af12013-02-18 06:54:13 +000022 * external_jars/
23 * javacpp.jar
24 * javacv-YOUR_OS.jar
25 * javacv.jar
26 * WPIJavaCV.jar
jerrymcb7a06a2013-02-17 22:32:29 +000027 *
jerrym38d8af12013-02-18 06:54:13 +000028 * REQUIRED NATIVE CODE LIBRARIES ON $PATH:
29 * Program Files/WPIJavaCV/ [for example]
jerrymcb7a06a2013-02-17 22:32:29 +000030 * JavaCV_2.2.0/javacv-bin/javacv-YOUR_OS.jar
31 * OpenCV_2.2.0/bin/*
jerrym38d8af12013-02-18 06:54:13 +000032 *
33 * The native libraries and javacv-YOUR_OS.jar must match the 32 vs. 64-bit JVM.
jerrymcb7a06a2013-02-17 22:32:29 +000034 */
35/**
36 * FRC 2013 vision-target recognizer tuner app.
37 *
38 * @author jerry
39 */
40public class VisionTuner {
41 private String[] testImageFilenames;
42 private WPIColorImage[] testImages;
jerrymcb7a06a2013-02-17 22:32:29 +000043 private int currentIndex = 0;
jerrym6ebe6452013-02-18 03:00:31 +000044 private Recognizer recognizer = new Recognizer2013();
jerrymcb7a06a2013-02-17 22:32:29 +000045
jerrymcd2c3322013-02-18 08:49:01 +000046 private final CanvasFrame cameraFrame = new CanvasFrame("Camera");
47 private final JPanel panel = new JPanel();
48 private final JSlider hueMinSlider = new JSlider();
49 private final JSlider hueMaxSlider = new JSlider();
50 private final JSlider satMinSlider = new JSlider();
51 private final JSlider valMinSlider = new JSlider();
52
jerrymcb7a06a2013-02-17 22:32:29 +000053 public VisionTuner(String[] imageFilenames) {
54 cameraFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jerrymcb7a06a2013-02-17 22:32:29 +000055
56 loadTestImages(imageFilenames);
jerrymcd2c3322013-02-18 08:49:01 +000057
58 cameraFrame.getContentPane().add(panel, BorderLayout.SOUTH);
59 panel.setLayout(new GridLayout(0, 2, 0, 0));
60
61 ChangeListener sliderListener = new ChangeListener() {
62 @Override
63 public void stateChanged(ChangeEvent e) {
64 System.out.println("New HSV range ["
65 + hueMinSlider.getValue() + " .. "
66 + hueMaxSlider.getValue() + "], ["
67 + satMinSlider.getValue() + " .. 255], ["
68 + valMinSlider.getValue() + " .. 255]");
69 recognizer.setHSVRange(
70 hueMinSlider.getValue(), hueMaxSlider.getValue(),
71 satMinSlider.getValue(),
72 valMinSlider.getValue());
73 processCurrentImage();
74 }
75 };
76
77 hueMinSlider.setValue(recognizer.getHueMin());
78 hueMinSlider.setToolTipText("minimum HSV hue");
79 hueMinSlider.setMaximum(255);
80 panel.add(hueMinSlider);
81
82 hueMaxSlider.setValue(recognizer.getHueMax());
83 hueMaxSlider.setToolTipText("maximum HSV hue");
84 hueMaxSlider.setMaximum(255);
85 panel.add(hueMaxSlider);
86
87 satMinSlider.setValue(recognizer.getSatMin());
88 satMinSlider.setToolTipText("minimum HSV color saturation");
89 satMinSlider.setMaximum(255);
90 panel.add(satMinSlider);
91
92 valMinSlider.setValue(recognizer.getValMin());
93 valMinSlider.setToolTipText("minimum HSV brightness value");
94 valMinSlider.setMaximum(255);
95 panel.add(valMinSlider);
96
97 hueMinSlider.addChangeListener(sliderListener);
98 hueMaxSlider.addChangeListener(sliderListener);
99 satMinSlider.addChangeListener(sliderListener);
100 valMinSlider.addChangeListener(sliderListener);
jerrymcb7a06a2013-02-17 22:32:29 +0000101 }
102
jerrymcb7a06a2013-02-17 22:32:29 +0000103 /**
104 * Loads the named test image files.
105 * Sets testImageFilenames and testImages.
106 */
107 private void loadTestImages(String[] imageFilenames) {
108 testImageFilenames = imageFilenames;
109 testImages = new WPIColorImage[testImageFilenames.length];
jerrymcd2c3322013-02-18 08:49:01 +0000110 currentIndex = 0;
jerrymcb7a06a2013-02-17 22:32:29 +0000111
112 for (int i = 0; i < testImageFilenames.length; i++) {
113 String imageFilename = testImageFilenames[i];
114
115 System.out.println("Loading image file: " + imageFilename);
116 WPIColorImage rawImage = null;
117 try {
jerrym6ebe6452013-02-18 03:00:31 +0000118 rawImage = new WPIColorImage(ImageIO.read(
119 new File(imageFilename)));
jerrymcb7a06a2013-02-17 22:32:29 +0000120 } catch (IOException e) {
jerrym6ebe6452013-02-18 03:00:31 +0000121 System.err.println("Couldn't load image file: " + imageFilename
122 + ": " + e.getMessage());
jerrymcb7a06a2013-02-17 22:32:29 +0000123 System.exit(1);
124 return;
125 }
126 testImages[i] = rawImage;
127 }
128 }
129
130 private void processCurrentImage() {
jerrym6ebe6452013-02-18 03:00:31 +0000131 WPIColorImage cameraImage = testImages[currentIndex];
jerrymcb7a06a2013-02-17 22:32:29 +0000132 cameraFrame.setTitle(testImageFilenames[currentIndex]);
jerrym6ebe6452013-02-18 03:00:31 +0000133
134 WPIImage processedImage = recognizer.processImage(cameraImage);
135 cameraFrame.showImage(processedImage.getBufferedImage());
jerrymcb7a06a2013-02-17 22:32:29 +0000136 }
137
138 private void previousImage() {
139 if (currentIndex > 0) {
140 --currentIndex;
141 }
142 processCurrentImage();
143 }
144
145 private void nextImage() {
146 if (currentIndex + 1 < testImages.length) {
147 ++currentIndex;
148 }
149 processCurrentImage();
150 }
151
152 private void processEvents() {
153 KeyEvent e = cameraFrame.waitKey();
154
155 switch (e.getKeyCode()) {
156 case KeyEvent.VK_LEFT:
157 previousImage();
158 break;
159 case KeyEvent.VK_RIGHT:
160 nextImage();
161 break;
162 }
163 }
164
165 public static void main(final String[] args) {
166 if (args.length == 0) {
167 System.err.println("Usage: " + VisionTuner.class.getName()
168 + " test image filenames...");
169 System.exit(1);
170 }
171
172 VisionTuner tuner = new VisionTuner(args);
173 tuner.processCurrentImage();
174
175 for (;;) {
176 tuner.processEvents();
177 }
178 }
179
180}