|  | 
| 1 | 1 | #include <Windows.h> | 
|  | 2 | +#include <mutex> | 
| 2 | 3 | #include <string> | 
| 3 | 4 | #include <sstream> | 
| 4 | 5 | #include <fstream> | 
| @@ -157,18 +158,31 @@ static cv::Scalar hue_to_scalar(int hue) | 
| 157 | 158 |         return cv::Scalar(255, 0, (360 - hue) * 255 / 60); | 
| 158 | 159 | } | 
| 159 | 160 | 
 | 
|  | 161 | +static std::mutex g_mutex; | 
|  | 162 | + | 
| 160 | 163 | static void update_object_selection_window(int x1, int y1, int x2, int y2, FILTER* fp) | 
| 161 | 164 | { | 
|  | 165 | +    std::lock_guard<std::mutex> lg(g_mutex); | 
|  | 166 | + | 
| 162 | 167 |     //update only if visible | 
| 163 | 168 |     if(!static_cast<bool>(cv::getWindowProperty("Object Selection", cv::WND_PROP_VISIBLE))) | 
| 164 | 169 |         return; | 
| 165 | 170 | 
 | 
| 166 |  | -    //draw the bounding box | 
| 167 |  | -    cv::Mat currentFrame; | 
| 168 |  | -    ocvImage.copyTo(currentFrame); | 
| 169 |  | -    cv::rectangle(currentFrame, cv::Point(x1, y1), cv::Point(x2, y2), hue_to_scalar(fp->track[1]), 2); | 
|  | 171 | +    x1 = std::clamp(x1, 0, ocvImage.cols); | 
|  | 172 | +    y1 = std::clamp(y1, 0, ocvImage.rows); | 
|  | 173 | +    x2 = std::clamp(x2, 0, ocvImage.cols); | 
|  | 174 | +    y2 = std::clamp(y2, 0, ocvImage.rows); | 
| 170 | 175 | 
 | 
| 171 |  | -    imshow("Object Selection", currentFrame); | 
|  | 176 | +    //draw the bounding box | 
|  | 177 | +    auto displayFrame = ocvImage.clone(); | 
|  | 178 | +    cv::Rect2i rect(std::min(x1, x2), std::min(y1, y2), std::abs(x1 - x2), std::abs(y1 - y2)); | 
|  | 179 | +    cv::Mat renderFrame; | 
|  | 180 | +    if (rect.area() > 0) { | 
|  | 181 | +        renderFrame = displayFrame(rect); | 
|  | 182 | +        renderFrame /= 2; | 
|  | 183 | +        renderFrame += hue_to_scalar(fp->track[1]) / 2; | 
|  | 184 | +    } | 
|  | 185 | +    cv::imshow("Object Selection", displayFrame); | 
| 172 | 186 | } | 
| 173 | 187 | 
 | 
| 174 | 188 | // Mouse callback function for object selection | 
|  | 
0 commit comments