Lane and Object Detection
Using OpenCV and YOLOv7
Loading...
Searching...
No Matches
FrameBuilder.cpp
1#include <algorithm>
2#include <chrono>
3#include <cmath>
4#include <cstdint>
5#include <format>
6
7#include <opencv2/core.hpp>
8#include <opencv2/core/mat.hpp>
9#include <opencv2/core/types.hpp>
10#include <opencv2/imgproc.hpp>
11
12#include "helpers/Globals.hpp"
13#include "helpers/Information.hpp"
14
15#include "helpers/FrameBuilder.hpp"
16
18{
19
20 void FrameBuilder::UpdateFrame(cv::Mat& p_frame,
21 const ObjectDetectionInformation& p_objectDetectionInformation,
22 const LaneDetectionInformation& p_laneDetectionInformation,
23 const PerformanceInformation& p_performanceInformation,
24 const VideoManagerInformation& p_videoManagerInformation)
25 {
26 AddObjectDetectorInformation(p_frame, p_objectDetectionInformation, p_videoManagerInformation.m_debugMode);
27
28 AddLaneDetectorInformation(p_frame, p_laneDetectionInformation, p_videoManagerInformation.m_debugMode);
29
30 AddPerformanceInformation(p_frame, p_performanceInformation, p_videoManagerInformation.m_debugMode);
31
32 AddVideoManagerInformation(p_frame, p_videoManagerInformation);
33 }
34
35 void FrameBuilder::AddObjectDetectorInformation(cv::Mat& p_frame, const ObjectDetectionInformation& p_objectDetectionInformation, const bool& p_debugMode)
36 {
37 if (!p_debugMode)
38 {
39 return;
40 }
41
42 for (const ObjectDetectionInformation::DetectedObjectInformation& objectInformation : p_objectDetectionInformation.m_objectInformation)
43 {
44 // Draw the bounding box
45 cv::rectangle(p_frame,
46 objectInformation.m_boundingBox,
47 objectInformation.m_boundingBoxColour,
49 cv::LINE_AA);
50
51 // Draw the bounding box header
52 cv::rectangle(p_frame,
53 cv::Rect(objectInformation.m_boundingBox.x,
55 std::max(objectInformation.m_boundingBox.width, static_cast<int32_t>(objectInformation.m_objectName.size() * Globals::G_OBJECT_DETECTOR_BOUNDING_BOX_CHARACTER_WIDTH)),
57 objectInformation.m_boundingBoxColour,
58 cv::FILLED,
59 cv::LINE_AA);
60
61 // Draw the bounding box header text
62 cv::putText(p_frame,
63 objectInformation.m_objectName,
64 cv::Point(objectInformation.m_boundingBox.x, objectInformation.m_boundingBox.y - Globals::G_OBJECT_DETECTOR_BOUNDING_BOX_TEXT_HEIGHT_OFFSET),
69 cv::LINE_AA);
70 }
71 }
72
73 void FrameBuilder::AddLaneDetectorInformation(cv::Mat& p_frame, const LaneDetectionInformation& p_laneDetectionInformation, const bool& p_debugMode)
74 {
75 // Add driving state
77
78 // Add turning state
80
81 if (!p_debugMode)
82 {
83 return;
84 }
85
86 // Draw the green translucent lane overlay to signify the area of the road which is considered the 'current lane'
87 cv::Mat blankFrame = cv::Mat::zeros(Globals::G_VIDEO_INPUT_HEIGHT, Globals::G_VIDEO_INPUT_WIDTH, p_frame.type());
88 cv::fillConvexPoly(blankFrame, p_laneDetectionInformation.m_laneOverlayCorners, Globals::G_LANE_OVERLAY_COLOUR, cv::LINE_AA);
89 cv::add(p_frame, blankFrame, p_frame);
90 }
91
92 void FrameBuilder::AddPerformanceInformation(cv::Mat& p_frame, const PerformanceInformation& p_performanceInformation, const bool& p_debugMode)
93 {
94 if (!p_debugMode)
95 {
96 return;
97 }
98
99 // Round frame per second values to two decimal places
100 const std::string CURRENT_FPS = std::format("{} Current FPS ({} Average FPS)",
101 std::round(p_performanceInformation.m_currentFramesPerSecond * 100.0) / 100.0,
102 std::round(p_performanceInformation.m_averageFramesPerSecond));
103
105 }
106
107 void FrameBuilder::AddVideoManagerInformation(cv::Mat& p_frame, const VideoManagerInformation& p_videoManagerInformation)
108 {
109 // UTC timestamp E.g. Thursday 01 January 1970 10:11:03
110 const std::string TIMESTAMP = std::format("{:%A %d %B %Y} ", std::chrono::system_clock::now()) + std::format("{:%H:%M:%S}", std::chrono::system_clock::now()).substr(0, 8);
112
114
115 if (p_videoManagerInformation.m_saveOutput)
116 {
119
120 // Add flashing recording dot and time spent recording
121 const uint32_t SECONDS_SINCE_EPOCH = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
122
123 if (static_cast<bool>(SECONDS_SINCE_EPOCH % 2))
124 {
126 }
127 }
128
129 else
130 {
132 }
133 }
134
135 void FrameBuilder::AddBackgroundRectAndCentredText(cv::Mat& p_frame, const cv::Rect& p_backgroundRect, const std::string& p_text, const double& p_fontScale)
136 {
137 cv::rectangle(p_frame, p_backgroundRect, Globals::G_COLOUR_BLACK, cv::FILLED, cv::LINE_AA);
138
139 double currentFontScale = p_fontScale;
140
141 cv::Size textSize = cv::getTextSize(p_text, Globals::G_FONT_DEFAULT_FACE, currentFontScale, Globals::G_FONT_DEFAULT_THICKNESS, nullptr);
142
143 while ((((textSize.width + Globals::G_FONT_DEFAULT_HORIZONTAL_PADDING) > p_backgroundRect.width) ||
144 ((textSize.height + Globals::G_FONT_DEFAULT_VERTICAL_PADDING) > p_backgroundRect.height)) &&
145 (currentFontScale > Globals::G_FONT_DEFAULT_DECREMENT))
146 {
147 currentFontScale -= Globals::G_FONT_DEFAULT_DECREMENT;
148 textSize = cv::getTextSize(p_text, Globals::G_FONT_DEFAULT_FACE, currentFontScale, Globals::G_FONT_DEFAULT_THICKNESS, nullptr);
149 }
150
151 const int32_t X_PAD = std::ceil((p_backgroundRect.width - textSize.width) / Globals::G_DIVIDE_BY_TWO);
152 const int32_t Y_PAD = std::ceil((p_backgroundRect.height - textSize.height) / Globals::G_DIVIDE_BY_TWO);
153
154 cv::putText(p_frame,
155 p_text,
156 {p_backgroundRect.x + X_PAD, p_backgroundRect.y + textSize.height + Y_PAD},
158 currentFontScale,
161 cv::LINE_AA);
162 }
163}
static void AddPerformanceInformation(cv::Mat &p_frame, const PerformanceInformation &p_performanceInformation, const bool &p_debugMode)
Adds performance information to p_frame.
static void AddLaneDetectorInformation(cv::Mat &p_frame, const LaneDetectionInformation &p_laneDetectionInformation, const bool &p_debugMode)
Adds lane detection information to p_frame.
static void AddBackgroundRectAndCentredText(cv::Mat &p_frame, const cv::Rect &p_backgroundRect, const std::string &p_text, const double &p_fontScale=Globals::G_FONT_DEFAULT_SCALE)
Adds p_backgroundRect to p_frame and centers p_text within p_backgroundRect.
static void AddVideoManagerInformation(cv::Mat &p_frame, const VideoManagerInformation &p_videoManagerInformation)
Adds video manager information to p_frame.
static void UpdateFrame(cv::Mat &p_frame, const ObjectDetectionInformation &p_objectDetectionInformation, const LaneDetectionInformation &p_laneDetectionInformation, const PerformanceInformation &p_performanceInformation, const VideoManagerInformation &p_videoManagerInformation)
Updates p_frame with object detection, lane detection, performance and video manager information.
static void AddObjectDetectorInformation(cv::Mat &p_frame, const ObjectDetectionInformation &p_objectDetectionInformation, const bool &p_debugMode)
Adds object detection information to p_frame.
static const uint32_t G_UI_RADIUS_RECORDING_DOT
Recording status UI locations.
Definition Globals.hpp:243
static const double G_UI_H1_FONT_SCALE
Font scales for different heading sizes.
Definition Globals.hpp:198
static const int32_t G_OBJECT_DETECTOR_BOUNDING_BOX_HEADER_HEIGHT
Object detection bounding box properties.
Definition Globals.hpp:493
static const uint32_t G_FONT_DEFAULT_THICKNESS
Font settings.
Definition Globals.hpp:134
static const cv::Scalar G_COLOUR_BLACK
OpenCV Colours (in BGR format).
Definition Globals.hpp:145
static const cv::Rect G_UI_RECT_DRIVING_STATE_SUBTITLE
Driving state sub-title UI location (width is the entire screen for centering).
Definition Globals.hpp:229
static const cv::Rect G_UI_RECT_RECORDING_ELAPSED_TIME
Recording status UI locations.
Definition Globals.hpp:241
static const uint32_t G_VIDEO_INPUT_HEIGHT
Input video dimensions.
Definition Globals.hpp:103
static const uint32_t G_VIDEO_INPUT_WIDTH
Input video dimensions.
Definition Globals.hpp:104
static const cv::Rect G_UI_RECT_FPS
Performance-related information UI location.
Definition Globals.hpp:219
static const double G_DIVIDE_BY_TWO
Divide by two.
Definition Globals.hpp:176
static const cv::Rect G_UI_RECT_DRIVING_STATE
Driving state UI location (width is the entire screen for centering).
Definition Globals.hpp:224
static const cv::Scalar G_COLOUR_WHITE
OpenCV Colours (in BGR format).
Definition Globals.hpp:147
static const double G_UI_H2_FONT_SCALE
Font scales for different heading sizes.
Definition Globals.hpp:199
static const double G_OBJECT_DETECTOR_BOUNDING_BOX_FONT_SCALE
Object detection bounding box properties.
Definition Globals.hpp:497
static const int32_t G_FONT_DEFAULT_VERTICAL_PADDING
Font settings.
Definition Globals.hpp:136
static const int32_t G_FONT_DEFAULT_HORIZONTAL_PADDING
Font settings.
Definition Globals.hpp:135
static const double G_FONT_DEFAULT_DECREMENT
Font settings.
Definition Globals.hpp:137
static const cv::Point G_UI_POINT_RECORDING_DOT
Recording status UI locations.
Definition Globals.hpp:242
static const cv::Rect G_UI_RECT_NOT_RECORDING_STATUS
Recording status UI locations.
Definition Globals.hpp:244
static const cv::Scalar G_COLOUR_RED
OpenCV Colours (in BGR format).
Definition Globals.hpp:148
static const uint32_t G_FONT_DEFAULT_FACE
Font settings.
Definition Globals.hpp:133
static const int32_t G_OBJECT_DETECTOR_BOUNDING_BOX_TEXT_HEIGHT_OFFSET
Object detection bounding box properties.
Definition Globals.hpp:496
static const cv::Scalar G_LANE_OVERLAY_COLOUR
Translucent colour of the overlay for the current lane.
Definition Globals.hpp:255
static const cv::Rect G_UI_RECT_RECORDING_STATUS
Recording status UI locations.
Definition Globals.hpp:240
static const cv::Rect G_UI_RECT_TIMESTAMP
Timestamp UI location.
Definition Globals.hpp:214
static const int32_t G_OBJECT_DETECTOR_BOUNDING_BOX_BORDER_THICKNESS
Object detection bounding box properties.
Definition Globals.hpp:494
static const int32_t G_OBJECT_DETECTOR_BOUNDING_BOX_CHARACTER_WIDTH
Object detection bounding box properties.
Definition Globals.hpp:495
static const cv::Rect G_UI_RECT_DEBUG_MODE_STATUS
Debug mode status UI location.
Definition Globals.hpp:234
Contains all Lane-and-Object-Detection objects.
The information needed by FrameBuilder to update frame with lane detection information.
std::string m_drivingStateTitle
The current driving state title.
std::vector< cv::Point > m_laneOverlayCorners
The co-ordinate points that outline the current lane.
std::string m_drivingStateSubTitle
Either the lane line information or turning state depending upon the current driving state.
The information needed by FrameBuilder to update frame with object detection information.
std::vector< DetectedObjectInformation > m_objectInformation
The list of detected objects for the current frame.
The information needed by FrameBuilder to update frame with performance information.
double m_averageFramesPerSecond
The average number of frames per second.
double m_currentFramesPerSecond
The current number of frames per second.
The information needed by FrameBuilder to update frame with video manager information.
std::string m_saveOutputElapsedTime
The time that has elapsed since starting to save the output video stream locally.
std::string m_saveOutputText
Text to display whether or not the program is recording the output.
bool m_saveOutput
Whether the output video stream should be saved locally.
std::string m_debugModeText
Text to display whether or not the program is in debug mode.