100 lines
3.0 KiB
C++
100 lines
3.0 KiB
C++
#include "intelligentroi.h"
|
|
|
|
#include <opencv2/imgproc.hpp>
|
|
|
|
#include "utils.h"
|
|
#include "log.h"
|
|
|
|
bool InteligentRoi::compPointPrio(const std::pair<cv::Point2i, int>& a, const std::pair<cv::Point2i, int>& b, const cv::Point2i& center)
|
|
{
|
|
if(a.second != b.second)
|
|
return a.second > b.second;
|
|
|
|
double distA = pointDist(a.first, center);
|
|
double distB = pointDist(b.first, center);
|
|
|
|
return distA < distB;
|
|
}
|
|
|
|
void InteligentRoi::slideRectToPoint(cv::Rect& rect, const cv::Point2i& point)
|
|
{
|
|
if(!pointInRect(point, rect))
|
|
{
|
|
if(point.x < rect.x)
|
|
rect.x = point.x;
|
|
else if(point.x > rect.x+rect.width)
|
|
rect.x = point.x-rect.width;
|
|
if(point.y < rect.y)
|
|
rect.y = point.y;
|
|
else if(point.y > rect.y+rect.height)
|
|
rect.y = point.y-rect.height;
|
|
}
|
|
}
|
|
|
|
cv::Rect InteligentRoi::maxRect(const cv::Size2i& imageSize, std::vector<std::pair<cv::Point2i, int>> mustInclude)
|
|
{
|
|
int radius = std::min(imageSize.height, imageSize.width)/2;
|
|
cv::Point2i point(imageSize.width/2, imageSize.height/2);
|
|
cv::Rect candiate(point.x-radius, point.y-radius, radius*2, radius*2);
|
|
|
|
std::sort(mustInclude.begin(), mustInclude.end(),
|
|
[&point](const std::pair<cv::Point2i, int>& a, const std::pair<cv::Point2i, int>& b){return compPointPrio(a, b, point);});
|
|
|
|
while(true)
|
|
{
|
|
cv::Rect includeRect = rectFromPoints(mustInclude);
|
|
if(includeRect.width-2 > radius || includeRect.height-2 > radius)
|
|
{
|
|
slideRectToPoint(candiate, mustInclude.back().first);
|
|
mustInclude.pop_back();
|
|
Log(Log::DEBUG)<<"cant fill";
|
|
for(const std::pair<cv::Point2i, int>& mipoint : mustInclude)
|
|
Log(Log::DEBUG)<<mipoint.first<<' '<<pointDist(mipoint.first, point)<<' '<<mipoint.second;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
|
|
for(const std::pair<cv::Point2i, int>& includePoint : mustInclude)
|
|
slideRectToPoint(candiate, includePoint.first);
|
|
|
|
if(candiate.x < 0)
|
|
candiate.x = 0;
|
|
if(candiate.y < 0)
|
|
candiate.y = 0;
|
|
if(candiate.x+candiate.width > imageSize.width)
|
|
candiate.width = imageSize.width-candiate.x;
|
|
if(candiate.y+candiate.height > imageSize.height)
|
|
candiate.height = imageSize.height-candiate.y;
|
|
|
|
return candiate;
|
|
}
|
|
|
|
InteligentRoi::InteligentRoi(const Yolo& yolo)
|
|
{
|
|
personId = yolo.getClassForStr("person");
|
|
}
|
|
|
|
cv::Rect InteligentRoi::getCropRectangle(const std::vector<Yolo::Detection>& detections, const cv::Size2i& imageSize)
|
|
{
|
|
if(!detections.empty())
|
|
{
|
|
std::vector<std::pair<cv::Point2i, int>> corners;
|
|
for(size_t i = 0; i < detections.size(); ++i)
|
|
{
|
|
int priority = detections[i].priority;
|
|
if(detections[i].class_id == personId)
|
|
corners.push_back({detections[i].box.tl()+cv::Point2i(detections[i].box.width/2, 0), priority+1});
|
|
corners.push_back({detections[i].box.tl(), priority});
|
|
corners.push_back({detections[i].box.br(), priority});
|
|
corners.push_back({detections[i].box.tl()+cv::Point2i(detections[i].box.width, 0), priority});
|
|
corners.push_back({detections[i].box.br()+cv::Point2i(0-detections[i].box.width, 0), priority});
|
|
}
|
|
|
|
return maxRect(imageSize, corners);
|
|
}
|
|
|
|
Log(Log::DEBUG)<<"Using center crop as there are no detections";
|
|
return maxRect(imageSize);
|
|
}
|