WIP
[kaka/cakelight.git] / src / kaka / cakelight / Frame.java
CommitLineData
e59e98fc
TW
1package kaka.cakelight;
2
3import org.opencv.core.CvType;
4import org.opencv.core.Mat;
5import org.opencv.core.Size;
6import org.opencv.imgproc.Imgproc;
7
4a2d6056
TW
8import java.awt.*;
9
e59e98fc
TW
10import static kaka.cakelight.Main.saveFile;
11import static kaka.cakelight.Main.timeIt;
12
13public 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}