#include "image_morphology.h" #include #include #include #include using namespace std; const string WHITE_BG = "white"; const string BLACK_BG = "black"; cv::Mat my_dilate(const cv::Mat& img, const cv::Size& ksize, int iter, const string& bg_type) { assert(bg_type == WHITE_BG || bg_type == BLACK_BG); cv::Mat kernel(ksize.height, ksize.width, CV_8UC1, cv::Scalar(255)); cv::Mat result; if (bg_type == BLACK_BG) { cv::dilate(img, result, kernel, cv::Point(-1, -1), iter); } else { cv::erode(img, result, kernel, cv::Point(-1, -1), iter); } return result; } cv::Mat wipe_noise(const cv::Mat& img) { cv::Mat result = img.clone(); int num_objects; cv::Mat labels, stats, centroids; num_objects = cv::connectedComponentsWithStats(img, labels, stats, centroids, 8); int img_min = min(img.rows, img.cols); double scale = pow(max(1.0, img_min / 300.0), 2); int threshold_area = static_cast(10 * scale); for (int index = 0; index < num_objects; ++index) { int area = stats.at(index, 4); if (area < threshold_area) { result.setTo(0, labels == index); } } return result; } cv::Mat wipe_noise_gray(const cv::Mat& img) { cv::Mat result = img.clone(); cv::Mat blur; cv::GaussianBlur(img, blur, cv::Size(3, 3), 0); cv::Mat binary; cv::threshold(blur, binary, 200, 255, cv::THRESH_BINARY_INV | cv::THRESH_OTSU); int num_objects; cv::Mat labels, stats, centroids; num_objects = cv::connectedComponentsWithStats(binary, labels, stats, centroids, 8); int img_min = min(img.rows, img.cols); double scale = pow(max(1.0, img_min / 300.0), 2); int threshold_area = static_cast(10 * scale); for (int index = 0; index < num_objects; ++index) { int area = stats.at(index, 4); if (area < threshold_area) { result.setTo(255, labels == index); } } return result; } cv::Mat wipe_star(const cv::Mat& img, const cv::RotatedRect& minAreaRect) { cv::Mat result = img.clone(); cv::Point2f center = minAreaRect.center; cv::Size2f wh = minAreaRect.size; double r = max(wh.width, wh.height) / min(wh.width, wh.height); int base_wh = static_cast(wh.height / 2 + wh.height / 20); double _W = base_wh * r; double _H = base_wh; int num_objects; cv::Mat labels, stats, centroids; num_objects = cv::connectedComponentsWithStats(img, labels, stats, centroids, 8); for (int index = 1; index < num_objects; ++index) { int x = stats.at(index, 0); int y = stats.at(index, 1); int w = stats.at(index, 2); int h = stats.at(index, 3); cv::Point2f _center(x + w / 2.0, y + h / 2.0); double center_dis = sqrt(pow(_center.x - center.x, 2) + pow(_center.y - center.y, 2)); double hehe = min(w, h); if (hehe > max(_W, _H) * 0.25 && hehe < min(_W, _H) && center_dis < max(_W, _H) * 0.2) { result.setTo(0, labels == index); } } if (r < 1.2) { int y1 = static_cast(center.y - wh.height * 0.15); int y2 = static_cast(center.y + wh.height * 0.15); int x1 = static_cast(center.x - wh.width * 0.15); int x2 = static_cast(center.x + wh.width * 0.15); int tx1 = max(0, x1); int ty1 = max(0, y1); int tx2 = min(static_cast(result.cols), x2); int ty2 = min(static_cast(result.rows), y2); if (tx1 < tx2 && ty1 < ty2) { result(cv::Rect(tx1, ty1, tx2 - tx1, ty2 - ty1)).setTo(0); } } return result; }