001/*----------------------------------------------------------------------------*/ 002/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */ 003/* Open Source Software - may be modified and shared by FRC teams. The code */ 004/* must be accompanied by the FIRST BSD license file in the root directory of */ 005/* the project. */ 006/*----------------------------------------------------------------------------*/ 007 008package edu.wpi.cscore; 009 010import org.opencv.core.Mat; 011 012/** 013 * A sink for user code to accept video frames as OpenCV images. 014 */ 015public class CvSink extends VideoSink { 016 /** 017 * Create a sink for accepting OpenCV images. 018 * WaitForFrame() must be called on the created sink to get each new 019 * image. 020 * @param name Source name (arbitrary unique identifier) 021 */ 022 public CvSink(String name) { 023 super(CameraServerJNI.createCvSink(name)); 024 } 025 026 /// Create a sink for accepting OpenCV images in a separate thread. 027 /// A thread will be created that calls WaitForFrame() and calls the 028 /// processFrame() callback each time a new frame arrives. 029 /// @param name Source name (arbitrary unique identifier) 030 /// @param processFrame Frame processing function; will be called with a 031 /// time=0 if an error occurred. processFrame should call GetImage() 032 /// or GetError() as needed, but should not call (except in very 033 /// unusual circumstances) WaitForImage(). 034 //public CvSink(llvm::StringRef name, 035 // std::function<void(uint64_t time)> processFrame) { 036 // super(CameraServerJNI.createCvSinkCallback(name, processFrame)); 037 //} 038 039 /** 040 * Set sink description. 041 * @param description Description 042 */ 043 public void setDescription(String description) { 044 CameraServerJNI.setSinkDescription(m_handle, description); 045 } 046 047 /** 048 * Wait for the next frame and get the image. 049 * Times out (returning 0) after 0.225 seconds. 050 * The provided image will have three 3-bit channels stored in BGR order. 051 * @return Frame time, or 0 on error (call GetError() to obtain the error 052 * message) 053 */ 054 public long grabFrame(Mat image) { 055 return grabFrame(image, 0.225); 056 } 057 058 /** 059 * Wait for the next frame and get the image. 060 * Times out (returning 0) after timeout seconds. 061 * The provided image will have three 3-bit channels stored in BGR order. 062 * @return Frame time, or 0 on error (call GetError() to obtain the error 063 * message); the frame time is in 1 us increments. 064 */ 065 public long grabFrame(Mat image, double timeout) { 066 return CameraServerJNI.grabSinkFrameTimeout(m_handle, image.nativeObj, timeout); 067 } 068 069 /** 070 * Wait for the next frame and get the image. May block forever. 071 * The provided image will have three 3-bit channels stored in BGR order. 072 * @return Frame time, or 0 on error (call GetError() to obtain the error 073 * message); the frame time is in 1 us increments. 074 */ 075 public long grabFrameNoTimeout(Mat image) { 076 return CameraServerJNI.grabSinkFrame(m_handle, image.nativeObj); 077 } 078 079 /** 080 * Get error string. Call this if WaitForFrame() returns 0 to determine 081 * what the error is. 082 */ 083 public String getError() { 084 return CameraServerJNI.getSinkError(m_handle); 085 } 086 087 /** 088 * Enable or disable getting new frames. 089 * Disabling will cause processFrame (for callback-based CvSinks) to not 090 * be called and WaitForFrame() to not return. This can be used to save 091 * processor resources when frames are not needed. 092 */ 093 public void setEnabled(boolean enabled) { 094 CameraServerJNI.setSinkEnabled(m_handle, enabled); 095 } 096}