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