Skip to content

Commit 4d8eca4

Browse files
author
Sergey Nuzhny
committed
New version of background substraction algorithm
1 parent ff34ca9 commit 4d8eca4

10 files changed

Lines changed: 295 additions & 386 deletions

File tree

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR})
2828
Detector/Detector.cpp
2929
HungarianAlg/HungarianAlg.cpp
3030
vibe_src/BackgroundSubtract.cpp
31-
vibe_src/VIBE.cpp
31+
vibe_src/vibe.cpp
3232
Tracker/Ctracker.cpp
3333
Tracker/Kalman.cpp)
3434

3535
set(folder_header Detector/Detector.h
3636
HungarianAlg/HungarianAlg.h
3737
vibe_src/BackgroundSubtract.h
38-
vibe_src/VIBE.h
38+
vibe_src/vibe.hpp
3939
Tracker/Ctracker.h
4040
Tracker/Kalman.h
4141
Tracker/defines.h)

Detector/Detector.cpp

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,55 +2,60 @@
22

33
CDetector::CDetector(cv::Mat& gray)
44
{
5-
fg = gray.clone();
6-
bs = new BackgroundSubtract;
7-
bs->init(gray);
5+
m_fg = gray.clone();
6+
m_bs = std::make_unique<BackgroundSubtract>(gray.channels());
7+
m_bs->init(gray);
8+
9+
m_minObjectSize.width = std::max(5, gray.cols / 100);
10+
m_minObjectSize.height = m_minObjectSize.width;
11+
}
12+
13+
CDetector::~CDetector(void)
14+
{
15+
}
16+
17+
void CDetector::SetMinObjectSize(cv::Size minObjectSize)
18+
{
19+
m_minObjectSize = minObjectSize;
820
}
921

1022
//----------------------------------------------------------------------
1123
// Detector
1224
//----------------------------------------------------------------------
13-
void CDetector::DetectContour(cv::Mat& img, std::vector<cv::Rect>& Rects, std::vector<Point_t>& centers)
25+
void CDetector::DetectContour()
1426
{
15-
Rects.clear();
16-
centers.clear();
27+
m_rects.clear();
28+
m_centers.clear();
1729
std::vector<std::vector<cv::Point> > contours;
1830
std::vector<cv::Vec4i> hierarchy;
19-
cv::Mat edges = img.clone();
20-
cv::Canny(img, edges, 50, 190, 3);
31+
cv::Mat edges;
32+
cv::Canny(m_fg, edges, 50, 190, 3);
2133
cv::findContours(edges, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, cv::Point());
2234
if (contours.size() > 0)
2335
{
2436
for (size_t i = 0; i < contours.size(); i++)
2537
{
2638
cv::Rect r = cv::boundingRect(contours[i]);
27-
Rects.push_back(r);
28-
centers.push_back((r.br() + r.tl())*0.5);
39+
40+
if (r.width >= m_minObjectSize.width &&
41+
r.height >= m_minObjectSize.height)
42+
{
43+
m_rects.push_back(r);
44+
m_centers.push_back((r.br() + r.tl())*0.5);
45+
}
2946
}
3047
}
3148
}
3249

3350
const std::vector<Point_t>& CDetector::Detect(cv::Mat& gray)
3451
{
35-
bs->subtract(gray, fg);
36-
// rects - bounding rectangles
37-
// centers - centers of bounding rectangles
38-
/*
39-
cv::Mat fg2;
40-
fg.convertTo(fg2,CV_32FC1);
41-
cv::GaussianBlur(fg2,fg2,Size(5,5),1.0);
42-
cv::Laplacian(fg2,fg2,CV_32FC1);
43-
44-
normalize(fg2,fg2,0,255,cv::NORM_MINMAX);
45-
fg2.convertTo(fg2,CV_8UC1);
46-
cv::applyColorMap(fg2,fg2,COLORMAP_JET);
47-
imshow("Foreground",fg2);
48-
*/
49-
DetectContour(fg, rects, centers);
50-
return centers;
52+
m_bs->subtract(gray, m_fg);
53+
54+
DetectContour();
55+
return m_centers;
5156
}
5257

53-
CDetector::~CDetector(void)
58+
const std::vector<cv::Rect>& CDetector::GetDetects() const
5459
{
55-
delete bs;
56-
}
60+
return m_rects;
61+
}

Detector/Detector.h

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,21 @@
77
class CDetector
88
{
99
private:
10-
void DetectContour(cv::Mat& img, std::vector<cv::Rect>& Rects, std::vector<Point_t>& centers);
11-
BackgroundSubtract* bs;
12-
std::vector<cv::Rect> rects;
13-
std::vector<Point_t> centers;
14-
cv::Mat fg;
10+
void DetectContour();
11+
12+
std::unique_ptr<BackgroundSubtract> m_bs;
13+
std::vector<cv::Rect> m_rects;
14+
std::vector<Point_t> m_centers;
15+
cv::Mat m_fg;
16+
17+
cv::Size m_minObjectSize;
18+
1519
public:
1620
CDetector(cv::Mat& gray);
1721
const std::vector<Point_t>& Detect(cv::Mat& gray);
1822
~CDetector(void);
19-
};
2023

24+
void SetMinObjectSize(cv::Size minObjectSize);
25+
26+
const std::vector<cv::Rect>& GetDetects() const;
27+
};

Tracker/Ctracker.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,13 @@ class CTrack
2323
class CTracker
2424
{
2525
public:
26-
26+
CTracker(track_t dt_, track_t Accel_noise_mag_, track_t dist_thres_ = 60, size_t maximum_allowed_skipped_frames_ = 10, size_t max_trace_length_ = 10);
27+
~CTracker(void);
28+
29+
std::vector<std::unique_ptr<CTrack>> tracks;
30+
void Update(const std::vector<Point_t>& detections);
31+
32+
private:
2733
// Шаг времени опроса фильтра
2834
track_t dt;
2935

@@ -36,10 +42,5 @@ class CTracker
3642
size_t maximum_allowed_skipped_frames;
3743
// Максимальная длина следа
3844
size_t max_trace_length;
39-
40-
std::vector<std::unique_ptr<CTrack>> tracks;
41-
void Update(const std::vector<Point_t>& detections);
42-
CTracker(track_t dt_, track_t Accel_noise_mag_, track_t dist_thres_ = 60, size_t maximum_allowed_skipped_frames_ = 10, size_t max_trace_length_ = 10);
43-
~CTracker(void);
4445
};
4546

main.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,12 @@ int main(int ac, char** av)
4848
cv::Mat frame;
4949
cv::Mat gray;
5050

51-
CTracker tracker(0.2f, 0.1f, 60.0f, 5, 10);
51+
CTracker tracker(0.2f, 0.1f, 60.0f, 10, 50);
5252

5353
capture >> frame;
5454
cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);
55-
CDetector* detector = new CDetector(gray);
55+
CDetector detector(gray);
56+
detector.SetMinObjectSize(cv::Size(gray.cols / 50, gray.rows / 20));
5657
int k = 0;
5758

5859
double freq = cv::getTickFrequency();
@@ -72,17 +73,22 @@ int main(int ac, char** av)
7273

7374
int64 t1 = cv::getTickCount();
7475

75-
const std::vector<Point_t>& centers = detector->Detect(gray);
76+
const std::vector<Point_t>& centers = detector.Detect(gray);
77+
const std::vector<cv::Rect>& rects = detector.GetDetects();
7678

7779
tracker.Update(centers);
7880

7981
int64 t2 = cv::getTickCount();
8082

8183
allTime += t2 - t1;
8284

83-
for (int i = 0; i < centers.size(); i++)
85+
for (auto p : centers)
8486
{
85-
cv::circle(frame, centers[i], 3, cv::Scalar(0, 255, 0), 1, CV_AA);
87+
cv::circle(frame, p, 3, cv::Scalar(0, 255, 0), 1, CV_AA);
88+
}
89+
for (auto r : rects)
90+
{
91+
cv::rectangle(frame, r, cv::Scalar(0, 255, 0), 1, CV_AA);
8692
}
8793

8894
std::cout << tracker.tracks.size() << std::endl;
@@ -105,9 +111,6 @@ int main(int ac, char** av)
105111

106112
std::cout << "work time = " << (allTime / freq) << std::endl;
107113

108-
delete detector;
109-
110-
111114
cv::destroyAllWindows();
112115
return 0;
113116
#else

vibe_src/BackgroundSubtract.cpp

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,71 @@
11
#include "BackgroundSubtract.h"
22

3-
BackgroundSubtract::BackgroundSubtract()
3+
BackgroundSubtract::BackgroundSubtract(
4+
int channels,
5+
int samples,
6+
int pixel_neighbor,
7+
int distance_threshold,
8+
int matching_threshold,
9+
int update_factor
10+
)
411
{
5-
model = libvibeModelNew();
12+
m_model = std::make_unique<vibe::VIBE>(channels, samples, pixel_neighbor, distance_threshold, matching_threshold, update_factor);
613
}
714

815
BackgroundSubtract::~BackgroundSubtract()
916
{
10-
libvibeModelFree(model);
1117
}
1218

13-
void BackgroundSubtract::init(cv::Mat &image)
19+
void BackgroundSubtract::init(const cv::Mat& image)
1420
{
15-
int32_t width = image.size().width;
16-
int32_t height = image.size().height;
17-
int32_t stride = image.channels()*image.size().width;
18-
uint8_t *image_data = (uint8_t*)image.data;
19-
20-
libvibeModelInit(model, image_data, width, height, stride);
21+
if (image.channels() != m_model->GetChannels())
22+
{
23+
if (image.channels() == 1)
24+
{
25+
cv::Mat newImg;
26+
cv::cvtColor(image, newImg, CV_GRAY2BGR);
27+
m_model->init(newImg);
28+
}
29+
else if (image.channels() == 3)
30+
{
31+
cv::Mat newImg;
32+
cv::cvtColor(image, newImg, CV_BGR2GRAY);
33+
m_model->init(newImg);
34+
}
35+
}
36+
else
37+
{
38+
m_model->init(image);
39+
}
2140
}
2241

23-
void BackgroundSubtract::subtract(const cv::Mat &image, cv::Mat &foreground)
42+
void BackgroundSubtract::subtract(const cv::Mat& image, cv::Mat& foreground)
2443
{
25-
uint8_t *image_data = (uint8_t*)image.data;
26-
uint8_t *segmentation_map = (uint8_t*)foreground.data;
2744
cv::Mat erodeElement = cv::getStructuringElement(0, cv::Size(5, 5), cv::Point(-1, -1));
2845
cv::Mat dilateElement = cv::getStructuringElement(0, cv::Size(3, 3), cv::Point(-1, -1));
2946

30-
libvibeModelUpdate(model, image_data, segmentation_map);
47+
if (image.channels() != m_model->GetChannels())
48+
{
49+
if (image.channels() == 1)
50+
{
51+
cv::Mat newImg;
52+
cv::cvtColor(image, newImg, CV_GRAY2BGR);
53+
m_model->update(newImg);
54+
}
55+
else if (image.channels() == 3)
56+
{
57+
cv::Mat newImg;
58+
cv::cvtColor(image, newImg, CV_BGR2GRAY);
59+
m_model->update(newImg);
60+
}
61+
}
62+
else
63+
{
64+
m_model->update(image);
65+
}
66+
67+
foreground = m_model->getMask();
3168

32-
//cv::dilate(foreground, foreground, dilateElement, cv::Point(-1,-1), 1);
3369
cv::erode(foreground, foreground, erodeElement, cv::Point(-1, -1), 1);
3470
cv::dilate(foreground, foreground, dilateElement, cv::Point(-1, -1), 2);
35-
}
71+
}

vibe_src/BackgroundSubtract.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@
22
#define _BACKGROUND_SUBTRACT_H_
33

44
#include "defines.h"
5-
#include "VIBE.h"
5+
#include "vibe.hpp"
66

77
class BackgroundSubtract
88
{
99
public:
10-
BackgroundSubtract();
10+
BackgroundSubtract(int channels = 1, int samples = 20, int pixel_neighbor = 1, int distance_threshold = 20, int matching_threshold = 3, int update_factor = 16);
1111
~BackgroundSubtract();
12-
void init(cv::Mat &image);
13-
void subtract(const cv::Mat &image, cv::Mat &foreground);
12+
void init(const cv::Mat& image);
13+
void subtract(const cv::Mat& image, cv::Mat& foreground);
1414

1515
private:
16-
vibeModel_t *model;
16+
std::unique_ptr<vibe::VIBE> m_model;
1717
};
1818

1919
#endif

0 commit comments

Comments
 (0)