James Kuszmaul | 4f3ad3c | 2019-12-01 16:35:21 -0800 | [diff] [blame] | 1 | /*----------------------------------------------------------------------------*/ |
| 2 | /* Copyright (c) 2018-2019 FIRST. All Rights Reserved. */ |
| 3 | /* Open Source Software - may be modified and shared by FRC teams. The code */ |
| 4 | /* must be accompanied by the FIRST BSD license file in the root directory of */ |
| 5 | /* the project. */ |
| 6 | /*----------------------------------------------------------------------------*/ |
| 7 | |
| 8 | package edu.wpi.cscore; |
| 9 | |
| 10 | import java.nio.ByteBuffer; |
| 11 | |
| 12 | import org.opencv.core.CvType; |
| 13 | import org.opencv.core.Mat; |
| 14 | |
| 15 | import edu.wpi.cscore.VideoMode.PixelFormat; |
| 16 | import edu.wpi.cscore.raw.RawFrame; |
| 17 | |
| 18 | public class RawCVMatSink extends ImageSink { |
| 19 | RawFrame frame = new RawFrame(); |
| 20 | Mat tmpMat; |
| 21 | ByteBuffer origByteBuffer; |
| 22 | int width; |
| 23 | int height; |
| 24 | int pixelFormat; |
| 25 | int bgrValue = PixelFormat.kBGR.getValue(); |
| 26 | |
| 27 | private int getCVFormat(PixelFormat pixelFormat) { |
| 28 | int type = 0; |
| 29 | switch (pixelFormat) { |
| 30 | case kYUYV: |
| 31 | case kRGB565: |
| 32 | type = CvType.CV_8UC2; |
| 33 | break; |
| 34 | case kBGR: |
| 35 | type = CvType.CV_8UC3; |
| 36 | break; |
| 37 | case kGray: |
| 38 | case kMJPEG: |
| 39 | default: |
| 40 | type = CvType.CV_8UC1; |
| 41 | break; |
| 42 | } |
| 43 | return type; |
| 44 | } |
| 45 | |
| 46 | /** |
| 47 | * Create a sink for accepting OpenCV images. |
| 48 | * WaitForFrame() must be called on the created sink to get each new |
| 49 | * image. |
| 50 | * |
| 51 | * @param name Source name (arbitrary unique identifier) |
| 52 | */ |
| 53 | public RawCVMatSink(String name) { |
| 54 | super(CameraServerJNI.createRawSink(name)); |
| 55 | } |
| 56 | |
| 57 | /** |
| 58 | * Wait for the next frame and get the image. |
| 59 | * Times out (returning 0) after 0.225 seconds. |
| 60 | * The provided image will have three 3-bit channels stored in BGR order. |
| 61 | * |
| 62 | * @return Frame time, or 0 on error (call GetError() to obtain the error |
| 63 | * message) |
| 64 | */ |
| 65 | public long grabFrame(Mat image) { |
| 66 | return grabFrame(image, 0.225); |
| 67 | } |
| 68 | |
| 69 | /** |
| 70 | * Wait for the next frame and get the image. |
| 71 | * Times out (returning 0) after timeout seconds. |
| 72 | * The provided image will have three 3-bit channels stored in BGR order. |
| 73 | * |
| 74 | * @return Frame time, or 0 on error (call GetError() to obtain the error |
| 75 | * message); the frame time is in 1 us increments. |
| 76 | */ |
| 77 | public long grabFrame(Mat image, double timeout) { |
| 78 | frame.setWidth(0); |
| 79 | frame.setHeight(0); |
| 80 | frame.setPixelFormat(bgrValue); |
| 81 | long rv = CameraServerJNI.grabSinkFrameTimeout(m_handle, frame, timeout); |
| 82 | if (rv <= 0) { |
| 83 | return rv; |
| 84 | } |
| 85 | |
| 86 | if (frame.getDataByteBuffer() != origByteBuffer || width != frame.getWidth() || height != frame.getHeight() || pixelFormat != frame.getPixelFormat()) { |
| 87 | origByteBuffer = frame.getDataByteBuffer(); |
| 88 | height = frame.getHeight(); |
| 89 | width = frame.getWidth(); |
| 90 | pixelFormat = frame.getPixelFormat(); |
| 91 | tmpMat = new Mat(frame.getHeight(), frame.getWidth(), getCVFormat(VideoMode.getPixelFormatFromInt(pixelFormat)), origByteBuffer); |
| 92 | } |
| 93 | tmpMat.copyTo(image); |
| 94 | return rv; |
| 95 | } |
| 96 | } |