Skip to content

Commit

Permalink
Merge pull request Smorodov#449 from Nuzhny007/master
Browse files Browse the repository at this point in the history
Add CLIP as objects classificator
  • Loading branch information
Nuzhny007 authored May 29, 2024
2 parents 19035f8 + ea3ee09 commit 2cd0a37
Show file tree
Hide file tree
Showing 36 changed files with 31,226 additions and 1,052 deletions.
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ if (BUILD_EXAMPLES)
add_subdirectory(example)
endif(BUILD_EXAMPLES)


option(USE_CLIP "Should be used RuCLIP|CLIP for objects classification?" OFF)
if (USE_CLIP)
add_definitions(-DUSE_CLIP)
endif(USE_CLIP)

option(BUILD_CARS_COUNTING "Should compiled Cars counting example?" OFF)
if (BUILD_CARS_COUNTING)
add_definitions(-DBUILD_CARS_COUNTING)
Expand Down
5 changes: 5 additions & 0 deletions example/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ set(SOURCES main.cpp
set(HEADERS MouseExample.h
VideoExample.h
examples.h
MotionDetectorExample.h
FileLogger.h)

if (BUILD_CARS_COUNTING)
Expand Down Expand Up @@ -54,6 +55,10 @@ if (BUILD_CARS_COUNTING)
add_definitions(-DBUILD_CARS_COUNTING)
endif(BUILD_CARS_COUNTING)

if (USE_CLIP)
add_definitions(-DUSE_CLIP)
set(LIBS ${LIBS} ruclip)
endif(USE_CLIP)

ADD_EXECUTABLE(${PROJECT_NAME} ${SOURCES} ${HEADERS})

Expand Down
2 changes: 1 addition & 1 deletion example/CarsCounting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ CarsCounting::CarsCounting(const cv::CommandLineParser& parser)
/// \param drawTrajectory
/// \param framesCounters
///
void CarsCounting::DrawTrack(cv::Mat frame, const TrackingObject& track, bool drawTrajectory, int framesCounter)
void CarsCounting::DrawTrack(cv::Mat frame, const TrackingObject& track, bool drawTrajectory, int framesCounter, const std::string& /*userLabel*/)
{
cv::Rect brect = track.m_rrect.boundingRect();

Expand Down
2 changes: 1 addition & 1 deletion example/CarsCounting.h
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ class CarsCounting final : public VideoExample
bool InitTracker(cv::UMat frame) override;

void DrawData(cv::Mat frame, const std::vector<TrackingObject>& tracks, int framesCounter, int currTime) override;
void DrawTrack(cv::Mat frame, const TrackingObject& track, bool drawTrajectory, int framesCounter) override;
void DrawTrack(cv::Mat frame, const TrackingObject& track, bool drawTrajectory, int framesCounter, const std::string& userLabel = "") override;

// Road lines
std::deque<RoadLine> m_lines;
Expand Down
225 changes: 225 additions & 0 deletions example/MotionDetectorExample.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
#pragma once

#include <iostream>
#include <vector>
#include <map>

#include "VideoExample.h"

#ifdef USE_CLIP
#include "ruclip/ClipAPI.h"
#endif // USE_CLIP

///
/// \brief The MotionDetectorExample class
///
class MotionDetectorExample final : public VideoExample
{
public:
MotionDetectorExample(const cv::CommandLineParser& parser)
: VideoExample(parser), m_minObjWidth(10)
{
#ifdef USE_CLIP
std::string clipModel = "C:/work/clip/ruclip_/CLIP/data/ruclip-vit-large-patch14-336";
std::string bpeModel = "C:/work/clip/ruclip_/CLIP/data/ruclip-vit-large-patch14-336/bpe.model";
m_clip.Init(clipModel, bpeModel, 336, 0, { "pedestrian", "person", "suv", "pickup", "car", "truck", "bus" });
#endif // USE_CLIP
}

protected:
///
/// \brief InitDetector
/// \param frame
/// \return
///
bool InitDetector(cv::UMat frame) override
{
m_minObjWidth = frame.cols / 20;

config_t config;
config.emplace("useRotatedRect", "0");

tracking::Detectors detectorType = tracking::Detectors::Motion_MOG;

switch (detectorType)
{
case tracking::Detectors::Motion_VIBE:
config.emplace("samples", "20");
config.emplace("pixelNeighbor", "1");
config.emplace("distanceThreshold", "20");
config.emplace("matchingThreshold", "3");
config.emplace("updateFactor", "16");
break;
case tracking::Detectors::Motion_MOG:
config.emplace("history", std::to_string(cvRound(50 * m_fps)));
config.emplace("nmixtures", "3");
config.emplace("backgroundRatio", "0.7");
config.emplace("noiseSigma", "0");
break;
case tracking::Detectors::Motion_GMG:
config.emplace("initializationFrames", "50");
config.emplace("decisionThreshold", "0.7");
break;
case tracking::Detectors::Motion_CNT:
config.emplace("minPixelStability", "15");
config.emplace("maxPixelStability", std::to_string(cvRound(20 * m_minStaticTime * m_fps)));
config.emplace("useHistory", "1");
config.emplace("isParallel", "1");
break;
case tracking::Detectors::Motion_SuBSENSE:
break;
case tracking::Detectors::Motion_LOBSTER:
break;
case tracking::Detectors::Motion_MOG2:
config.emplace("history", std::to_string(cvRound(20 * m_minStaticTime * m_fps)));
config.emplace("varThreshold", "10");
config.emplace("detectShadows", "1");
break;
}
m_detector = BaseDetector::CreateDetector(detectorType, config, frame);

if (m_detector.get())
{
m_detector->SetMinObjectSize(cv::Size(m_minObjWidth, m_minObjWidth));
return true;
}
return false;
}
///
/// \brief InitTracker
/// \param frame
/// \return
///
bool InitTracker(cv::UMat frame) override
{
if (!m_trackerSettingsLoaded)
{
m_trackerSettings.SetDistance(tracking::DistRects);
m_trackerSettings.m_kalmanType = tracking::KalmanLinear;
m_trackerSettings.m_filterGoal = tracking::FilterCenter;
m_trackerSettings.m_lostTrackType = tracking::TrackNone; // Use visual objects tracker for collisions resolving. Used if m_filterGoal == tracking::FilterRect
m_trackerSettings.m_matchType = tracking::MatchHungrian;
m_trackerSettings.m_useAcceleration = false; // Use constant acceleration motion model
m_trackerSettings.m_dt = m_trackerSettings.m_useAcceleration ? 0.05f : 0.5f; // Delta time for Kalman filter
m_trackerSettings.m_accelNoiseMag = 0.1f; // Accel noise magnitude for Kalman filter
m_trackerSettings.m_distThres = 0.95f; // Distance threshold between region and object on two frames
#if 1
m_trackerSettings.m_minAreaRadiusPix = frame.rows / 5.f;
#else
m_trackerSettings.m_minAreaRadiusPix = -1.f;
#endif
m_trackerSettings.m_minAreaRadiusK = 0.8f;

m_trackerSettings.m_useAbandonedDetection = false;
if (m_trackerSettings.m_useAbandonedDetection)
{
m_trackerSettings.m_minStaticTime = m_minStaticTime;
m_trackerSettings.m_maxStaticTime = 10;
m_trackerSettings.m_maximumAllowedSkippedFrames = cvRound(m_trackerSettings.m_minStaticTime * m_fps); // Maximum allowed skipped frames
m_trackerSettings.m_maxTraceLength = 2 * m_trackerSettings.m_maximumAllowedSkippedFrames; // Maximum trace length
}
else
{
m_trackerSettings.m_maximumAllowedSkippedFrames = cvRound(2 * m_fps); // Maximum allowed skipped frames
m_trackerSettings.m_maxTraceLength = cvRound(2 * m_fps); // Maximum trace length
}
}

m_tracker = BaseTracker::CreateTracker(m_trackerSettings);
return true;
}

///
/// \brief DrawData
/// \param frame
/// \param tracks
/// \param framesCounter
/// \param currTime
///
void DrawData(cv::Mat frame, const std::vector<TrackingObject>& tracks, int framesCounter, int currTime) override
{
if (m_showLogs)
std::cout << "Frame " << framesCounter << " (" << m_framesCount << "): tracks = " << tracks.size() << ", time = " << currTime << std::endl;

#ifdef USE_CLIP
std::vector<CLIPResult> clipResult;
std::vector<cv::Rect> clipRects;
clipRects.reserve(tracks.size());
for (const auto& track : tracks)
{
clipRects.emplace_back(track.GetBoundingRect());
}
m_clip.ProcessFrame(frame, clipRects, clipResult);
#endif // USE_CLIP

for (size_t i = 0; i < tracks.size(); ++i)
{
const auto& track = tracks[i];
if (track.m_isStatic)
{
#ifdef USE_CLIP
DrawTrack(frame, track, false, framesCounter, clipResult[i].m_label + ", " + std::to_string(clipResult[i].m_conf));
#else
DrawTrack(frame, track, false, framesCounter);
#endif //USE_CLIP
std::string label = "abandoned " + track.m_ID.ID2Str();
int baseLine = 0;
cv::Size labelSize = cv::getTextSize(label, cv::FONT_HERSHEY_TRIPLEX, 0.5, 1, &baseLine);

cv::Rect brect = track.m_rrect.boundingRect();
if (brect.x < 0)
{
brect.width = std::min(brect.width, frame.cols - 1);
brect.x = 0;
}
else if (brect.x + brect.width >= frame.cols)
{
brect.x = std::max(0, frame.cols - brect.width - 1);
brect.width = std::min(brect.width, frame.cols - 1);
}
if (brect.y - labelSize.height < 0)
{
brect.height = std::min(brect.height, frame.rows - 1);
brect.y = labelSize.height;
}
else if (brect.y + brect.height >= frame.rows)
{
brect.y = std::max(0, frame.rows - brect.height - 1);
brect.height = std::min(brect.height, frame.rows - 1);
}
DrawFilledRect(frame, cv::Rect(cv::Point(brect.x, brect.y - labelSize.height), cv::Size(labelSize.width, labelSize.height + baseLine)), cv::Scalar(255, 0, 255), 150);
cv::putText(frame, label, brect.tl(), cv::FONT_HERSHEY_TRIPLEX, 0.5, cv::Scalar(0, 0, 0));
}
else
{
auto velocity = sqrt(sqr(track.m_velocity[0]) + sqr(track.m_velocity[1]));
if (track.IsRobust(4, // Minimal trajectory size
0.3f, // Minimal ratio raw_trajectory_points / trajectory_lenght
cv::Size2f(0.2f, 5.0f))) // Min and max ratio: width / height
//velocity > 30 // Velocity more than 30 pixels per second
{
//track_t mean = 0;
//track_t stddev = 0;
//TrackingObject::LSParams lsParams;
//if (track.LeastSquares2(20, mean, stddev, lsParams) && mean > stddev)
{
#ifdef USE_CLIP
DrawTrack(frame, track, true, framesCounter, clipResult[i].m_label + ", " + std::to_string(clipResult[i].m_conf));
#else
DrawTrack(frame, track, true, framesCounter);
#endif //USE_CLIP
}
}
}
}
m_detector->CalcMotionMap(frame);
}

private:
int m_minObjWidth = 8;
int m_minStaticTime = 5;

#ifdef USE_CLIP
ClassificationCLIP m_clip;
#endif // USE_CLIP
};
5 changes: 4 additions & 1 deletion example/VideoExample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,8 @@ void VideoExample::Tracking(FrameInfo& frame)
void VideoExample::DrawTrack(cv::Mat frame,
const TrackingObject& track,
bool drawTrajectory,
int framesCounter)
int framesCounter,
const std::string& userLabel)
{
cv::Scalar color = track.m_isStatic ? cv::Scalar(255, 0, 255) : cv::Scalar(0, 255, 0);
cv::Point2f rectPoints[4];
Expand Down Expand Up @@ -587,6 +588,8 @@ void VideoExample::DrawTrack(cv::Mat frame,
std::string label = track.m_ID.ID2Str();
if (track.m_type != bad_type)
label += ": " + TypeConverter::Type2Str(track.m_type);
else if (!userLabel.empty())
label += ": " + userLabel;
if (track.m_confidence > 0)
label += ", " + std::to_string(track.m_confidence);
#if 0
Expand Down
2 changes: 1 addition & 1 deletion example/VideoExample.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ class VideoExample
void Tracking(FrameInfo& frame);

virtual void DrawData(cv::Mat frame, const std::vector<TrackingObject>& tracks, int framesCounter, int currTime) = 0;
virtual void DrawTrack(cv::Mat frame, const TrackingObject& track, bool drawTrajectory, int framesCounter);
virtual void DrawTrack(cv::Mat frame, const TrackingObject& track, bool drawTrajectory, int framesCounter, const std::string& userLabel = "");

TrackerSettings m_trackerSettings;
bool m_trackerSettingsLoaded = false;
Expand Down
Loading

0 comments on commit 2cd0a37

Please sign in to comment.