Autonomy Software C++ 24.5.1
Welcome to the Autonomy Software repository of the Mars Rover Design Team (MRDT) at Missouri University of Science and Technology (Missouri S&T)! API reference contains the source code and other resources for the development of the autonomy software for our Mars rover. The Autonomy Software project aims to compete in the University Rover Challenge (URC) by demonstrating advanced autonomous capabilities and robust navigation algorithms.
Loading...
Searching...
No Matches
RecordingHandler Class Reference

The RecordingHandler class serves to enumerate the cameras available from the CameraHandler and retrieve and write frames from each camera to the filesystem. The recording of each camera can be disabled through constants and the framerate of the recording can be adjusted to save CPU-time and resources. More...

#include <RecordingHandler.h>

Inheritance diagram for RecordingHandler:
Collaboration diagram for RecordingHandler:

Public Types

enum class  RecordingMode { eCameraHandler , eTagDetectionHandler , eObjectDetectionHandler }
 
- Public Types inherited from AutonomyThread< void >
enum  AutonomyThreadState
 

Public Member Functions

 RecordingHandler (RecordingMode eRecordingMode)
 Construct a new Recording Handler:: Recording Handler object.
 
 ~RecordingHandler ()
 Destroy the Recording Handler:: Recording Handler object.
 
void SetRecordingFPS (const int nRecordingFPS)
 Mutator for the desired FPS for all camera recordings.
 
int GetRecordingFPS () const
 Accessor for the desired FPS for all camera recordings.
 
- Public Member Functions inherited from AutonomyThread< void >
 AutonomyThread ()
 Construct a new Autonomy Thread object.
 
virtual ~AutonomyThread ()
 Destroy the Autonomy Thread object. If the parent object or main thread is destroyed or exited while this thread is still running, a race condition will occur. Stopping and joining the thread here insures that the main program can't exit if the user forgot to stop and join the thread.
 
void Start ()
 When this method is called, it starts a new thread that runs the code within the ThreadedContinuousCode method. This is the users main code that will run the important and continuous code for the class.
 
void RequestStop ()
 Signals threads to stop executing user code, terminate. DOES NOT JOIN. This method will not force the thread to exit, if the user code is not written properly and contains WHILE statement or any other long-executing or blocking code, then the thread will not exit until the next iteration.
 
void Join ()
 Waits for thread to finish executing and then closes thread. This method will block the calling code until thread is finished.
 
bool Joinable () const
 Check if the code within the thread and all pools created by it are finished executing and the thread is ready to be closed.
 
AutonomyThreadState GetThreadState () const
 Accessor for the Threads State private member.
 
IPSGetIPS ()
 Accessor for the Frame I P S private member.
 

Private Member Functions

void ThreadedContinuousCode () override
 This code will run continuously in a separate thread. New frames from the cameras that have recording enabled are grabbed and the images are written to the filesystem.
 
void PooledLinearCode () override
 This method holds the code that is ran in the thread pool started by the ThreadedLinearCode() method. It currently does nothing and is not needed in the current implementation of the RecordingHandler.
 
void UpdateRecordableCameras ()
 This method is used internally by the class to update the number of cameras that have recording enabled from the camera handler.
 
void RequestAndWriteCameraFrames ()
 This method is used internally by the RecordingHandler to request and write frames to from the cameras stored in the member variable vectors.
 
void UpdateRecordableTagDetectors ()
 This method is used internally by the class to update the number of TagDetectors that have recording enabled from the camera handler.
 
void RequestAndWriteTagDetectorFrames ()
 This method is used internally by the RecordingHandler to request and write frames to from the TagDetectors stored in the member variable vectors.
 

Private Attributes

int m_nTotalVideoFeeds
 
RecordingMode m_eRecordingMode
 
std::vector< ZEDCamera * > m_vZEDCameras
 
std::vector< BasicCamera * > m_vBasicCameras
 
std::vector< TagDetector * > m_vTagDetectors
 
std::vector< cv::VideoWriterm_vCameraWriters
 
std::vector< bool > m_vRecordingToggles
 
std::vector< cv::Matm_vFrames
 
std::vector< cv::cuda::GpuMatm_vGPUFrames
 
std::vector< std::future< bool > > m_vFrameFutures
 

Additional Inherited Members

- Protected Member Functions inherited from AutonomyThread< void >
void RunPool (const unsigned int nNumTasksToQueue, const unsigned int nNumThreads=2, const bool bForceStopCurrentThreads=false)
 When this method is called, it starts/adds tasks to a thread pool that runs nNumTasksToQueue copies of the code within the PooledLinearCode() method using nNumThreads number of threads. This is meant to be used as an internal utility of the child class to further improve parallelization. Default value for nNumThreads is 2.
 
void RunDetachedPool (const unsigned int nNumTasksToQueue, const unsigned int nNumThreads=2, const bool bForceStopCurrentThreads=false)
 When this method is called, it starts a thread pool full of threads that don't return std::futures (like a placeholder for the thread return type). This means the thread will not have a return type and there is no way to determine if the thread has finished other than calling the Join() method. Only use this if you want to 'set and forget'. It will be faster as it doesn't return futures. Runs PooledLinearCode() method code. This is meant to be used as an internal utility of the child class to further improve parallelization.
 
void ParallelizeLoop (const int nNumThreads, const N tTotalIterations, F &&tLoopFunction)
 Given a ref-qualified looping function and an arbitrary number of iterations, this method will divide up the loop and run each section in a thread pool. This function must not return anything. This method will block until the loop has completed.
 
void ClearPoolQueue ()
 Clears any tasks waiting to be ran in the queue, tasks currently running will remain running.
 
void JoinPool ()
 Waits for pool to finish executing tasks. This method will block the calling code until thread is finished.
 
bool PoolJoinable () const
 Check if the internal pool threads are done executing code and the queue is empty.
 
void SetMainThreadIPSLimit (int nMaxIterationsPerSecond=0)
 Mutator for the Main Thread Max I P S private member.
 
int GetPoolNumOfThreads ()
 Accessor for the Pool Num Of Threads private member.
 
int GetPoolQueueLength ()
 Accessor for the Pool Queue Size private member.
 
std::vector< void > GetPoolResults ()
 Accessor for the Pool Results private member. The action of getting results will destroy and remove them from this object. This method blocks if the thread is not finished, so no need to call JoinPool() before getting results.
 
int GetMainThreadMaxIPS () const
 Accessor for the Main Thread Max I P S private member.
 
- Protected Attributes inherited from AutonomyThread< void >
IPS m_IPS
 

Detailed Description

The RecordingHandler class serves to enumerate the cameras available from the CameraHandler and retrieve and write frames from each camera to the filesystem. The recording of each camera can be disabled through constants and the framerate of the recording can be adjusted to save CPU-time and resources.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-12-26

Member Enumeration Documentation

◆ RecordingMode

enum class RecordingHandler::RecordingMode
strong
43 {
44 eCameraHandler, // Record video feeds from the CameraHandler.
45 eTagDetectionHandler, // Record video feeds from the TagDetectionHandler.
46 eObjectDetectionHandler // Record video feeds from the ObjectDetectionHandler.
47 };

Constructor & Destructor Documentation

◆ RecordingHandler()

RecordingHandler::RecordingHandler ( RecordingMode  eRecordingMode)

Construct a new Recording Handler:: Recording Handler object.

Parameters
eRecordingMode-
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-01-05
30{
31 // Initialize member variables.
32 m_eRecordingMode = eRecordingMode;
33 // Set max FPS of the ThreadedContinuousCode method.
34 this->SetMainThreadIPSLimit(constants::RECORDER_FPS);
35
36 // Resize vectors to match number of video feeds.
37 switch (eRecordingMode)
38 {
39 // RecordingHandler was initialized to record feeds from the CameraHandler.
40 case RecordingMode::eCameraHandler:
41 // Initialize member variables.
42 m_nTotalVideoFeeds = int(CameraHandler::BasicCamName::BASICCAM_END) + int(CameraHandler::ZEDCamName::ZEDCAM_END) - 2;
43 // Resize member vectors to match number of total video feeds to record.
44 m_vZEDCameras.resize(m_nTotalVideoFeeds);
45 m_vBasicCameras.resize(m_nTotalVideoFeeds);
46 m_vCameraWriters.resize(m_nTotalVideoFeeds);
47 m_vRecordingToggles.resize(m_nTotalVideoFeeds);
48 m_vFrames.resize(m_nTotalVideoFeeds);
49 m_vGPUFrames.resize(m_nTotalVideoFeeds);
50 m_vFrameFutures.resize(m_nTotalVideoFeeds);
51 break;
52
53 // RecordingHandler was initialized to record feeds from the TagDetectionHandler.
54 case RecordingMode::eTagDetectionHandler:
55 // Initialize member variables.
56 m_nTotalVideoFeeds = int(TagDetectionHandler::TagDetectors::TAGDETECTOR_END) - 1;
57 // Resize member vectors to match number of total video feeds to record.
58 m_vTagDetectors.resize(m_nTotalVideoFeeds);
59 m_vCameraWriters.resize(m_nTotalVideoFeeds);
60 m_vRecordingToggles.resize(m_nTotalVideoFeeds);
61 m_vFrames.resize(m_nTotalVideoFeeds);
62 m_vFrameFutures.resize(m_nTotalVideoFeeds);
63 break;
64
65 default:
66 // Do nothing.
67 break;
68 }
69}
void SetMainThreadIPSLimit(int nMaxIterationsPerSecond=0)
Mutator for the Main Thread Max I P S private member.
Definition AutonomyThread.hpp:467
Here is the call graph for this function:

◆ ~RecordingHandler()

RecordingHandler::~RecordingHandler ( )

Destroy the Recording Handler:: Recording Handler object.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-12-26
79{
80 // Signal and wait for recording thread to stop.
81 this->RequestStop();
82 this->Join();
83
84 // Loop through and close video writers.
85 for (cv::VideoWriter cvCameraWriter : m_vCameraWriters)
86 {
87 // Release video writer.
88 cvCameraWriter.release();
89 }
90}
void Join()
Waits for thread to finish executing and then closes thread. This method will block the calling code ...
Definition AutonomyThread.hpp:180
void RequestStop()
Signals threads to stop executing user code, terminate. DOES NOT JOIN. This method will not force the...
Definition AutonomyThread.hpp:164
Here is the call graph for this function:

Member Function Documentation

◆ SetRecordingFPS()

void RecordingHandler::SetRecordingFPS ( const int  nRecordingFPS)

Mutator for the desired FPS for all camera recordings.

Parameters
nRecordingFPS- The frames per second to record all cameras at.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-12-26
541{
542 // Set the max iterations per second of the recording handler.
543 this->SetMainThreadIPSLimit(nRecordingFPS);
544}
Here is the call graph for this function:

◆ GetRecordingFPS()

int RecordingHandler::GetRecordingFPS ( ) const

Accessor for the desired FPS for all camera recordings.

Returns
int - The FPS of all camera recordings.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-12-26
555{
556 // Return member variable value.
557 return this->GetMainThreadMaxIPS();
558}
int GetMainThreadMaxIPS() const
Accessor for the Main Thread Max I P S private member.
Definition AutonomyThread.hpp:531
Here is the call graph for this function:

◆ ThreadedContinuousCode()

void RecordingHandler::ThreadedContinuousCode ( )
overrideprivatevirtual

This code will run continuously in a separate thread. New frames from the cameras that have recording enabled are grabbed and the images are written to the filesystem.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-12-26

Implements AutonomyThread< void >.

102{
103 // Check what mode recorder was initialized with.
104 switch (m_eRecordingMode)
105 {
106 // Record video feeds from the CameraHandler.
107 case RecordingMode::eCameraHandler:
108 // Update recordable cameras.
110 // Grab and write frames to VideoWriters.
112 break;
113
114 // Record video feeds from the TagDetectionHandler.
115 case RecordingMode::eTagDetectionHandler:
116 // Update recordable detectors.
118 // Grab and write overlay frames to VideoWriters.
120 break;
121
122 // Shutdown recording handler.
123 default:
124 // Submit logger message.
125 LOG_ERROR(logging::g_qSharedLogger,
126 "The RecordingHandler was initialized with a RecordingMode enum value that doesn't make sense! Thread is shutting down...");
127 // Request main thread stop.
128 this->RequestStop();
129 break;
130 }
131}
void UpdateRecordableTagDetectors()
This method is used internally by the class to update the number of TagDetectors that have recording ...
Definition RecordingHandler.cpp:416
void RequestAndWriteTagDetectorFrames()
This method is used internally by the RecordingHandler to request and write frames to from the TagDet...
Definition RecordingHandler.cpp:490
void UpdateRecordableCameras()
This method is used internally by the class to update the number of cameras that have recording enabl...
Definition RecordingHandler.cpp:152
void RequestAndWriteCameraFrames()
This method is used internally by the RecordingHandler to request and write frames to from the camera...
Definition RecordingHandler.cpp:293
Here is the call graph for this function:

◆ PooledLinearCode()

void RecordingHandler::PooledLinearCode ( )
overrideprivatevirtual

This method holds the code that is ran in the thread pool started by the ThreadedLinearCode() method. It currently does nothing and is not needed in the current implementation of the RecordingHandler.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-12-26

Implements AutonomyThread< void >.

142{}

◆ UpdateRecordableCameras()

void RecordingHandler::UpdateRecordableCameras ( )
private

This method is used internally by the class to update the number of cameras that have recording enabled from the camera handler.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-12-31
153{
154 // Loop through all Basic cameras from the CameraHandler.
155 for (int nCamera = int(CameraHandler::BasicCamName::BASICCAM_START) + 1; nCamera != int(CameraHandler::BasicCamName::BASICCAM_END); ++nCamera)
156 {
157 // Get pointer to camera.
158 BasicCamera* pBasicCamera = globals::g_pCameraHandler->GetBasicCam(static_cast<CameraHandler::BasicCamName>(nCamera));
159 // Store camera pointer in vector so we can get images later.
160 m_vBasicCameras[nCamera - 1] = pBasicCamera;
161
162 // Check if recording for this camera is enabled.
163 if (pBasicCamera->GetEnableRecordingFlag() && pBasicCamera->GetCameraIsOpen())
164 {
165 // Set recording toggle.
166 m_vRecordingToggles[nCamera - 1] = true;
167 // Setup VideoWriter if needed.
168 if (!m_vCameraWriters[nCamera - 1].isOpened())
169 {
170 // Assemble filepath string.
171 std::filesystem::path szFilePath;
172 std::filesystem::path szFilenameWithExtension;
173 szFilePath = constants::LOGGING_OUTPUT_PATH_ABSOLUTE; // Main location for all recordings.
174 szFilePath += logging::g_szProgramStartTimeString + "/cameras"; // Folder for each program run.
175 szFilenameWithExtension = pBasicCamera->GetCameraLocation() + ".mkv"; // Folder for each camera index or name.
176
177 // Check if directory exists.
178 if (!std::filesystem::exists(szFilePath))
179 {
180 // Create directory.
181 if (!std::filesystem::create_directories(szFilePath))
182 {
183 // Submit logger message.
184 LOG_ERROR(logging::g_qSharedLogger,
185 "Unable to create the VideoWriter output directory: {} for camera {}",
186 szFilePath.string(),
187 pBasicCamera->GetCameraLocation());
188 }
189 }
190
191 // Construct the full output path.
192 std::filesystem::path szFullOutputPath = szFilePath / szFilenameWithExtension;
193
194 // Open writer.
195 bool bWriterOpened = m_vCameraWriters[nCamera - 1].open(szFullOutputPath.string(),
196 cv::VideoWriter::fourcc('H', '2', '6', '4'),
197 constants::RECORDER_FPS,
198 pBasicCamera->GetPropResolution());
199
200 // Check writer opened status.
201 if (!bWriterOpened)
202 {
203 // Submit logger message.
204 LOG_WARNING(logging::g_qSharedLogger,
205 "RecordingHandler: Failed to open cv::VideoWriter for basic camera at path/index {}",
206 pBasicCamera->GetCameraLocation());
207 }
208 }
209 }
210 else
211 {
212 // Set recording toggle.
213 m_vRecordingToggles[nCamera - 1] = false;
214 }
215 }
216
217 // Get index offset so we don't overwrite BasicCam pointers and booleans.
218 int nIndexOffset = int(CameraHandler::BasicCamName::BASICCAM_END) - 2;
219 // Loop through all ZED cameras from the CameraHandler.
220 for (int nCamera = int(CameraHandler::ZEDCamName::ZEDCAM_START) + 1; nCamera != int(CameraHandler::ZEDCamName::ZEDCAM_END); ++nCamera)
221 {
222 // Get pointer to camera.
223 ZEDCamera* pZEDCamera = globals::g_pCameraHandler->GetZED(static_cast<CameraHandler::ZEDCamName>(nCamera));
224 // Store camera pointer in vector so we can get images later.
225 m_vZEDCameras[nCamera + nIndexOffset] = pZEDCamera;
226
227 // Check if recording for this camera is enabled.
228 if (pZEDCamera->GetEnableRecordingFlag() && pZEDCamera->GetCameraIsOpen())
229 {
230 // Set recording toggle.
231 m_vRecordingToggles[nCamera + nIndexOffset] = true;
232 // Setup VideoWriter if needed.
233 if (!m_vCameraWriters[nCamera + nIndexOffset].isOpened())
234 {
235 // Assemble filepath string.
236 std::filesystem::path szFilePath;
237 std::filesystem::path szFilenameWithExtension;
238 szFilePath = constants::LOGGING_OUTPUT_PATH_ABSOLUTE; // Main location for all recordings.
239 szFilePath += logging::g_szProgramStartTimeString + "/cameras"; // Folder for each program run.
240 szFilenameWithExtension =
241 pZEDCamera->GetCameraModel() + "_" + std::to_string(pZEDCamera->GetCameraSerial()) + ".mkv"; // Folder for each camera index or name.
242
243 // Check if directory exists.
244 if (!std::filesystem::exists(szFilePath))
245 {
246 // Create directory.
247 if (!std::filesystem::create_directories(szFilePath))
248 {
249 // Submit logger message.
250 LOG_ERROR(logging::g_qSharedLogger,
251 "Unable to create the output directory: {} for camera {} ({})",
252 szFilePath.string(),
253 pZEDCamera->GetCameraModel(),
254 pZEDCamera->GetCameraSerial());
255 }
256 }
257
258 // Construct the full output path.
259 std::filesystem::path szFullOutputPath = szFilePath / szFilenameWithExtension;
260
261 // Open writer.
262 bool bWriterOpened = m_vCameraWriters[nCamera + nIndexOffset].open(szFullOutputPath,
263 cv::VideoWriter::fourcc('H', '2', '6', '4'),
264 constants::RECORDER_FPS,
265 pZEDCamera->GetPropResolution());
266
267 // Check writer opened status.
268 if (!bWriterOpened)
269 {
270 // Submit logger message.
271 LOG_WARNING(logging::g_qSharedLogger,
272 "RecordingHandler: Failed to open cv::VideoWriter for ZED camera with serial {}",
273 pZEDCamera->GetCameraSerial());
274 }
275 }
276 }
277 else
278 {
279 // Set recording toggle.
280 m_vRecordingToggles[nCamera + nIndexOffset] = false;
281 }
282 }
283}
This class serves as a middle inheritor between the Camera interface and the BasicCam class....
Definition BasicCamera.hpp:28
virtual std::string GetCameraLocation() const
Accessor for the cameras path or video index.
Definition BasicCamera.hpp:157
BasicCamera * GetBasicCam(BasicCamName eCameraName)
Accessor for Basic cameras.
Definition CameraHandler.cpp:231
ZEDCamera * GetZED(ZEDCamName eCameraName)
Accessor for ZED cameras.
Definition CameraHandler.cpp:210
cv::Size GetPropResolution() const
Accessor for the Prop Resolution private member.
Definition Camera.hpp:88
bool GetEnableRecordingFlag() const
Accessor for the Enable Recording Flag private member.
Definition Camera.hpp:140
virtual bool GetCameraIsOpen()=0
Accessor for the Camera Is Open private member.
This class serves as a middle inheritor between the Camera interface and the ZEDCam class....
Definition ZEDCamera.hpp:33
virtual unsigned int GetCameraSerial()
Accessor for the Camera Serial private member.
Definition ZEDCamera.hpp:548
virtual std::string GetCameraModel()=0
Accessor for the Camera Model private member.
static int fourcc(char c1, char c2, char c3, char c4)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ RequestAndWriteCameraFrames()

void RecordingHandler::RequestAndWriteCameraFrames ( )
private

This method is used internally by the RecordingHandler to request and write frames to from the cameras stored in the member variable vectors.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-01-01
294{
295 // Loop through total number of cameras and request frames.
296 for (int nIter = 0; nIter < m_nTotalVideoFeeds; ++nIter)
297 {
298 // Check if recording for the camera at this index is enabled.
299 if (m_vRecordingToggles[nIter])
300 {
301 // Check if the camera at the current index is a BasicCam or ZEDCam.
302 if (m_vBasicCameras[nIter] != nullptr)
303 {
304 // Request frame.
305 m_vFrameFutures[nIter] = m_vBasicCameras[nIter]->RequestFrameCopy(m_vFrames[nIter]);
306 }
307 else if (m_vZEDCameras[nIter] != nullptr)
308 {
309 // Check if the camera is setup to use CPU or GPU mats.
310 if (m_vZEDCameras[nIter]->GetUsingGPUMem())
311 {
312 // Grab frames from camera.
313 m_vFrameFutures[nIter] = m_vZEDCameras[nIter]->RequestFrameCopy(m_vGPUFrames[nIter]);
314 }
315 else
316 {
317 // Grab frames from camera.
318 m_vFrameFutures[nIter] = m_vZEDCameras[nIter]->RequestFrameCopy(m_vFrames[nIter]);
319 }
320 }
321 }
322 }
323
324 // Loop through cameras and wait for frame requests to be fulfilled.
325 for (int nIter = 0; nIter < m_nTotalVideoFeeds; ++nIter)
326 {
327 // Check if recording for the camera at this index is enabled.
328 if (m_vRecordingToggles[nIter])
329 {
330 // Check if the camera at the current index is a BasicCam or ZEDCam.
331 if (m_vBasicCameras[nIter] != nullptr)
332 {
333 // Wait for future to be fulfilled.
334 if (m_vFrameFutures[nIter].get() && !m_vFrames[nIter].empty())
335 {
336 // Check if this is a grayscale or color image.
337 if (m_vFrames[nIter].channels() == 1)
338 {
339 // Convert frame from 1 channel grayscale to 3 channel BGR.
340 cv::cvtColor(m_vFrames[nIter], m_vFrames[nIter], cv::COLOR_GRAY2BGR);
341 }
342 // Check if this has an alpha channel.
343 else if (m_vFrames[nIter].channels() == 4)
344 {
345 // Convert from from 4 channels to 3 channels.
346 cv::cvtColor(m_vFrames[nIter], m_vFrames[nIter], cv::COLOR_BGRA2BGR);
347 }
348
349 // Write frame to OpenCV video writer.
350 m_vCameraWriters[nIter].write(m_vFrames[nIter]);
351 }
352 }
353 else if (m_vZEDCameras[nIter] != nullptr)
354 {
355 // Check if the camera is setup to use CPU or GPU mats.
356 if (m_vZEDCameras[nIter]->GetUsingGPUMem())
357 {
358 // Wait for future to be fulfilled.
359 if (m_vFrameFutures[nIter].get() && !m_vGPUFrames[nIter].empty())
360 {
361 // Download GPU mat frame to normal mat.
362 m_vGPUFrames[nIter].download(m_vFrames[nIter]);
363
364 // Check if this is a grayscale or color image.
365 if (m_vFrames[nIter].channels() == 1)
366 {
367 // Convert frame from 1 channel grayscale to 3 channel BGR.
368 cv::cvtColor(m_vFrames[nIter], m_vFrames[nIter], cv::COLOR_GRAY2BGR);
369 }
370 // Check if this has an alpha channel.
371 else if (m_vFrames[nIter].channels() == 4)
372 {
373 // Convert from from 4 channels to 3 channels.
374 cv::cvtColor(m_vFrames[nIter], m_vFrames[nIter], cv::COLOR_BGRA2BGR);
375 }
376
377 // Write frame to OpenCV video writer.
378 m_vCameraWriters[nIter].write(m_vFrames[nIter]);
379 }
380 }
381 else
382 {
383 // Wait for future to be fulfilled.
384 if (m_vFrameFutures[nIter].get() && !m_vFrames[nIter].empty())
385 {
386 // Check if this is a grayscale or color image.
387 if (m_vFrames[nIter].channels() == 1)
388 {
389 // Convert frame from 1 channel grayscale to 3 channel BGR.
390 cv::cvtColor(m_vFrames[nIter], m_vFrames[nIter], cv::COLOR_GRAY2BGR);
391 }
392 // Check if this has an alpha channel.
393 else if (m_vFrames[nIter].channels() == 4)
394 {
395 // Convert from from 4 channels to 3 channels.
396 cv::cvtColor(m_vFrames[nIter], m_vFrames[nIter], cv::COLOR_BGRA2BGR);
397 }
398
399 // Write frame to OpenCV video writer.
400 m_vCameraWriters[nIter].write(m_vFrames[nIter]);
401 }
402 }
403 }
404 }
405 }
406}
__host__ cudaTextureObject_t get() const noexcept
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0)
COLOR_BGRA2BGR
COLOR_GRAY2BGR
Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateRecordableTagDetectors()

void RecordingHandler::UpdateRecordableTagDetectors ( )
private

This method is used internally by the class to update the number of TagDetectors that have recording enabled from the camera handler.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-12-31
417{
418 // Loop through all Basic cameras from the CameraHandler.
419 for (int nDetector = int(TagDetectionHandler::TagDetectors::TAGDETECTOR_START) + 1; nDetector != int(TagDetectionHandler::TagDetectors::TAGDETECTOR_END); ++nDetector)
420 {
421 // Get pointer to camera.
422 TagDetector* pTagDetector = globals::g_pTagDetectionHandler->GetTagDetector(static_cast<TagDetectionHandler::TagDetectors>(nDetector));
423 // Store camera pointer in vector so we can get images later.
424 m_vTagDetectors[nDetector - 1] = pTagDetector;
425
426 // Check if recording for this camera is enabled.
427 if (pTagDetector->GetEnableRecordingFlag() && pTagDetector->GetIsReady())
428 {
429 // Set recording toggle.
430 m_vRecordingToggles[nDetector - 1] = true;
431 // Setup VideoWriter if needed.
432 if (!m_vCameraWriters[nDetector - 1].isOpened())
433 {
434 // Assemble filepath string.
435 std::filesystem::path szFilePath;
436 std::filesystem::path szFilenameWithExtension;
437 szFilePath = constants::LOGGING_OUTPUT_PATH_ABSOLUTE; // Main location for all recordings.
438 szFilePath += logging::g_szProgramStartTimeString + "/tagdetector"; // Folder for each program run.
439 szFilenameWithExtension = pTagDetector->GetCameraName() + ".mkv"; // Folder for each camera index or name.
440
441 // Check if directory exists.
442 if (!std::filesystem::exists(szFilePath))
443 {
444 // Create directory.
445 if (!std::filesystem::create_directories(szFilePath))
446 {
447 // Submit logger message.
448 LOG_ERROR(logging::g_qSharedLogger,
449 "Unable to create the VideoWriter output directory: {} for camera {}",
450 szFilePath.string(),
451 pTagDetector->GetCameraName());
452 }
453 }
454
455 // Construct the full output path.
456 std::filesystem::path szFullOutputPath = szFilePath / szFilenameWithExtension;
457
458 // Open writer.
459 bool bWriterOpened = m_vCameraWriters[nDetector - 1].open(szFullOutputPath.string(),
460 cv::VideoWriter::fourcc('H', '2', '6', '4'),
461 constants::RECORDER_FPS,
462 pTagDetector->GetProcessFrameResolution());
463
464 // Check writer opened status.
465 if (!bWriterOpened)
466 {
467 // Submit logger message.
468 LOG_WARNING(logging::g_qSharedLogger,
469 "RecordingHandler: Failed to open cv::VideoWriter for basic camera at path/index {}",
470 pTagDetector->GetCameraName());
471 }
472 }
473 }
474 else
475 {
476 // Set recording toggle.
477 m_vRecordingToggles[nDetector - 1] = false;
478 }
479 }
480}
TagDetector * GetTagDetector(TagDetectors eDetectorName)
Accessor for TagDetector detectors.
Definition TagDetectionHandler.cpp:197
Run's Aruco detection & camera pose estimation in a multithreading environment. Given a camera,...
Definition TagDetector.h:45
bool GetEnableRecordingFlag() const
Accessor for the Enable Recording Flag private member.
Definition TagDetector.cpp:779
std::string GetCameraName()
Accessor for the camera name or path that this TagDetector is tied to.
Definition TagDetector.cpp:792
cv::Size GetProcessFrameResolution() const
Accessor for the resolution of the process image used for tag detection.
Definition TagDetector.cpp:805
bool GetIsReady()
Accessor for the status of this TagDetector.
Definition TagDetector.cpp:723
Here is the call graph for this function:
Here is the caller graph for this function:

◆ RequestAndWriteTagDetectorFrames()

void RecordingHandler::RequestAndWriteTagDetectorFrames ( )
private

This method is used internally by the RecordingHandler to request and write frames to from the TagDetectors stored in the member variable vectors.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-01-01
491{
492 // Loop through total number of cameras and request frames.
493 for (int nIter = 0; nIter < m_nTotalVideoFeeds; ++nIter)
494 {
495 // Check if recording for the camera at this index is enabled and tag detector at index is not null.
496 if (m_vRecordingToggles[nIter] && m_vTagDetectors[nIter] != nullptr)
497 {
498 // Request frame.
499 m_vFrameFutures[nIter] = m_vTagDetectors[nIter]->RequestDetectionOverlayFrame(m_vFrames[nIter]);
500 }
501 }
502
503 // Loop through cameras and wait for frame requests to be fulfilled.
504 for (int nIter = 0; nIter < m_nTotalVideoFeeds; ++nIter)
505 {
506 // Check if recording for the camera at this index is enabled and tag detector is not null.
507 if (m_vRecordingToggles[nIter] && m_vTagDetectors[nIter] != nullptr)
508 {
509 // Wait for future to be fulfilled.
510 if (m_vFrameFutures[nIter].get() && !m_vFrames[nIter].empty())
511 {
512 // Check if this is a grayscale or color image.
513 if (m_vFrames[nIter].channels() == 1)
514 {
515 // Convert frame from 1 channel grayscale to 3 channel BGR.
516 cv::cvtColor(m_vFrames[nIter], m_vFrames[nIter], cv::COLOR_GRAY2BGR);
517 }
518 // Check if this has an alpha channel.
519 else if (m_vFrames[nIter].channels() == 4)
520 {
521 // Convert from from 4 channels to 3 channels.
522 cv::cvtColor(m_vFrames[nIter], m_vFrames[nIter], cv::COLOR_BGRA2BGR);
523 }
524
525 // Write frame to OpenCV video writer.
526 m_vCameraWriters[nIter].write(m_vFrames[nIter]);
527 }
528 }
529 }
530}
Here is the call graph for this function:
Here is the caller graph for this function:

The documentation for this class was generated from the following files: