1 package kaka.cakelight;
3 import javafx.scene.paint.Color;
4 import org.opencv.core.CvType;
5 import org.opencv.core.Mat;
6 import org.opencv.core.Size;
7 import org.opencv.imgproc.Imgproc;
9 import static kaka.cakelight.Main.saveFile;
10 import static kaka.cakelight.Main.timeIt;
14 private Configuration config;
17 private Mat converted;
19 private Frame(byte[] data) {
23 public static Frame of(byte[] data, Configuration config) {
24 Frame frame = new Frame(data);
25 frame.config = config;
30 private void convert() {
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
38 Mat src = new Mat(config.video.height, config.video.width, CvType.CV_8UC2); // 8-bit, unsigned, 2 channels
41 // Mat converted = new Mat();
42 // Mat resized = new Mat();
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)
49 Mat cropped = src.submat(
50 config.video.crop.top,
51 config.video.height - config.video.crop.bottom,
52 config.video.crop.left,
53 config.video.width - config.video.crop.right
55 converted = new Mat();
56 Imgproc.cvtColor(cropped, converted, Imgproc.COLOR_YUV2RGB_YUYV);
57 // timeIt("model 1", () -> model1(converted, Imgproc.INTER_AREA));
58 // timeIt("model 2", () -> model2(converted, Imgproc.INTER_AREA));
59 timeIt("model 3", () -> model3(converted, Imgproc.INTER_AREA));
60 // save(converted, "/home/kaka/test-converted.data");
61 // save(resized, "/home/kaka/test-resized.data");
66 private void model1(Mat src, int interpolation) {
67 Mat resized = new Mat();
68 Imgproc.resize(src, resized, new Size(config.leds.cols, config.leds.rows), 0, 0, interpolation);
71 private void model2(Mat src, int interpolation) {
72 Mat resized = new Mat();
73 Imgproc.resize(src, resized, new Size(16, 9), 0, 0, interpolation);
76 private void model3(Mat src, int interpolation) {
79 Imgproc.resize(src, colImage, new Size(config.leds.cols, 9), 0, 0, interpolation);
80 Imgproc.resize(src, rowImage, new Size(16, config.leds.rows), 0, 0, interpolation);
83 public Color getLedColor(ListPosition listPosition, int xy) {
84 switch (listPosition) {
86 return interpolatedRowColor(xy, 0, 1, 2);
88 return interpolatedRowColor(xy, 15, 14, 13);
90 return interpolatedColColor(xy, 0, 1, 2);
92 return interpolatedColColor(xy, 8, 7, 6);
97 private Color interpolatedRowColor(int y, int x1, int x2, int x3) {
98 return pixelToColor(rowImage, x3, y).interpolate(pixelToColor(rowImage, x2, y), 0.65).interpolate(pixelToColor(rowImage, x1, y), 0.65);
101 private Color interpolatedColColor(int x, int y1, int y2, int y3) {
102 return pixelToColor(colImage, x, y3).interpolate(pixelToColor(colImage, x, y2), 0.65).interpolate(pixelToColor(colImage, x, y1), 0.65);
105 private Color pixelToColor(Mat image, int x, int y) {
106 byte[] rgb = new byte[3];
107 image.get(y, x, rgb);
108 return Color.rgb(rgb[0] & 0xff, rgb[1] & 0xff, rgb[2] & 0xff);
111 private void save(Mat mat, String filepath) {
112 byte[] data = new byte[mat.cols() * mat.rows() * mat.channels()];
114 saveFile(data, filepath);
117 public byte[] getData() {
118 byte[] buff = new byte[(int) (converted.total() * converted.channels())];
119 converted.get(0, 0, buff);
123 public Mat getColImage() {
127 public Mat getRowImage() {
131 public Mat getConvertedImage() {
136 * Creates a LED frame going clockwise from the bottom-left corner, sans the corners.
138 public LedFrame getLedFrame() {
139 LedFrame frame = LedFrame.from(config);
141 for (int i = config.leds.rows - 1; i >= 0; i--) frame.setLedColor(led++, getLedColor(ListPosition.LEFT, i));
142 for (int i = 0; i < config.leds.cols; i++) frame.setLedColor(led++, getLedColor(ListPosition.TOP, i));
143 for (int i = 0; i < config.leds.rows; i++) frame.setLedColor(led++, getLedColor(ListPosition.RIGHT, i));
144 for (int i = config.leds.cols - 1; i >= 0; i--) frame.setLedColor(led++, getLedColor(ListPosition.BOTTOM, i));