#include "intelligentroi.h" #include #include "utils.h" #include "log.h" bool InteligentRoi::compPointPrio(const std::pair& a, const std::pair& 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> 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& a, const std::pair& 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& mipoint : mustInclude) Log(Log::DEBUG)<& 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& detections, const cv::Size2i& imageSize) { if(!detections.empty()) { std::vector> 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+2}); corners.push_back({detections[i].box.tl(), priority+1}); corners.push_back({detections[i].box.br(), priority}); corners.push_back({detections[i].box.tl()+cv::Point2i(detections[i].box.width, 0), priority+1}); corners.push_back({detections[i].box.br()+cv::Point2i(0-detections[i].box.width, 0), priority}); } else { 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); }