2020-12-26 14:12:05 -08:00
|
|
|
// Copyright (c) FIRST and other WPILib contributors.
|
|
|
|
|
// Open Source Software; you can modify and/or share it under the terms of
|
|
|
|
|
// the WPILib BSD license file in the root directory of this project.
|
2019-05-30 19:12:05 -07:00
|
|
|
|
|
|
|
|
package edu.wpi.cscore;
|
|
|
|
|
|
2020-12-29 22:45:16 -08:00
|
|
|
import edu.wpi.cscore.VideoMode.PixelFormat;
|
|
|
|
|
import edu.wpi.cscore.raw.RawFrame;
|
2019-05-30 19:12:05 -07:00
|
|
|
import java.nio.ByteBuffer;
|
|
|
|
|
import org.opencv.core.CvType;
|
|
|
|
|
import org.opencv.core.Mat;
|
|
|
|
|
|
|
|
|
|
public class RawCVMatSink extends ImageSink {
|
|
|
|
|
RawFrame frame = new RawFrame();
|
|
|
|
|
Mat tmpMat;
|
|
|
|
|
ByteBuffer origByteBuffer;
|
|
|
|
|
int width;
|
|
|
|
|
int height;
|
|
|
|
|
int pixelFormat;
|
|
|
|
|
int bgrValue = PixelFormat.kBGR.getValue();
|
|
|
|
|
|
|
|
|
|
private int getCVFormat(PixelFormat pixelFormat) {
|
|
|
|
|
int type = 0;
|
|
|
|
|
switch (pixelFormat) {
|
2020-12-29 22:45:16 -08:00
|
|
|
case kYUYV:
|
|
|
|
|
case kRGB565:
|
|
|
|
|
type = CvType.CV_8UC2;
|
|
|
|
|
break;
|
|
|
|
|
case kBGR:
|
|
|
|
|
type = CvType.CV_8UC3;
|
|
|
|
|
break;
|
|
|
|
|
case kGray:
|
|
|
|
|
case kMJPEG:
|
|
|
|
|
default:
|
|
|
|
|
type = CvType.CV_8UC1;
|
|
|
|
|
break;
|
2019-05-30 19:12:05 -07:00
|
|
|
}
|
|
|
|
|
return type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2020-12-29 22:45:16 -08:00
|
|
|
* Create a sink for accepting OpenCV images. WaitForFrame() must be called on the created sink to
|
|
|
|
|
* get each new image.
|
2019-05-30 19:12:05 -07:00
|
|
|
*
|
|
|
|
|
* @param name Source name (arbitrary unique identifier)
|
|
|
|
|
*/
|
|
|
|
|
public RawCVMatSink(String name) {
|
|
|
|
|
super(CameraServerJNI.createRawSink(name));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2020-12-29 22:45:16 -08:00
|
|
|
* Wait for the next frame and get the image. Times out (returning 0) after 0.225 seconds. The
|
|
|
|
|
* provided image will have three 3-bit channels stored in BGR order.
|
2019-05-30 19:12:05 -07:00
|
|
|
*
|
2020-12-29 22:45:16 -08:00
|
|
|
* @return Frame time, or 0 on error (call GetError() to obtain the error message)
|
2019-05-30 19:12:05 -07:00
|
|
|
*/
|
|
|
|
|
public long grabFrame(Mat image) {
|
|
|
|
|
return grabFrame(image, 0.225);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2020-12-29 22:45:16 -08:00
|
|
|
* Wait for the next frame and get the image. Times out (returning 0) after timeout seconds. The
|
|
|
|
|
* provided image will have three 3-bit channels stored in BGR order.
|
2019-05-30 19:12:05 -07:00
|
|
|
*
|
2020-12-29 22:45:16 -08:00
|
|
|
* @return Frame time, or 0 on error (call GetError() to obtain the error message); the frame time
|
|
|
|
|
* is in 1 us increments.
|
2019-05-30 19:12:05 -07:00
|
|
|
*/
|
|
|
|
|
public long grabFrame(Mat image, double timeout) {
|
|
|
|
|
frame.setWidth(0);
|
|
|
|
|
frame.setHeight(0);
|
|
|
|
|
frame.setPixelFormat(bgrValue);
|
|
|
|
|
long rv = CameraServerJNI.grabSinkFrameTimeout(m_handle, frame, timeout);
|
|
|
|
|
if (rv <= 0) {
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-29 22:45:16 -08:00
|
|
|
if (frame.getDataByteBuffer() != origByteBuffer
|
|
|
|
|
|| width != frame.getWidth()
|
|
|
|
|
|| height != frame.getHeight()
|
|
|
|
|
|| pixelFormat != frame.getPixelFormat()) {
|
2019-05-30 19:12:05 -07:00
|
|
|
origByteBuffer = frame.getDataByteBuffer();
|
|
|
|
|
height = frame.getHeight();
|
|
|
|
|
width = frame.getWidth();
|
|
|
|
|
pixelFormat = frame.getPixelFormat();
|
2020-12-29 22:45:16 -08:00
|
|
|
tmpMat =
|
|
|
|
|
new Mat(
|
|
|
|
|
frame.getHeight(),
|
|
|
|
|
frame.getWidth(),
|
|
|
|
|
getCVFormat(VideoMode.getPixelFormatFromInt(pixelFormat)),
|
|
|
|
|
origByteBuffer);
|
2019-05-30 19:12:05 -07:00
|
|
|
}
|
|
|
|
|
tmpMat.copyTo(image);
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
}
|