blob: c0acc2845136bf3edf775a374e3f55af03ceb6c4 [file] [log] [blame]
Austin Schuh812d0d12021-11-04 20:16:48 -07001// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
Brian Silverman8fce7482020-01-05 13:18:21 -08004
5package edu.wpi.cscore;
6
Brian Silverman8fce7482020-01-05 13:18:21 -08007import edu.wpi.cscore.VideoMode.PixelFormat;
8import edu.wpi.cscore.raw.RawFrame;
Austin Schuh812d0d12021-11-04 20:16:48 -07009import java.nio.ByteBuffer;
10import org.opencv.core.CvType;
11import org.opencv.core.Mat;
Brian Silverman8fce7482020-01-05 13:18:21 -080012
13public class RawCVMatSink extends ImageSink {
14 RawFrame frame = new RawFrame();
15 Mat tmpMat;
16 ByteBuffer origByteBuffer;
17 int width;
18 int height;
19 int pixelFormat;
20 int bgrValue = PixelFormat.kBGR.getValue();
21
22 private int getCVFormat(PixelFormat pixelFormat) {
23 int type = 0;
24 switch (pixelFormat) {
Austin Schuh812d0d12021-11-04 20:16:48 -070025 case kYUYV:
26 case kRGB565:
27 type = CvType.CV_8UC2;
28 break;
29 case kBGR:
30 type = CvType.CV_8UC3;
31 break;
32 case kGray:
33 case kMJPEG:
34 default:
35 type = CvType.CV_8UC1;
36 break;
Brian Silverman8fce7482020-01-05 13:18:21 -080037 }
38 return type;
39 }
40
41 /**
Austin Schuh812d0d12021-11-04 20:16:48 -070042 * Create a sink for accepting OpenCV images. WaitForFrame() must be called on the created sink to
43 * get each new image.
Brian Silverman8fce7482020-01-05 13:18:21 -080044 *
45 * @param name Source name (arbitrary unique identifier)
46 */
47 public RawCVMatSink(String name) {
48 super(CameraServerJNI.createRawSink(name));
49 }
50
51 /**
Austin Schuh812d0d12021-11-04 20:16:48 -070052 * Wait for the next frame and get the image. Times out (returning 0) after 0.225 seconds. The
53 * provided image will have three 3-bit channels stored in BGR order.
Brian Silverman8fce7482020-01-05 13:18:21 -080054 *
Austin Schuh812d0d12021-11-04 20:16:48 -070055 * @return Frame time, or 0 on error (call GetError() to obtain the error message)
Brian Silverman8fce7482020-01-05 13:18:21 -080056 */
57 public long grabFrame(Mat image) {
58 return grabFrame(image, 0.225);
59 }
60
61 /**
Austin Schuh812d0d12021-11-04 20:16:48 -070062 * Wait for the next frame and get the image. Times out (returning 0) after timeout seconds. The
63 * provided image will have three 3-bit channels stored in BGR order.
Brian Silverman8fce7482020-01-05 13:18:21 -080064 *
Austin Schuh812d0d12021-11-04 20:16:48 -070065 * @return Frame time, or 0 on error (call GetError() to obtain the error message); the frame time
66 * is in 1 us increments.
Brian Silverman8fce7482020-01-05 13:18:21 -080067 */
68 public long grabFrame(Mat image, double timeout) {
69 frame.setWidth(0);
70 frame.setHeight(0);
71 frame.setPixelFormat(bgrValue);
72 long rv = CameraServerJNI.grabSinkFrameTimeout(m_handle, frame, timeout);
73 if (rv <= 0) {
74 return rv;
75 }
76
Austin Schuh812d0d12021-11-04 20:16:48 -070077 if (frame.getDataByteBuffer() != origByteBuffer
78 || width != frame.getWidth()
79 || height != frame.getHeight()
80 || pixelFormat != frame.getPixelFormat()) {
Brian Silverman8fce7482020-01-05 13:18:21 -080081 origByteBuffer = frame.getDataByteBuffer();
82 height = frame.getHeight();
83 width = frame.getWidth();
84 pixelFormat = frame.getPixelFormat();
Austin Schuh812d0d12021-11-04 20:16:48 -070085 tmpMat =
86 new Mat(
87 frame.getHeight(),
88 frame.getWidth(),
89 getCVFormat(VideoMode.getPixelFormatFromInt(pixelFormat)),
90 origByteBuffer);
Brian Silverman8fce7482020-01-05 13:18:21 -080091 }
92 tmpMat.copyTo(image);
93 return rv;
94 }
95}