| 256 | |
| 257 | |
| 258 | cv::Mat getAppGuide(const cv::Mat& image, bool stretchHist) |
| 259 | { |
| 260 | // orig_img = blur_orig_img + G_app ==> G_app = orig_img - blur_orig_img |
| 261 | cv::Mat grayImg, resultImg, blurImg; |
| 262 | cv::cvtColor(image, grayImg, cv::COLOR_BGR2GRAY); |
| 263 | cv::pyrDown(grayImg, blurImg); |
| 264 | cv::pyrDown(blurImg, blurImg); |
| 265 | cv::pyrDown(blurImg, blurImg); |
| 266 | |
| 267 | cv::resize(blurImg, resultImg, cv::Size(grayImg.cols, grayImg.rows), 0, 0, cv::INTER_LINEAR); |
| 268 | //imwrite("C:\\Users\\Aneta\\Desktop\\intermed_results\\appGuideBlur" + std::to_string(stretchHist) + ".png", resultImg); |
| 269 | //cv::GaussianBlur(grayImg, resultImg, cv::Size(5, 5), 0, 0, 4); |
| 270 | int min = 255; |
| 271 | int max = 0; |
| 272 | |
| 273 | for (int row = 0; row < grayImg.rows; row++) |
| 274 | { |
| 275 | for (int col = 0; col < grayImg.cols; col++) |
| 276 | { |
| 277 | int diff = grayImg.at<uchar>(row, col) - resultImg.at<uchar>(row, col); |
| 278 | resultImg.at<uchar>(row, col) = (diff / 2) + MEAN; |
| 279 | |
| 280 | if ((int)resultImg.at<uchar>(row, col) < min) |
| 281 | min = resultImg.at<uchar>(row, col); |
| 282 | if ((int)resultImg.at<uchar>(row, col) > max) |
| 283 | max = resultImg.at<uchar>(row, col); |
| 284 | } |
| 285 | } |
| 286 | |
| 287 | if (!stretchHist) return resultImg; |
| 288 | |
| 289 | // Prevent mean shift |
| 290 | int x = MIN(min, (255 - max)); |
| 291 | min = x; |
| 292 | max = 255 - x; |
| 293 | |
| 294 | // Histogram stretching - contrast enhancement |
| 295 | for (int row = 0; row < grayImg.rows; row++) |
| 296 | { |
| 297 | for (int col = 0; col < grayImg.cols; col++) |
| 298 | { |
| 299 | resultImg.at<uchar>(row, col) = (((double)resultImg.at<uchar>(row, col) - min) / (max - min)) * 255; |
| 300 | } |
| 301 | } |
| 302 | |
| 303 | return resultImg; |
| 304 | } |
| 305 | |
| 306 | |
| 307 | cv::Mat getSkinMask(const cv::Mat& image, const std::vector<cv::Point2i>& landmarks) |