WPILibC++ 2024.3.2
cscore_raw_cv.h
Go to the documentation of this file.
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.
4
5#ifndef CSCORE_CSCORE_RAW_CV_H_
6#define CSCORE_CSCORE_RAW_CV_H_
7
8#ifdef CSCORE_CSCORE_CV_H_
9#error "Cannot include both cscore_cv.h and cscore_raw_cv.h in the same file"
10#endif
11
12#include <functional>
13
14#include <opencv2/core/mat.hpp>
15
16#include "cscore_raw.h"
17
18namespace cs {
19/**
20 * A source for using the raw frame API to provide opencv images.
21 *
22 * If you are using the WPILib OpenCV builds, do not use this, and
23 * instead include "cscore_cv.h" to get a more performant version.
24 *
25 * This is not dependent on any opencv binary ABI, and can be used
26 * with versions of OpenCV that are not 3. If using OpenCV 3, use
27 * CvSource.
28 */
29class RawCvSource : public RawSource {
30 public:
31 RawCvSource() = default;
32
33 /**
34 * Create a Raw OpenCV source.
35 *
36 * @param name Source name (arbitrary unique identifier)
37 * @param mode Video mode being generated
38 */
39 RawCvSource(std::string_view name, const VideoMode& mode);
40
41 /**
42 * Create a Raw OpenCV source.
43 *
44 * @param name Source name (arbitrary unique identifier)
45 * @param pixelFormat Pixel format
46 * @param width width
47 * @param height height
48 * @param fps fps
49 */
51 int width, int height, int fps);
52
53 /**
54 * Put an OpenCV image and notify sinks.
55 *
56 * <p>Only 8-bit single-channel or 3-channel (with BGR channel order) images
57 * are supported. If the format, depth or channel order is different, use
58 * cv::Mat::convertTo() and/or cv::cvtColor() to convert it first.
59 *
60 * @param image OpenCV image
61 */
62 void PutFrame(cv::Mat& image);
63
64 private:
65 wpi::RawFrame rawFrame;
66};
67
68/**
69 * A sink for user code to accept raw video frames as OpenCV images.
70 *
71 * If you are using the WPILib OpenCV builds, do not use this, and
72 * instead include "cscore_cv.h" to get a more performant version.
73 *
74 * This is not dependent on any opencv binary ABI, and can be used
75 * with versions of OpenCV that are not 3. If using OpenCV 3, use
76 * CvSink.
77 */
78class RawCvSink : public RawSink {
79 public:
80 RawCvSink() = default;
81
82 /**
83 * Create a sink for accepting OpenCV images.
84 *
85 * <p>WaitForFrame() must be called on the created sink to get each new
86 * image.
87 *
88 * @param name Source name (arbitrary unique identifier)
89 */
90 explicit RawCvSink(std::string_view name);
91
92 /**
93 * Create a sink for accepting OpenCV images in a separate thread.
94 *
95 * <p>A thread will be created that calls WaitForFrame() and calls the
96 * processFrame() callback each time a new frame arrives.
97 *
98 * @param name Source name (arbitrary unique identifier)
99 * @param processFrame Frame processing function; will be called with a
100 * time=0 if an error occurred. processFrame should call GetImage()
101 * or GetError() as needed, but should not call (except in very
102 * unusual circumstances) WaitForImage().
103 */
105 std::function<void(uint64_t time)> processFrame);
106
107 /**
108 * Wait for the next frame and get the image.
109 * Times out (returning 0) after timeout seconds.
110 * The provided image will have three 8-bit channels stored in BGR order.
111 *
112 * @return Frame time, or 0 on error (call GetError() to obtain the error
113 * message); the frame time is in the same time base as wpi::Now(),
114 * and is in 1 us increments.
115 */
116 [[nodiscard]]
117 uint64_t GrabFrame(cv::Mat& image, double timeout = 0.225);
118
119 /**
120 * Wait for the next frame and get the image. May block forever.
121 * The provided image will have three 8-bit channels stored in BGR order.
122 *
123 * @return Frame time, or 0 on error (call GetError() to obtain the error
124 * message); the frame time is in the same time base as wpi::Now(),
125 * and is in 1 us increments.
126 */
127 [[nodiscard]]
128 uint64_t GrabFrameNoTimeout(cv::Mat& image);
129
130 /**
131 * Wait for the next frame and get the image.
132 * Times out (returning 0) after timeout seconds.
133 * The provided image will have three 8-bit channels stored in BGR order.
134 *
135 * @return Frame time, or 0 on error (call GetError() to obtain the error
136 * message); the frame time is in the same time base as wpi::Now(),
137 * and is in 1 us increments.
138 */
139 [[nodiscard]]
140 uint64_t GrabFrameDirect(cv::Mat& image, double timeout = 0.225);
141
142 /**
143 * Wait for the next frame and get the image. May block forever.
144 * The provided image will have three 8-bit channels stored in BGR order.
145 *
146 * @return Frame time, or 0 on error (call GetError() to obtain the error
147 * message); the frame time is in the same time base as wpi::Now(),
148 * and is in 1 us increments.
149 */
150 [[nodiscard]]
151 uint64_t GrabFrameNoTimeoutDirect(cv::Mat& image);
152
153 private:
154 wpi::RawFrame rawFrame;
155};
156
158 : RawSource{name, mode} {}
159
162 int height, int fps)
163 : RawSource{name, format, width, height, fps} {}
164
165inline void RawCvSource::PutFrame(cv::Mat& image) {
166 m_status = 0;
167 rawFrame.data = reinterpret_cast<char*>(image.data);
168 rawFrame.width = image.cols;
169 rawFrame.height = image.rows;
170 rawFrame.totalData = image.total() * image.channels();
171 rawFrame.pixelFormat =
172 image.channels() == 3 ? WPI_PIXFMT_BGR : WPI_PIXFMT_GRAY;
173 PutSourceFrame(m_handle, rawFrame, &m_status);
174}
175
177
179 std::function<void(uint64_t time)> processFrame)
180 : RawSink{name, processFrame} {}
181
182inline uint64_t RawCvSink::GrabFrame(cv::Mat& image, double timeout) {
183 cv::Mat tmpnam;
184 auto retVal = GrabFrameDirect(tmpnam);
185 if (retVal <= 0) {
186 return retVal;
187 }
188 tmpnam.copyTo(image);
189 return retVal;
190}
191
192inline uint64_t RawCvSink::GrabFrameNoTimeout(cv::Mat& image) {
193 cv::Mat tmpnam;
194 auto retVal = GrabFrameNoTimeoutDirect(tmpnam);
195 if (retVal <= 0) {
196 return retVal;
197 }
198 tmpnam.copyTo(image);
199 return retVal;
200}
201
202inline uint64_t RawCvSink::GrabFrameDirect(cv::Mat& image, double timeout) {
203 rawFrame.height = 0;
204 rawFrame.width = 0;
206 m_status = RawSink::GrabFrame(rawFrame, timeout);
207 if (m_status <= 0) {
208 return m_status;
209 }
210 image = cv::Mat{rawFrame.height, rawFrame.width, CV_8UC3, rawFrame.data};
211 return m_status;
212}
213
214inline uint64_t RawCvSink::GrabFrameNoTimeoutDirect(cv::Mat& image) {
215 rawFrame.height = 0;
216 rawFrame.width = 0;
219 if (m_status <= 0) {
220 return m_status;
221 }
222 image = cv::Mat{rawFrame.height, rawFrame.width, CV_8UC3, rawFrame.data};
223 return m_status;
224}
225
226} // namespace cs
227
228#endif // CSCORE_CSCORE_RAW_CV_H_
@ WPI_PIXFMT_GRAY
Definition: RawFrame.h:55
@ WPI_PIXFMT_BGR
Definition: RawFrame.h:54
A sink for user code to accept raw video frames as OpenCV images.
Definition: cscore_raw_cv.h:78
uint64_t GrabFrameNoTimeout(cv::Mat &image)
Wait for the next frame and get the image.
Definition: cscore_raw_cv.h:192
uint64_t GrabFrameNoTimeoutDirect(cv::Mat &image)
Wait for the next frame and get the image.
Definition: cscore_raw_cv.h:214
RawCvSink()=default
uint64_t GrabFrameDirect(cv::Mat &image, double timeout=0.225)
Wait for the next frame and get the image.
Definition: cscore_raw_cv.h:202
uint64_t GrabFrame(cv::Mat &image, double timeout=0.225)
Wait for the next frame and get the image.
Definition: cscore_raw_cv.h:182
A source for using the raw frame API to provide opencv images.
Definition: cscore_raw_cv.h:29
void PutFrame(cv::Mat &image)
Put an OpenCV image and notify sinks.
Definition: cscore_raw_cv.h:165
RawCvSource()=default
A sink for user code to accept video frames as raw bytes.
Definition: cscore_raw.h:114
A source for user code to provide video frames as raw bytes.
Definition: cscore_raw.h:76
CS_Status m_status
Definition: cscore_oo.h:1002
CS_Source m_handle
Video source handle.
Definition: cscore_oo.h:473
CS_Status m_status
Definition: cscore_oo.h:470
basic_string_view< char > string_view
Definition: core.h:501
uint64_t GrabFrame(wpi::RawFrame &image, double timeout=0.225) const
Wait for the next frame and get the image.
Definition: cscore_raw.h:193
void PutSourceFrame(CS_Source source, const WPI_RawFrame &image, CS_Status *status)
uint64_t GrabFrameNoTimeout(wpi::RawFrame &image) const
Wait for the next frame and get the image.
Definition: cscore_raw.h:198
CameraServer (cscore) namespace.
Definition: cscore_oo.inc:16
fps
Definition: velocity.h:46
int pixelFormat
Definition: RawFrame.h:40
uint8_t * data
Definition: RawFrame.h:34
int height
Definition: RawFrame.h:42
int width
Definition: RawFrame.h:41
Video mode.
Definition: cscore_cpp.h:62
PixelFormat
Definition: cscore_cpp.h:63
Definition: RawFrame.h:74
auto format(wformat_string< T... > fmt, T &&... args) -> std::wstring
Definition: xchar.h:108