Commit | Line | Data |
---|---|---|
e59e98fc TW |
1 | package kaka.cakelight; |
2 | ||
3 | import org.opencv.core.CvType; | |
4 | import org.opencv.core.Mat; | |
5 | import org.opencv.core.Size; | |
6 | import org.opencv.imgproc.Imgproc; | |
7 | ||
4a2d6056 TW |
8 | import java.awt.*; |
9 | ||
e59e98fc TW |
10 | import static kaka.cakelight.Main.saveFile; |
11 | import static kaka.cakelight.Main.timeIt; | |
12 | ||
13 | public class Frame { | |
14 | private byte[] data; | |
15 | private Configuration config; | |
4a2d6056 TW |
16 | private Mat colImage; |
17 | private Mat rowImage; | |
e59e98fc TW |
18 | |
19 | private Frame(byte[] data) { | |
20 | this.data = data; | |
21 | } | |
22 | ||
23 | public static Frame of(byte[] data, Configuration config) { | |
24 | Frame frame = new Frame(data); | |
25 | frame.config = config; | |
26 | frame.convert(); | |
27 | return frame; | |
28 | } | |
29 | ||
30 | private void convert() { | |
4a2d6056 TW |
31 | /* TODO: how to do this? |
32 | 1) Resize to an image with the size of the number of leds and use config to define how many pixels deep into the screen to use. | |
33 | 2) Resize to 16x9 and use 2 pixels of depth (or maybe 3) and interpolate for each led. | |
34 | 3) Resize to 2 images where each led uses 2 pixels: | |
35 | vertical - 16 x <#leds> | |
36 | horizontal - <#leds> x 9 | |
37 | */ | |
e59e98fc TW |
38 | Mat src = new Mat(config.video.height, config.video.width, CvType.CV_8UC2); // 8-bit, unsigned, 2 channels |
39 | src.put(0, 0, data); | |
40 | ||
4a2d6056 TW |
41 | // Mat converted = new Mat(); |
42 | // Mat resized = new Mat(); | |
43 | // | |
44 | // timeIt("total", () -> { | |
45 | // timeIt("yuyv2rgb", () -> Imgproc.cvtColor(src, converted, Imgproc.COLOR_YUV2RGB_YUYV)); // 3.5 - 4.0 ms | |
46 | // timeIt("resizing", () -> Imgproc.resize(converted, resized, new Size(config.leds.cols, config.leds.rows), 0, 0, Imgproc.INTER_AREA)); // INTER_AREA is the best for shrinking, but also the slowest (~1.5 ms) | |
47 | // }); | |
e59e98fc | 48 | |
4a2d6056 TW |
49 | Mat converted = new Mat(); |
50 | Imgproc.cvtColor(src, converted, Imgproc.COLOR_YUV2RGB_YUYV); | |
51 | timeIt("model 1", () -> model1(converted, Imgproc.INTER_AREA)); | |
52 | timeIt("model 2", () -> model2(converted, Imgproc.INTER_AREA)); | |
53 | timeIt("model 3", () -> model3(converted, Imgproc.INTER_AREA)); | |
e59e98fc TW |
54 | // save(converted, "/home/kaka/test-converted.data"); |
55 | // save(resized, "/home/kaka/test-resized.data"); | |
4a2d6056 TW |
56 | System.out.println("color: " + getPixel(ListPosition.BOTTOM, 0)); |
57 | } | |
58 | ||
59 | private void model1(Mat src, int interpolation) { | |
60 | Mat resized = new Mat(); | |
61 | Imgproc.resize(src, resized, new Size(config.leds.cols, config.leds.rows), 0, 0, interpolation); | |
62 | } | |
63 | ||
64 | private void model2(Mat src, int interpolation) { | |
65 | Mat resized = new Mat(); | |
66 | Imgproc.resize(src, resized, new Size(16, 9), 0, 0, interpolation); | |
67 | } | |
68 | ||
69 | private void model3(Mat src, int interpolation) { | |
70 | colImage = new Mat(); | |
71 | rowImage = new Mat(); | |
72 | Imgproc.resize(src, colImage, new Size(config.leds.cols, 9), 0, 0, interpolation); | |
73 | Imgproc.resize(src, rowImage, new Size(16, config.leds.rows), 0, 0, interpolation); | |
74 | } | |
75 | ||
76 | public Color getPixel(ListPosition listPosition, int xy) { | |
77 | switch (listPosition) { | |
78 | case LEFT: | |
79 | return pixelToColor(rowImage, 0, xy); | |
80 | case RIGHT: | |
81 | return pixelToColor(rowImage, config.leds.cols - 1, xy); | |
82 | case TOP: | |
83 | return pixelToColor(colImage, xy, 0); | |
84 | case BOTTOM: | |
85 | return pixelToColor(colImage, xy, config.leds.cols - 1); | |
86 | } | |
87 | return null; | |
88 | } | |
89 | ||
90 | private Color pixelToColor(Mat image, int x, int y) { | |
91 | byte[] rgb = new byte[3]; | |
92 | image.get(y, x, rgb); | |
93 | System.out.println("r = " + rgb[0] + ", g = " + rgb[1] + ", b = " + rgb[2]); | |
94 | return new Color(rgb[0], rgb[1], rgb[2]); | |
e59e98fc TW |
95 | } |
96 | ||
97 | private void save(Mat mat, String filepath) { | |
98 | byte[] data = new byte[mat.cols() * mat.rows() * mat.channels()]; | |
99 | mat.get(0, 0, data); | |
100 | saveFile(data, filepath); | |
101 | } | |
102 | ||
103 | public byte[] getData() { | |
104 | return data; | |
105 | } | |
106 | } |