#include "StdAfx.h" #include "ImageApplyDiscardBlank.h" #include "ImageProcess_Public.h" CImageApplyDiscardBlank::CImageApplyDiscardBlank(bool isnormal) : m_res(false) , isNormalDiscard(isnormal) , dSize(200) , 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(20, val), 2); devTh = cv::Scalar(val, val, val, 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; int edgeWidth = 10; 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) + 100; inRect = cv::Rect(inRect.x + gap, inRect.y + gap, inRect.width - gap * 2, inRect.height - gap * 2); return image(inRect); } void CImageApplyDiscardBlank::apply(cv::Mat& pDib,int side) { #ifdef LOG FileTools::write_log("imgprc.txt", "enter CImageApplyDiscardBlank apply"); #endif // LOG if (pDib.empty()) { #ifdef LOG FileTools::write_log("imgprc.txt", "exit CImageApplyDiscardBlank apply"); #endif // LOG return; } setIntensity(isNormalDiscard ? 8 : 20); setMinArea(isNormalDiscard ? 200 : 300); 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+= dSize) for(int j = 0; j < image.rows; j+= dSize) { rect = cv::Rect(i, j,dSize, dSize) & imRect; if(rect != cv::Rect()) { cv::meanStdDev (image(rect) , mean, dev); if(!scalar_LE(dev, 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) { if (mats.empty()) return; apply(mats[0], 0); if (isTwoSide && mats.size() > 1) apply(mats[1], 1); }