#include "image_utilities.h" #include #include #include #include #include using namespace std; vector mrect2box(const cv::RotatedRect& mrect) { cv::Point2f boxPoints[4]; mrect.points(boxPoints); vector result; for (int i = 0; i < 4; ++i) { result.emplace_back(cv::Point(static_cast(boxPoints[i].x), static_cast(boxPoints[i].y))); } return result; } cv::Mat block_threshold(const cv::Mat& gray) { try { int height = gray.rows; int width = gray.cols; vector divisions = {8, 13}; vector block_sizes; for (int div : divisions) { int size = max(19, (height + width) / 2 / div); if (size % 2 == 0) size++; block_sizes.push_back(size); } vector> block_strategies; for (int size : block_sizes) { block_strategies.push_back({size, 0}); block_strategies.push_back({size, size / 2}); } cv::Mat otsu; double global_threshold = cv::threshold(gray, otsu, 0, 255, cv::THRESH_BINARY_INV | cv::THRESH_OTSU); cv::Mat adaptive_ref; cv::adaptiveThreshold(gray, adaptive_ref, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY_INV, block_sizes[0], 20); cv::Mat result = cv::Mat::zeros(gray.size(), CV_8UC1); for (auto& strategy : block_strategies) { int block_size = strategy.first; int offset = strategy.second; cv::Mat current_result = cv::Mat::zeros(gray.size(), CV_8UC1); for (int y = offset; y < height; y += block_size) { for (int x = offset; x < width; x += block_size) { int end_y = min(y + block_size, height); int end_x = min(x + block_size, width); cv::Mat block_roi = gray(cv::Rect(x, y, end_x - x, end_y - y)); cv::Scalar mean, stddev; cv::meanStdDev(block_roi, mean, stddev); double variance = stddev[0] * stddev[0]; cv::Mat block_result; if (variance < 80) { block_result = cv::Mat::zeros(block_roi.size(), CV_8UC1); if (mean[0] < global_threshold) { block_result = cv::Mat::ones(block_roi.size(), CV_8UC1) * 255; } } else { cv::threshold(block_roi, block_result, 0, 255, cv::THRESH_BINARY_INV | cv::THRESH_OTSU); cv::Scalar ref_mean, block_mean; cv::Mat adaptive_block = adaptive_ref(cv::Rect(x, y, end_x - x, end_y - y)); cv::meanStdDev(adaptive_block, ref_mean, cv::noArray()); cv::meanStdDev(block_result, block_mean, cv::noArray()); if (abs(ref_mean[0] - block_mean[0]) > 200) { block_result = 255 - block_result; } } block_result.copyTo(current_result(cv::Rect(x, y, end_x - x, end_y - y))); } } cv::bitwise_or(result, current_result, result); } return result; } catch (const exception& e) { cout << "Exception in block_threshold: " << e.what() << endl; return cv::Mat(); } catch (...) { cout << "Unknown exception in block_threshold" << endl; return cv::Mat(); } }