Skip to content

Commit b6873ed

Browse files
Img_processing: implement sun detector
1 parent 8efc50f commit b6873ed

File tree

7 files changed

+134
-2
lines changed

7 files changed

+134
-2
lines changed

img_processing/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ add_library(CommunicationLib STATIC ../communication/src/communication.cpp ../co
3232

3333
configure_file( ${CMAKE_BINARY_DIR}/config.json COPYONLY)
3434
# create test executable
35-
add_executable(runTests tests/main.cpp tests/test_serialize.cpp tests/test_detector.cpp tests/test_dynamic_tracker.cpp tests/test_distance.cpp tests/test_manager.cpp tests/test_velocity.cpp tests/test_lane_detector.cpp)
35+
add_executable(runTests tests/main.cpp tests/test_serialize.cpp tests/test_detector.cpp tests/test_dynamic_tracker.cpp tests/test_distance.cpp tests/test_manager.cpp tests/test_velocity.cpp tests/test_sun_detector.cpp tests/test_lane_detector.cpp)
3636
target_link_libraries(runTests ImageProcessingLib ${OpenCV_LIBS} ${GTEST_LIBRARIES} pthread CommunicationLib)
3737

3838
#adding tests

img_processing/include/manager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "log_manager.h"
1111
#include "velocity.h"
1212
#include "communication.h"
13+
#include "sun_detector.h"
1314

1415
class Manager {
1516
public:
@@ -32,6 +33,7 @@ class Manager {
3233
Velocity velocity;
3334
DynamicTracker dynamicTracker;
3435
Alerter alerter;
36+
SunDetector sunDetector;
3537
LaneDetector laneDetector;
3638
int longTime;
3739
int iterationCnt;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#ifndef __SUN_DETECTOR_H__
2+
#define __SUN_DETECTOR_H__
3+
4+
#include <opencv2/opencv.hpp>
5+
6+
class SunDetector {
7+
public:
8+
void detectSun(const std::shared_ptr<cv::Mat> &frame);
9+
void drowSun(std::shared_ptr<cv::Mat> &frame);
10+
11+
private:
12+
cv::Point2f center;
13+
float radius;
14+
bool isSun;
15+
};
16+
17+
#endif // __SUN_DETECTOR_H__

img_processing/src/manager.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ int Manager::processing(const Mat &newFrame, bool isTravel)
166166
// add distance to detection objects
167167
distance.findDistance(this->currentOutput);
168168
velocity.returnVelocities(this->currentOutput);
169-
169+
sunDetector.detectSun(this->currentFrame);
170170
// send allerts to main control
171171
vector<vector<uint8_t>> alerts = alerter.sendAlerts(this->currentOutput);
172172
sendAlerts(alerts);
@@ -258,6 +258,8 @@ void Manager::drawOutput()
258258
Point(legendX + 10, legendY + 55), Scalar(255, 0, 0), FILLED);
259259
putText(*currentFrame, "velocity", Point(legendX + 15, legendY + 50),
260260
FONT_HERSHEY_SIMPLEX, 0.6, Scalar(255, 255, 255), 1);
261+
262+
sunDetector.drowSun(this->currentFrame);
261263

262264
#ifdef LANE_DETECT
263265
laneDetector.drawLanesOnImage(currentFrame);
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#include "sun_detector.h"
2+
3+
using namespace std;
4+
using namespace cv;
5+
6+
void SunDetector::detectSun(const std::shared_ptr<cv::Mat> &frame)
7+
{
8+
isSun = false;
9+
// Convert the frame to grayscale for easier processing
10+
Mat image;
11+
cvtColor(*frame, image, COLOR_BGR2GRAY);
12+
// Calculate the histogram of the grayscale image
13+
Mat histogram;
14+
int histSize = 256;
15+
float range[] = {0, 256};
16+
const float *histRange = {range};
17+
calcHist(&image, 1, 0, Mat(), histogram, 1, &histSize, &histRange);
18+
// Compute the cumulative distribution function (CDF) from the histogram
19+
Mat cdf;
20+
histogram.copyTo(cdf);
21+
for (int i = 1; i < histSize; i++) {
22+
cdf.at<float>(i) += cdf.at<float>(i - 1);
23+
}
24+
cdf /= cdf.at<float>(histSize - 1); // Normalize the CDF
25+
// Determine a threshold based on the 95th percentile of pixel intensities
26+
double minVal, maxVal;
27+
minMaxLoc(image, &minVal, &maxVal); // Find min and max pixel intensities
28+
Mat percentileThreshold;
29+
threshold(image, percentileThreshold, maxVal * 0.95, 255, THRESH_BINARY);
30+
int thresholdArea = cv::countNonZero(percentileThreshold);
31+
// Detect contours in the thresholded image (for bright regions)
32+
std::vector<std::vector<Point>> contours;
33+
findContours(percentileThreshold, contours, RETR_EXTERNAL,
34+
CHAIN_APPROX_SIMPLE);
35+
// Find the largest contour in terms of area (which could be the sun)
36+
double maxArea = 0;
37+
int maxAreaIdx = -1;
38+
for (size_t i = 0; i < contours.size(); i++) {
39+
double area = contourArea(contours[i]);
40+
if (area > maxArea) {
41+
maxArea = area;
42+
maxAreaIdx = i;
43+
}
44+
}
45+
// If a valid contour was found, proceed with further analysis
46+
if (maxAreaIdx != -1) {
47+
// Draw a circle around the largest contour to visualize it
48+
minEnclosingCircle(contours[maxAreaIdx], center, radius);
49+
// Calculate image gradients (Sobel) to analyze the smoothness of the region
50+
Mat gradX, gradY;
51+
Sobel(image, gradX, CV_32F, 1, 0); // Gradient in X direction
52+
Sobel(image, gradY, CV_32F, 0, 1); // Gradient in Y direction
53+
// Calculate the gradient magnitude (intensity of edges)
54+
Mat gradientMag;
55+
magnitude(gradX, gradY, gradientMag); // sqrt(gradX^2 + gradY^2)
56+
// Compute the average gradient magnitude in the bright region (contour
57+
// area)
58+
Scalar meanGradient = mean(gradientMag, percentileThreshold);
59+
// If the gradient magnitude is low, the area is likely smooth, like the sun
60+
if (meanGradient[0] < 7 &&
61+
thresholdArea < 35000) // Adjust this threshold as needed
62+
{
63+
isSun = true;
64+
}
65+
}
66+
}
67+
68+
void SunDetector::drowSun(std::shared_ptr<cv::Mat> &frame)
69+
{
70+
if (isSun) {
71+
// Draw a green circle around the detected sun region
72+
circle(*frame, center, static_cast<int>(radius), Scalar(0, 255, 0), 2);
73+
}
74+
}
20 MB
Binary file not shown.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include <gtest/gtest.h>
2+
#include <opencv2/opencv.hpp>
3+
#include "sun_detector.h"
4+
5+
using namespace std;
6+
using namespace cv;
7+
8+
TEST(SunDetectorTest, detectSun)
9+
{
10+
VideoCapture capture("../tests/images/sun_in_street.mov");
11+
12+
if (!capture.isOpened()) {
13+
// LogManager::logErrorMessage(ErrorType::VIDEO_ERROR, "video not found");
14+
// throw runtime_error("video not found");
15+
cout << "couldn't open video" << endl;
16+
return;
17+
}
18+
Mat img;
19+
SunDetector sd;
20+
while (1) {
21+
capture >> img;
22+
23+
if (img.empty()) {
24+
// LogManager::logInfoMessage(InfoType::MEDIA_FINISH);
25+
cout << "media finish" << endl;
26+
break;
27+
}
28+
shared_ptr<Mat> frame = make_shared<Mat>(img);
29+
sd.detectSun(frame);
30+
sd.drowSun(frame);
31+
imshow("sun", *frame);
32+
int key = waitKey(1);
33+
if (key == 27) {
34+
break;
35+
}
36+
}
37+
}

0 commit comments

Comments
 (0)