Skip to content

Commit da22d84

Browse files
committed
First implementation of the SSD detector
1 parent d4b3dea commit da22d84

10 files changed

Lines changed: 2203 additions & 42 deletions

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR})
4040
Detector/FaceDetector.cpp
4141
Detector/PedestrianDetector.cpp
4242
Detector/pedestrians/c4-pedestrian-detector.cpp
43+
Detector/DNNDetector.cpp
4344

4445
Tracker/Ctracker.cpp
4546
Tracker/track.cpp
@@ -66,6 +67,7 @@ set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR})
6667
Detector/FaceDetector.h
6768
Detector/PedestrianDetector.h
6869
Detector/pedestrians/c4-pedestrian-detector.h
70+
Detector/DNNDetector.h
6971

7072
Tracker/Ctracker.h
7173
Tracker/track.h

Detector/BaseDetector.cpp

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "MotionDetector.h"
33
#include "FaceDetector.h"
44
#include "PedestrianDetector.h"
5+
#include "DNNDetector.h"
56

67
///
78
/// \brief CreateDetector
@@ -41,28 +42,40 @@ BaseDetector* CreateDetector(
4142

4243
case tracking::Face_HAAR:
4344
{
44-
FaceDetector* faceDetector = new FaceDetector(collectPoints, gray);
45-
if (!faceDetector->Init("../data/haarcascade_frontalface_alt2.xml"))
45+
FaceDetector* detector = new FaceDetector(collectPoints, gray);
46+
if (!detector->Init("../data/haarcascade_frontalface_alt2.xml"))
4647
{
47-
delete faceDetector;
48-
faceDetector = nullptr;
48+
delete detector;
49+
detector = nullptr;
4950
}
50-
return faceDetector;
51+
return detector;
5152
}
5253

5354
case tracking::Pedestrian_HOG:
5455
case tracking::Pedestrian_C4:
5556
{
56-
PedestrianDetector* pedestrianDetector = new PedestrianDetector(collectPoints, gray);
57-
if (!pedestrianDetector->Init((detectorType == tracking::Pedestrian_HOG) ? PedestrianDetector::HOG : PedestrianDetector::C4,
58-
"../data/combined.txt.model", "../data/combined.txt.model_"))
57+
PedestrianDetector* detector = new PedestrianDetector(collectPoints, gray);
58+
if (!detector->Init((detectorType == tracking::Pedestrian_HOG) ? PedestrianDetector::HOG : PedestrianDetector::C4,
59+
"../data/combined.txt.model", "../data/combined.txt.model_"))
5960
{
60-
delete pedestrianDetector;
61-
pedestrianDetector = nullptr;
61+
delete detector;
62+
detector = nullptr;
6263
}
63-
return pedestrianDetector;
64+
return detector;
6465
}
6566

67+
case tracking::DNN:
68+
{
69+
DNNDetector* detector = new DNNDetector(collectPoints, gray);
70+
if (!detector->Init("../data/MobileNetSSD_deploy.prototxt", "../data/MobileNetSSD_deploy.caffemodel"))
71+
{
72+
delete detector;
73+
detector = nullptr;
74+
}
75+
return detector;
76+
}
77+
78+
6679
default:
6780
return nullptr;
6881
}

Detector/BaseDetector.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@
99
class BaseDetector
1010
{
1111
public:
12-
BaseDetector(bool collectPoints, cv::UMat& gray)
12+
BaseDetector(bool collectPoints, cv::UMat& frame)
1313
: m_collectPoints(collectPoints)
1414
{
15-
m_minObjectSize.width = std::max(5, gray.cols / 100);
15+
m_minObjectSize.width = std::max(5, frame.cols / 100);
1616
m_minObjectSize.height = m_minObjectSize.width;
1717
}
1818
virtual ~BaseDetector(void)
1919
{
2020
}
2121

22-
virtual void Detect(cv::UMat& gray) = 0;
22+
virtual void Detect(cv::UMat& frame) = 0;
2323

2424
void SetMinObjectSize(cv::Size minObjectSize)
2525
{
@@ -43,7 +43,7 @@ class BaseDetector
4343
{
4444
cv::ellipse(foreground,
4545
cv::RotatedRect((region.m_rect.tl() + region.m_rect.br()) / 2, region.m_rect.size(), 0),
46-
cv::Scalar(255, 255, 255), -1);
46+
cv::Scalar(255, 255, 255), CV_FILLED);
4747
}
4848

4949
cv::Mat normFor;

Detector/DNNDetector.cpp

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#include "DNNDetector.h"
2+
3+
///
4+
/// \brief DNNDetector::DNNDetector
5+
/// \param collectPoints
6+
/// \param gray
7+
///
8+
DNNDetector::DNNDetector(
9+
bool collectPoints,
10+
cv::UMat& colorFrame
11+
)
12+
:
13+
BaseDetector(collectPoints, colorFrame)
14+
{
15+
}
16+
17+
///
18+
/// \brief DNNDetector::~DNNDetector
19+
///
20+
DNNDetector::~DNNDetector(void)
21+
{
22+
}
23+
24+
///
25+
/// \brief DNNDetector::Init
26+
/// \return
27+
///
28+
bool DNNDetector::Init(std::string modelConfiguration, std::string modelBinary)
29+
{
30+
m_net = cv::dnn::readNetFromCaffe(modelConfiguration, modelBinary);
31+
32+
return !m_net.empty();
33+
}
34+
35+
///
36+
/// \brief DNNDetector::Detect
37+
/// \param gray
38+
///
39+
void DNNDetector::Detect(cv::UMat& colorFrame)
40+
{
41+
const int inWidth = 300;
42+
const int inHeight = 300;
43+
const float WHRatio = inWidth / (float)inHeight;
44+
const float inScaleFactor = 0.007843f;
45+
const float meanVal = 127.5;
46+
const float confidenceThreshold = 0.2f;
47+
std::string classNames[] = {"background",
48+
"aeroplane", "bicycle", "bird", "boat",
49+
"bottle", "bus", "car", "cat", "chair",
50+
"cow", "diningtable", "dog", "horse",
51+
"motorbike", "person", "pottedplant",
52+
"sheep", "sofa", "train", "tvmonitor"};
53+
54+
cv::Size cropSize;
55+
if (colorFrame.cols / (float)colorFrame.rows > WHRatio)
56+
{
57+
cropSize = cv::Size(cvRound(colorFrame.rows * WHRatio), colorFrame.rows);
58+
}
59+
else
60+
{
61+
cropSize = cv::Size(colorFrame.cols, cvRound(colorFrame.cols / WHRatio));
62+
}
63+
64+
cv::Rect crop(cv::Point((colorFrame.cols - cropSize.width) / 2, (colorFrame.rows - cropSize.height) / 2), cropSize);
65+
66+
cv::Mat inputBlob = cv::dnn::blobFromImage(colorFrame.getMat(cv::ACCESS_READ), inScaleFactor, cv::Size(inWidth, inHeight), meanVal, false); //Convert Mat to batch of images
67+
68+
m_net.setInput(inputBlob, "data"); //set the network input
69+
70+
cv::Mat detection = m_net.forward("detection_out"); //compute output
71+
72+
std::vector<double> layersTimings;
73+
double freq = cv::getTickFrequency() / 1000;
74+
double time = m_net.getPerfProfile(layersTimings) / freq;
75+
76+
cv::Mat detectionMat(detection.size[2], detection.size[3], CV_32F, detection.ptr<float>());
77+
78+
//cv::Mat frame = colorFrame(crop);
79+
80+
//ss << "FPS: " << 1000/time << " ; time: " << time << " ms";
81+
//putText(frame, ss.str(), Point(20,20), 0, 0.5, Scalar(0,0,255));
82+
//std::cout << "Inference time, ms: " << time << endl;
83+
84+
m_regions.clear();
85+
86+
for (int i = 0; i < detectionMat.rows; ++i)
87+
{
88+
float confidence = detectionMat.at<float>(i, 2);
89+
90+
if (confidence > confidenceThreshold)
91+
{
92+
size_t objectClass = (size_t)(detectionMat.at<float>(i, 1));
93+
94+
int xLeftBottom = cvRound(detectionMat.at<float>(i, 3) * colorFrame.cols);
95+
int yLeftBottom = cvRound(detectionMat.at<float>(i, 4) * colorFrame.rows);
96+
int xRightTop = cvRound(detectionMat.at<float>(i, 5) * colorFrame.cols);
97+
int yRightTop = cvRound(detectionMat.at<float>(i, 6) * colorFrame.rows);
98+
99+
cv::Rect object((int)xLeftBottom, (int)yLeftBottom, (int)(xRightTop - xLeftBottom), (int)(yRightTop - yLeftBottom));
100+
101+
m_regions.push_back(object);
102+
103+
//cv::rectangle(frame, object, Scalar(0, 255, 0));
104+
std::string label = classNames[objectClass] + ": " + std::to_string(confidence);
105+
int baseLine = 0;
106+
cv::Size labelSize = cv::getTextSize(label, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
107+
//cv::rectangle(frame, cv::Rect(cv::Point(xLeftBottom, yLeftBottom - labelSize.height), cv::Size(labelSize.width, labelSize.height + baseLine)), cv::Scalar(255, 255, 255), CV_FILLED);
108+
//cv::putText(frame, label, Point(xLeftBottom, yLeftBottom), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0,0,0));
109+
}
110+
}
111+
}

Detector/DNNDetector.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma once
2+
3+
#include "BaseDetector.h"
4+
5+
#include <opencv2/dnn.hpp>
6+
#include <opencv2/dnn/shape_utils.hpp>
7+
8+
///
9+
/// \brief The DNNDetector class
10+
///
11+
class DNNDetector : public BaseDetector
12+
{
13+
public:
14+
DNNDetector(bool collectPoints, cv::UMat& colorFrame);
15+
~DNNDetector(void);
16+
17+
bool Init(std::string modelConfiguration = "../data/MobileNetSSD_deploy.prototxt", std::string modelBinary = "../data/MobileNetSSD_deploy.caffemodel");
18+
19+
void Detect(cv::UMat& colorFrame);
20+
21+
private:
22+
cv::dnn::Net m_net;
23+
};

0 commit comments

Comments
 (0)