#include "ImageApplyDiscardBlank.h" #include "ImageProcess_Public.h" CImageApplyDiscardBlank::CImageApplyDiscardBlank(int blockSize, int devTh) : m_res(false) , m_dSize(blockSize) , m_devTh(devTh) { } CImageApplyDiscardBlank::CImageApplyDiscardBlank() : m_res(false) , m_dSize(200) , m_devTh(15, 15, 15, 15) { } CImageApplyDiscardBlank::~CImageApplyDiscardBlank(void) { } int CImageApplyDiscardBlank::processRectR(const cv::Mat& image, cv::RotatedRect& rotatedRect, std::vector& maxContour, double scale, double thresh, int blobAreaSize) { cv::Mat gray; int blockCount = 0; if (image.channels() == 3) if (scale != 1.0f) { cv::Size ResImgSiz = cv::Size(image.cols * scale, image.rows * scale); resize(image, gray, cv::Size(), scale, scale, 0); cvtColor(gray, gray, CV_BGR2GRAY); } else cvtColor(image, gray, CV_BGR2GRAY); else if (scale != 1.0f) resize(image, gray, cv::Size(), scale, scale, 0); else gray = image; cv::Mat threshold_img; threshold(gray, threshold_img, thresh, 255.0, CV_THRESH_BINARY); std::vector> contours; std::vector h1; hg::findContours(threshold_img, contours, h1, CV_CHAIN_APPROX_SIMPLE); threshold_img.release(); if (contours.size() == 0) return blockCount; std::vector list_com; for (int i = 0; i < contours.size(); i++) { double area = cv::contourArea(contours[i]); if (area > blobAreaSize) { blockCount++; for (int j = 0; j < contours[i].size(); j++) list_com.push_back(contours[i][j]); } } if (list_com.size() == 0) return blockCount; rotatedRect = cv::minAreaRect(list_com); rotatedRect.center.x /= (float)scale; rotatedRect.center.y /= (float)scale; rotatedRect.size.width /= (float)scale; rotatedRect.size.height /= (float)scale; if (rotatedRect.angle < -45.0f) { rotatedRect.angle += 90.0f; float l_temp = rotatedRect.size.width; rotatedRect.size.width = rotatedRect.size.height; rotatedRect.size.height = l_temp; } std::vector hull(list_com.size()); cv::convexHull(list_com, hull); for (int i = 0; i < hull.size(); i++) { cv::Point temp = list_com[hull[i]]; int x = (int)(temp.x / scale); int y = (int)(temp.y / scale); maxContour.push_back(cv::Point(x, y)); } return blockCount; } bool CImageApplyDiscardBlank::scalar_LE(const cv::Scalar& val1, const cv::Scalar& val2) { for (int i = 0; i < 3; i++) if (val1[i] > val2[i]) return false; return true; } void CImageApplyDiscardBlank::setIntensity(int val) { val = cv::max(cv::min(100, val), 2); m_devTh = cv::Scalar::all(val); } cv::Mat CImageApplyDiscardBlank::getRoiMat(const cv::Mat& image) { int gap = 100; cv::RotatedRect rect; std::vector contour; double scale = 0.25; double thresh = 50; int blobSize = 200; processRectR(image, rect, contour, scale, thresh, blobSize); cv::Rect rect2 = rect.boundingRect(); cv::Rect inRect = rect2 & cv::Rect(0, 0, image.cols, image.rows); gap = cv::max(inRect.width - rect.size.width, inRect.height - rect.size.height) + 20; inRect = cv::Rect(inRect.x + gap, inRect.y + gap, inRect.width - gap * 2, inRect.height - gap * 2); if (inRect.width <= 0 || inRect.height <= 0) return cv::Mat(); return image(inRect); } void CImageApplyDiscardBlank::apply(cv::Mat& pDib, int side) { if (pDib.empty()) { return; } cv::Scalar mean; cv::Scalar dev; cv::Mat image = getRoiMat(pDib); cv::Rect rect; cv::Rect imRect(0, 0, image.cols, image.rows); for(int i = 0; i < image.cols; i+= m_dSize) for(int j = 0; j < image.rows; j+= m_dSize) { rect = cv::Rect(i, j, m_dSize, m_dSize) & imRect; if(rect != cv::Rect()) { cv::meanStdDev (image(rect) , mean, dev); if(!scalar_LE(dev, m_devTh)) { m_res = false; #ifdef LOG FileTools::write_log("imgprc.txt", "exit CImageApplyDiscardBlank apply"); #endif // LOG return; } } } m_res = true; if (m_res) pDib.release(); #ifdef LOG FileTools::write_log("imgprc.txt", "exit CImageApplyDiscardBlank apply"); #endif // LOG } void CImageApplyDiscardBlank::apply(std::vector& mats, bool isTwoSide) { (void)isTwoSide; int i = 0; for (cv::Mat& var : mats) { if (i != 0 && isTwoSide == false) break; if (!var.empty()) apply(var, 0); i++; } } bool CImageApplyDiscardBlank::apply(const cv::Mat& pDib, int blockSize, int devTh) { if (pDib.empty()) return true; cv::Scalar mean; cv::Scalar dev; cv::Scalar s_devTh = cv::Scalar::all(devTh); cv::Mat image = getRoiMat(pDib); if (image.empty()) return false; cv::Rect rect; cv::Rect imRect(0, 0, image.cols, image.rows); for (int i = 0; i < image.cols; i += blockSize) for (int j = 0; j < image.rows; j += blockSize) { rect = cv::Rect(i, j, blockSize, blockSize) & imRect; if (rect != cv::Rect()) { cv::meanStdDev(image(rect), mean, dev); if (!scalar_LE(dev, s_devTh)) return false; } } return true; }