WPILibC++ 2023.4.3
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]] uint64_t GrabFrame(cv::Mat& image, double timeout = 0.225);
115
116 /**
117 * Wait for the next frame and get the image. May block forever.
118 * The provided image will have three 8-bit channels stored in BGR order.
119 *
120 * @return Frame time, or 0 on error (call GetError() to obtain the error
121 * message); the frame time is in the same time base as wpi::Now(),
122 * and is in 1 us increments.
123 */
124 [[nodiscard]] uint64_t GrabFrameNoTimeout(cv::Mat& image);
125
126 /**
127 * Wait for the next frame and get the image.
128 * Times out (returning 0) after timeout seconds.
129 * The provided image will have three 8-bit channels stored in BGR order.
130 *
131 * @return Frame time, or 0 on error (call GetError() to obtain the error
132 * message); the frame time is in the same time base as wpi::Now(),
133 * and is in 1 us increments.
134 */
135 [[nodiscard]] uint64_t GrabFrameDirect(cv::Mat& image,
136 double timeout = 0.225);
137
138 /**
139 * Wait for the next frame and get the image. May block forever.
140 * The provided image will have three 8-bit channels stored in BGR order.
141 *
142 * @return Frame time, or 0 on error (call GetError() to obtain the error
143 * message); the frame time is in the same time base as wpi::Now(),
144 * and is in 1 us increments.
145 */
146 [[nodiscard]] uint64_t GrabFrameNoTimeoutDirect(cv::Mat& image);
147
148 private:
149 RawFrame rawFrame;
150};
151
153 : RawSource{name, mode} {}
154
157 int height, int fps)
158 : RawSource{name, format, width, height, fps} {}
159
160inline void RawCvSource::PutFrame(cv::Mat& image) {
161 m_status = 0;
162 rawFrame.data = reinterpret_cast<char*>(image.data);
163 rawFrame.width = image.cols;
164 rawFrame.height = image.rows;
165 rawFrame.totalData = image.total() * image.channels();
166 rawFrame.pixelFormat = image.channels() == 3 ? CS_PIXFMT_BGR : CS_PIXFMT_GRAY;
167 PutSourceFrame(m_handle, rawFrame, &m_status);
168}
169
170inline RawCvSink::RawCvSink(std::string_view name) : RawSink{name} {}
171
173 std::function<void(uint64_t time)> processFrame)
174 : RawSink{name, processFrame} {}
175
176inline uint64_t RawCvSink::GrabFrame(cv::Mat& image, double timeout) {
177 cv::Mat tmpnam;
178 auto retVal = GrabFrameDirect(tmpnam);
179 if (retVal <= 0) {
180 return retVal;
181 }
182 tmpnam.copyTo(image);
183 return retVal;
184}
185
187 cv::Mat tmpnam;
188 auto retVal = GrabFrameNoTimeoutDirect(tmpnam);
189 if (retVal <= 0) {
190 return retVal;
191 }
192 tmpnam.copyTo(image);
193 return retVal;
194}
195
196inline uint64_t RawCvSink::GrabFrameDirect(cv::Mat& image, double timeout) {
197 rawFrame.height = 0;
198 rawFrame.width = 0;
199 rawFrame.pixelFormat = CS_PixelFormat::CS_PIXFMT_BGR;
200 m_status = RawSink::GrabFrame(rawFrame, timeout);
201 if (m_status <= 0) {
202 return m_status;
203 }
204 image = cv::Mat{rawFrame.height, rawFrame.width, CV_8UC3, rawFrame.data};
205 return m_status;
206}
207
209 rawFrame.height = 0;
210 rawFrame.width = 0;
211 rawFrame.pixelFormat = CS_PixelFormat::CS_PIXFMT_BGR;
212 m_status = RawSink::GrabFrameNoTimeout(rawFrame);
213 if (m_status <= 0) {
214 return m_status;
215 }
216 image = cv::Mat{rawFrame.height, rawFrame.width, CV_8UC3, rawFrame.data};
217 return m_status;
218}
219
220} // namespace cs
221
222#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:186
uint64_t GrabFrameNoTimeoutDirect(cv::Mat &image)
Wait for the next frame and get the image.
Definition: cscore_raw_cv.h:208
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:196
uint64_t GrabFrame(cv::Mat &image, double timeout=0.225)
Wait for the next frame and get the image.
Definition: cscore_raw_cv.h:176
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:160
RawCvSource()=default
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 uint64_t
Definition: Meta.h:58
CameraServer (cscore) namespace.
Definition: cscore_cpp.h:31
fps
Definition: velocity.h:46
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