#include "ImageApplyAutoCrop.h" #include "ImageProcess_Public.h" #define RE 2 CImageApplyAutoCrop::CImageApplyAutoCrop() : m_isCrop(false) , m_isDesaskew(false) , m_isFillBlank(false) , m_isConvexHull(true) , m_threshold(40) , m_noise(2) , m_indent(5) { } CImageApplyAutoCrop::CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFillBlank, const cv::Size& fixedSize, bool isConvex, double threshold, int noise, int indent) : m_isCrop(isCrop) , m_isDesaskew(isDesaskew) , m_isFillBlank(isFillBlank) , m_isConvexHull(isConvex) , m_threshold(threshold) , m_noise(noise) , m_indent(indent) , m_fixedSize(fixedSize) { } CImageApplyAutoCrop::~CImageApplyAutoCrop() { } void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side) { #ifdef LOG FileTools::write_log("imgprc.txt", "enter CImageApplyAutoCrop apply"); #endif // LOG if (pDib.empty()) { #ifdef LOG FileTools::write_log("imgprc.txt", "exit CImageApplyAutoCrop apply"); #endif // LOG return; } cv::Mat src = pDib; cv::Mat dst; cv::Mat src_resize; cv::resize(src, src_resize, cv::Size(src.cols / RE, src.rows / RE)); cv::Mat scale_mat; cv::Mat thre(src_resize.size(), CV_8UC1); hg::threshold_Mat(src_resize, thre, m_threshold); src_resize.release(); if (m_noise > RE) { cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(m_noise / RE, m_noise / RE)); cv::morphologyEx(thre, thre, cv::MORPH_OPEN, element); element.release(); } std::vector hierarchy; std::vector> contours; hg::findContours(thre, contours, hierarchy, cv::RETR_EXTERNAL); std::vector maxContour = hg::getMaxContour(contours, hierarchy); for (cv::Point& item : maxContour) { item.x = item.x * RE - RE / 2; item.y = item.y * RE - RE / 2; } if (maxContour.size() == 0) { thre.release(); #ifdef LOG FileTools::write_log("imgprc.txt", "exit CImageApplyAutoCrop apply"); #endif // LOG return; } thre.release(); dst.release(); m_rect = hg::getBoundingRect(maxContour); if (m_isDesaskew) { cv::Point2f srcTri[4]; cv::Point2f dstTri[3]; m_rect.points(srcTri); dstTri[0] = cv::Point2f(0, m_rect.size.height - 1); dstTri[1] = cv::Point2f(0, 0); dstTri[2] = cv::Point2f(m_rect.size.width - 1, 0); cv::Mat warp_mat; warp_mat = cv::getAffineTransform(srcTri, dstTri); cv::warpAffine(src, dst, warp_mat, m_rect.size); } else dst = src(m_rect.boundingRect() & cv::Rect(0, 0, src.cols, src.rows)); if (m_isFillBlank) { cv::Mat thre_dst; hg::threshold_Mat(dst, thre_dst, m_threshold); cv::erode(thre_dst, thre_dst, cv::Mat(), cv::Point(-1, -1), m_indent); hierarchy.clear(); contours.clear(); maxContour.clear(); hg::findContours(thre_dst, contours, hierarchy, cv::RETR_EXTERNAL); thre_dst.release(); maxContour = hg::getMaxContour(contours, hierarchy); if (m_isConvexHull) hg::convexHull(maxContour, maxContour); contours.clear(); contours.resize(2); contours[0] = maxContour; contours[1].push_back(cv::Point(0, dst.rows - 1)); contours[1].push_back(cv::Point(0, 0)); contours[1].push_back(cv::Point(dst.cols - 1, 0)); contours[1].push_back(cv::Point(dst.cols - 1, dst.rows - 1)); hg::fillPolys(dst, contours, cv::Scalar(255, 255, 255)); } pDib.release(); if ((m_isCrop && side == 0) || (side == 1 && m_fixedSize.width * m_fixedSize.height == 0)) pDib = dst.clone(); else { if (m_isCrop && side == 1 && !m_fixedSize.empty()) if (std::abs(m_fixedSize.width - dst.cols) > 50 || std::abs(m_fixedSize.height - dst.rows) > 50) { pDib = dst.clone(); #ifdef LOG FileTools::write_log("imgprc.txt", "exit CImageApplyAutoCrop apply"); #endif // LOG return; } pDib = cv::Mat(m_fixedSize, dst.type(), m_isFillBlank ? cv::Scalar(255, 255, 255) : cv::Scalar(0, 0, 0)); cv::Rect roi; roi.x = dst.cols > pDib.cols ? (dst.cols - pDib.cols) / 2 : 0; roi.width = cv::min(pDib.cols, dst.cols); roi.y = dst.rows > pDib.rows ? (dst.rows - pDib.rows) / 2 : 0; roi.height = cv::min(pDib.rows, dst.rows); cv::Rect rect((pDib.cols - roi.width) / 2, (pDib.rows - roi.height) / 2, roi.width, roi.height); #if 0 std::string outrectinfo ="copy to rect x: "+std::to_string(rect.x) + "y: "+std::to_string(rect.y) + "width: "+std::to_string(rect.width) + "height: "+std::to_string(rect.height); std::string outroiinfo = "roi x: " + std::to_string(roi.x) + "y: " + std::to_string(roi.y) + "width: " + std::to_string(roi.width) + "height: " + std::to_string(roi.height); std::string dstsize = "dst size: width:" + std::to_string(dst.cols) + "height: " + std::to_string(dst.rows); std::string pDibszie= "pDib size: width: " + std::to_string(pDib.cols) + "height: " + std::to_string(pDib.rows); FileTools::write_log("imgprc.txt", dstsize); FileTools::write_log("imgprc.txt", pDibszie); FileTools::write_log("imgprc.txt", outrectinfo); FileTools::write_log("imgprc.txt", outroiinfo); #endif // LOG dst(roi).copyTo(pDib(rect)); } #ifdef LOG FileTools::write_log("imgprc.txt", "exit CImageApplyAutoCrop apply8"); #endif // LOG } void CImageApplyAutoCrop::apply(std::vector& mats, bool isTwoSide) { m_rects.clear(); if (mats.empty()) return; if (!mats[0].empty()) { apply(mats[0], 0); m_rects.push_back(m_rect); //cv::imwrite("1.bmp", mats[0]); } if (isTwoSide && mats.size() > 1) { cv::Size dSize = m_fixedSize; if (!mats[0].empty()) m_fixedSize = mats[0].size(); if (!mats[1].empty()) { apply(mats[1], 1); m_rects.push_back(m_rect); //cv::imwrite("1.bmp", mats[0]); } if (!mats[0].empty()) m_fixedSize = dSize; } }