Austin Schuh | 812d0d1 | 2021-11-04 20:16:48 -0700 | [diff] [blame] | 1 | // 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 Silverman | 8fce748 | 2020-01-05 13:18:21 -0800 | [diff] [blame] | 4 | |
| 5 | package edu.wpi.cscore; |
| 6 | |
Brian Silverman | 8fce748 | 2020-01-05 13:18:21 -0800 | [diff] [blame] | 7 | import edu.wpi.cscore.VideoMode.PixelFormat; |
| 8 | import edu.wpi.cscore.raw.RawFrame; |
Austin Schuh | 812d0d1 | 2021-11-04 20:16:48 -0700 | [diff] [blame] | 9 | import java.nio.ByteBuffer; |
| 10 | import org.opencv.core.CvType; |
| 11 | import org.opencv.core.Mat; |
Brian Silverman | 8fce748 | 2020-01-05 13:18:21 -0800 | [diff] [blame] | 12 | |
| 13 | public 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 Schuh | 812d0d1 | 2021-11-04 20:16:48 -0700 | [diff] [blame] | 25 | 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 Silverman | 8fce748 | 2020-01-05 13:18:21 -0800 | [diff] [blame] | 37 | } |
| 38 | return type; |
| 39 | } |
| 40 | |
| 41 | /** |
Austin Schuh | 812d0d1 | 2021-11-04 20:16:48 -0700 | [diff] [blame] | 42 | * Create a sink for accepting OpenCV images. WaitForFrame() must be called on the created sink to |
| 43 | * get each new image. |
Brian Silverman | 8fce748 | 2020-01-05 13:18:21 -0800 | [diff] [blame] | 44 | * |
| 45 | * @param name Source name (arbitrary unique identifier) |
| 46 | */ |
| 47 | public RawCVMatSink(String name) { |
| 48 | super(CameraServerJNI.createRawSink(name)); |
| 49 | } |
| 50 | |
| 51 | /** |
Austin Schuh | 812d0d1 | 2021-11-04 20:16:48 -0700 | [diff] [blame] | 52 | * 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 Silverman | 8fce748 | 2020-01-05 13:18:21 -0800 | [diff] [blame] | 54 | * |
Austin Schuh | 812d0d1 | 2021-11-04 20:16:48 -0700 | [diff] [blame] | 55 | * @return Frame time, or 0 on error (call GetError() to obtain the error message) |
Brian Silverman | 8fce748 | 2020-01-05 13:18:21 -0800 | [diff] [blame] | 56 | */ |
| 57 | public long grabFrame(Mat image) { |
| 58 | return grabFrame(image, 0.225); |
| 59 | } |
| 60 | |
| 61 | /** |
Austin Schuh | 812d0d1 | 2021-11-04 20:16:48 -0700 | [diff] [blame] | 62 | * 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 Silverman | 8fce748 | 2020-01-05 13:18:21 -0800 | [diff] [blame] | 64 | * |
Austin Schuh | 812d0d1 | 2021-11-04 20:16:48 -0700 | [diff] [blame] | 65 | * @return Frame time, or 0 on error (call GetError() to obtain the error message); the frame time |
| 66 | * is in 1 us increments. |
Brian Silverman | 8fce748 | 2020-01-05 13:18:21 -0800 | [diff] [blame] | 67 | */ |
| 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 Schuh | 812d0d1 | 2021-11-04 20:16:48 -0700 | [diff] [blame] | 77 | if (frame.getDataByteBuffer() != origByteBuffer |
| 78 | || width != frame.getWidth() |
| 79 | || height != frame.getHeight() |
| 80 | || pixelFormat != frame.getPixelFormat()) { |
Brian Silverman | 8fce748 | 2020-01-05 13:18:21 -0800 | [diff] [blame] | 81 | origByteBuffer = frame.getDataByteBuffer(); |
| 82 | height = frame.getHeight(); |
| 83 | width = frame.getWidth(); |
| 84 | pixelFormat = frame.getPixelFormat(); |
Austin Schuh | 812d0d1 | 2021-11-04 20:16:48 -0700 | [diff] [blame] | 85 | tmpMat = |
| 86 | new Mat( |
| 87 | frame.getHeight(), |
| 88 | frame.getWidth(), |
| 89 | getCVFormat(VideoMode.getPixelFormatFromInt(pixelFormat)), |
| 90 | origByteBuffer); |
Brian Silverman | 8fce748 | 2020-01-05 13:18:21 -0800 | [diff] [blame] | 91 | } |
| 92 | tmpMat.copyTo(image); |
| 93 | return rv; |
| 94 | } |
| 95 | } |