-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdistance.cpp
More file actions
146 lines (129 loc) · 4.78 KB
/
distance.cpp
File metadata and controls
146 lines (129 loc) · 4.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#define MIN_LEGAL_HEIGHT 900
#include <opencv2/opencv.hpp>
#include <iostream>
#include <stdexcept>
#include "distance.h"
#include "detector.h"
#include "manager.h"
using namespace std;
using namespace cv;
void Distance::setFocalLength(const Mat &image)
{
findFocalLength(image);
}
void Distance::setFocalLength(double focalLength)
{
this->focalLength = focalLength;
}
// function that finds the distance of the objects and update them in
// detectionObjects
void Distance::findDistance(std::vector<ObjectInformation> &objectInformations)
{
int knownSize, imageSize;
// Move over all objects
for (ObjectInformation &objectInformation : objectInformations) {
// is person
if (objectInformation.type == 0) {
// distance test based on the position of the legs in the image
if (objectInformation.position.y +
objectInformation.position.height >
MIN_LEGAL_HEIGHT) {
addDistance(0, objectInformation);
return;
}
// Find the size of the object in reality and in the picture
knownSize = PERSON_HEIGHT;
imageSize = objectInformation.position.height;
}
else {
// Find the size of the object in reality and in the picture
knownSize = CAR_WIDTH;
imageSize = objectInformation.position.width;
}
// Calculate the distance in meters
float distance = (focalLength * knownSize / imageSize) / 1000;
addDistance(distance, objectInformation);
}
}
void Distance::findFocalLength(const cv::Mat &image)
{
// Check if the input image is empty
if (image.empty()) {
LogManager::logErrorMessage(ErrorType::IMAGE_ERROR,
"Could not load image");
//throw std::runtime_error("Could not open or find the image");
return;
}
// Convert the input image to grayscale
Mat testImage, grayImage;
image.copyTo(testImage);
cvtColor(testImage, grayImage, COLOR_BGR2GRAY);
grayImage = 255 - grayImage;
// Apply thresholding to the grayscale image
Mat thresh;
threshold(grayImage, thresh, 0, 255, THRESH_BINARY | THRESH_OTSU);
// Find contours in the thresholded image
std::vector<std::vector<Point>> contours;
findContours(thresh, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
// Find the longest contour (assumed to be the black line)
double maxLength = 0.0;
std::vector<cv::Point> maxContour;
for (const auto &contour : contours) {
double length = cv::arcLength(contour, true);
if (length > maxLength) {
maxLength = length;
maxContour = contour;
}
}
// Find the top-left and bottom-right points of the bounding box
cv::Point topLeft = maxContour[0];
cv::Point bottomRight = maxContour[0];
for (const auto &point : maxContour) {
if (point.y < topLeft.y ||
(point.y == topLeft.y && point.x < topLeft.x)) {
topLeft = point;
}
if (point.y > bottomRight.y ||
(point.y == bottomRight.y && point.x > bottomRight.x)) {
bottomRight = point;
}
}
// Calculate the width of the bounding box
double rectWidth = sqrt(pow(bottomRight.y - topLeft.y, 2) +
pow(bottomRight.x - topLeft.x, 2));
// Known parameters
const double actualLineLengthMm = 200.0;
const double distanceToCameraMm = 1000.0;
// Calculate focal length in pixels
this->focalLength = (rectWidth * distanceToCameraMm) / actualLineLengthMm;
}
void Distance::addDistance(float distance, ObjectInformation &obj)
{
if (obj.prevDistances.size() == MAX_PREV_DISTANCES_SIZE)
obj.prevDistances.pop_front();
obj.prevDistances.push_back(distance);
obj.distance = distance;
}
void Distance::drawDistance(shared_ptr<Mat> image,
vector<ObjectInformation> &objects)
{
int fontFace = FONT_HERSHEY_SIMPLEX;
double fontScale = 0.6;
int thickness = 2;
int baseline = 0;
// Calculate text sizes
Size distanceTextSize =
getTextSize("distance", fontFace, fontScale, thickness, &baseline);
for (auto &obj : objects) {
std::stringstream ssDistance;
ssDistance << std::fixed << std::setprecision(2) << obj.distance;
Point distanceTextOrg(obj.position.x + 5,
obj.position.y - distanceTextSize.height - 10);
// Draw outline for distance text
putText(*image, ssDistance.str(), distanceTextOrg, fontFace, fontScale,
Scalar(0, 0, 0), thickness + 3);
// Write the distance text
putText(*image, ssDistance.str(), distanceTextOrg, fontFace, fontScale,
Scalar(255, 255, 255), thickness);
}
}