From a72e300eb17b7ae56573965bd0e51a7a0b64298c Mon Sep 17 00:00:00 2001 From: masayume <1936714878@qq.com> Date: Mon, 21 Dec 2020 17:34:20 +0800 Subject: [PATCH] =?UTF-8?q?1=EF=BC=8C=E4=BF=AE=E6=94=B9=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E8=A3=81=E5=89=AA=E5=8F=82=E6=95=B0=E5=88=97=E8=A1=A8=202?= =?UTF-8?q?=EF=BC=8C=E6=9B=B4=E6=96=B0=E6=89=80=E6=9C=89=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E5=88=B0=E6=9C=80=E6=96=B0=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- huagao/CBasicPage.cpp | 2 +- huagao/Device/ImageMatQueue.cpp | 2 +- .../ImageProcess/ImageApplyAdjustColors.cpp | 72 +++++--------- huagao/ImageProcess/ImageApplyAdjustColors.h | 5 + huagao/ImageProcess/ImageApplyAutoCrop.cpp | 85 +++++++++++----- huagao/ImageProcess/ImageApplyAutoCrop.h | 23 +++-- huagao/ImageProcess/ImageApplyBWBinaray.cpp | 6 +- huagao/ImageProcess/ImageApplyBWBinaray.h | 10 +- huagao/ImageProcess/ImageApplyChannel.cpp | 81 +++++++++------ huagao/ImageProcess/ImageApplyChannel.h | 26 ++--- .../ImageApplyColorRecognition.cpp | 2 +- .../ImageProcess/ImageApplyConcatenation.cpp | 28 +++++- huagao/ImageProcess/ImageApplyConcatenation.h | 27 ++++- .../ImageProcess/ImageApplyDiscardBlank.cpp | 57 ++++++++--- huagao/ImageProcess/ImageApplyDiscardBlank.h | 18 ++-- huagao/ImageProcess/ImageApplyOutHole.cpp | 14 ++- huagao/ImageProcess/ImageApplyOutHole.h | 2 +- huagao/ImageProcess/ImageApplyResize.cpp | 34 +++---- huagao/ImageProcess/ImageApplyResize.h | 6 ++ huagao/ImageProcess/ImageApplyRotation.h | 29 +++++- huagao/ImageProcess/ImageProcess_Public.cpp | 21 +++- huagao/ImageProcess/ImageProcess_Public.h | 92 +++++++++++++++++- huagao/huagaods.cpp | 4 +- huagao/stdafx.h | Bin 10770 -> 10770 bytes 24 files changed, 456 insertions(+), 190 deletions(-) diff --git a/huagao/CBasicPage.cpp b/huagao/CBasicPage.cpp index 493c3bbb..73932e2d 100644 --- a/huagao/CBasicPage.cpp +++ b/huagao/CBasicPage.cpp @@ -87,7 +87,7 @@ static std::vector reslutions{ _T("240"), _T("300"), #ifndef LANXUM - //_T("600") + _T("600") #endif // LANXUM }; diff --git a/huagao/Device/ImageMatQueue.cpp b/huagao/Device/ImageMatQueue.cpp index 531b5780..6c1ba5ee 100644 --- a/huagao/Device/ImageMatQueue.cpp +++ b/huagao/Device/ImageMatQueue.cpp @@ -162,7 +162,7 @@ void ImageMatQueue::setparam(const GScanCap& param) #else // REAL300DPI fixedSize = papersize.GetPaperSize(param.papertype, 200.0f, param.paperAlign); #endif - m_iaList.push_back(shared_ptr(new CImageApplyAutoCrop(islongcustomcrop ? islongcustomcrop : param.is_autocrop, param.autodescrew, param.fillbackground, cv::Size(fixedSize.cx, fixedSize.cy), param.is_convex,param.AutoCrop_threshold,param.noise,param.indent))); + m_iaList.push_back(shared_ptr(new CImageApplyAutoCrop(islongcustomcrop ? islongcustomcrop : param.is_autocrop, param.autodescrew, param.fillbackground, cv::Size(fixedSize.cx, fixedSize.cy), param.is_convex,false,param.AutoCrop_threshold,param.noise,param.indent))); } if (param.is_autodiscradblank_normal || param.is_autodiscradblank_vince) { //m_iaList.push_back(shared_ptr(new CImageApplyDiscardBlank())); diff --git a/huagao/ImageProcess/ImageApplyAdjustColors.cpp b/huagao/ImageProcess/ImageApplyAdjustColors.cpp index 0d1eead8..fd46f987 100644 --- a/huagao/ImageProcess/ImageApplyAdjustColors.cpp +++ b/huagao/ImageProcess/ImageApplyAdjustColors.cpp @@ -22,44 +22,31 @@ CImageApplyAdjustColors::~CImageApplyAdjustColors(void) void CImageApplyAdjustColors::apply(cv::Mat& pDib,int side) { -#ifdef LOG - FileTools::write_log("imgprc.txt", "enter CImageApplyAdjustColors apply"); -#endif // LOG - if (pDib.empty()) - { + (void)side; + if (pDib.empty()) return; -#ifdef LOG - FileTools::write_log("imgprc.txt", "exit CImageApplyAdjustColors apply"); -#endif // LOG - return; - } - - if (m_brightness != 0 || m_contrast != 0 || m_gamma != 1.0) - cv::LUT(pDib, lut, pDib); -#ifdef LOG - FileTools::write_log("imgprc.txt", "exit CImageApplyAdjustColors apply"); -#endif // LOG + if (m_brightness != 0 || m_contrast != 0 || m_gamma < 0.999999f || m_gamma > 1.000001f) + cv::LUT(pDib, lut, pDib); } void CImageApplyAdjustColors::apply(std::vector& mats, bool isTwoSide) { - if (mats.empty()) return; - if (!mats[0].empty()) { - apply(mats[0], 0); - } - - - if (isTwoSide && mats.size() > 1) { - if(!mats[1].empty()) - apply(mats[1], 1); + (void)isTwoSide; + int i = 0; + for (cv::Mat& var : mats) { + if (i != 0 && isTwoSide == false) + break; + if(!var.empty()) + apply(var, 0); + i++; } } void CImageApplyAdjustColors::setAdjustColors(int brightness, int contrast, float gamma) { - setBrightness(brightness); - setContrast(contrast); - setGamma(gamma); + m_brightness = cv::max(-255, cv::min(brightness, 255)); + m_contrast = cv::max(-127, cv::min(contrast, 127)); + m_gamma = cv::max(0.1f, cv::min(gamma, 5.0f)); update_lutData(); } @@ -85,24 +72,19 @@ void CImageApplyAdjustColors::update_lutData() { unsigned char* ptr = lut.data; - if (m_gamma != 1.0f) + uchar buffer[256]; + for (int i = 0; i < 256; i++) { - float g = 1.0f / m_gamma; - for (int i = 0; i < 256; i++) - ptr[i] = static_cast(cv::min(255, static_cast(cv::pow(i / 255.0f, g) * 255.0f + 0.5f))); - } - else - { - for (int i = 0; i < 256; i++) - { - //update contrast - if (i < 128) - ptr[i] = static_cast(cv::max(0, cv::min(i - m_contrast, 127))); - else - ptr[i] = static_cast(cv::max(127, cv::min(i + m_contrast, 255))); + //update brightness + ptr[i] = static_cast(cv::max(0, cv::min(i + m_brightness, 255))); - //update brightness - ptr[i] = static_cast(cv::max(0, cv::min(ptr[i] + m_brightness, 255))); - } + //update contrast + if (ptr[i] < 128) + ptr[i] = static_cast(cv::max(0, cv::min(ptr[i] - m_contrast, 127))); + else + ptr[i] = static_cast(cv::max(127, cv::min(ptr[i] + m_contrast, 255))); } + float g = 1.0f / m_gamma; + for (int i = 0; i < 256; i++) + ptr[i] = static_cast(cv::min(255, static_cast(cv::pow(static_cast(ptr[i]) / 255.0f, g) * 255.0f + 0.5f))); } diff --git a/huagao/ImageProcess/ImageApplyAdjustColors.h b/huagao/ImageProcess/ImageApplyAdjustColors.h index f9dd77bb..83ea5959 100644 --- a/huagao/ImageProcess/ImageApplyAdjustColors.h +++ b/huagao/ImageProcess/ImageApplyAdjustColors.h @@ -9,6 +9,11 @@ public: CImageApplyAdjustColors(void); + /* + * brightness [in]: 亮度调节,取值范围[-255, 255] + * constrast [in]: 对比度调节,取值范围[-128, 127] + * gamma [in]: 伽马调节,取值范围[0.1, 5.0] + */ CImageApplyAdjustColors(int brightness, int contrast, float gamma); virtual ~CImageApplyAdjustColors(void); diff --git a/huagao/ImageProcess/ImageApplyAutoCrop.cpp b/huagao/ImageProcess/ImageApplyAutoCrop.cpp index accd9f88..e3e5bb30 100644 --- a/huagao/ImageProcess/ImageApplyAutoCrop.cpp +++ b/huagao/ImageProcess/ImageApplyAutoCrop.cpp @@ -6,17 +6,19 @@ CImageApplyAutoCrop::CImageApplyAutoCrop() , m_isDesaskew(false) , m_isFillBlank(false) , m_isConvexHull(true) + , m_isFillColor(false) , 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) +CImageApplyAutoCrop::CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFillBlank, const cv::Size& fixedSize, bool isConvex, bool isFillColor, double threshold, int noise, int indent) : m_isCrop(isCrop) , m_isDesaskew(isDesaskew) , m_isFillBlank(isFillBlank) , m_isConvexHull(isConvex) + , m_isFillColor(isFillColor) , m_threshold(threshold) , m_noise(noise) , m_indent(indent) @@ -101,7 +103,7 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side) cv::Point(thre_dst.cols - 1, thre_dst.rows - 1), cv::Point(0, thre_dst.rows - 1) }; std::vector> rectEdges{ rectEdge }; cv::drawContours(thre_dst, rectEdges, 0, cv::Scalar::all(0)); - cv::Mat element = cv::getStructuringElement(cv::MorphShapes::MORPH_RECT, cv::Size(m_indent * 2, m_indent * 2)); + cv::Mat element = cv::getStructuringElement(cv::MorphShapes::MORPH_RECT, cv::Size(m_indent, m_indent)); cv::erode(thre_dst, thre_dst, element, cv::Point(-1, -1), 1); } hierarchy.clear(); @@ -123,7 +125,7 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side) contours[contours.size() - 1].push_back(cv::Point(dst.cols, -1)); contours[contours.size() - 1].push_back(cv::Point(dst.cols, dst.rows)); - hg::fillPolys(dst, contours, cv::Scalar(255, 255, 255)); + hg::fillPolys(dst, contours, m_isFillColor ? getBackGroudColor(pDib, rect.size.area()) : cv::Scalar(255, 255, 255)); } pDib.release(); @@ -131,17 +133,6 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side) pDib = dst.clone(); else { -#if 0 - 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; - } -#endif pDib = cv::Mat(m_fixedSize, dst.type(), m_isFillBlank ? cv::Scalar(255, 255, 255) : cv::Scalar(0, 0, 0)); cv::Rect roi; @@ -153,18 +144,7 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side) for (cv::Point& p : m_maxContour) p += roi.tl(); -#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"); @@ -191,3 +171,58 @@ void CImageApplyAutoCrop::apply(std::vector& mats, bool isTwoSide) m_fixedSize = dSize; } } + +cv::Scalar CImageApplyAutoCrop::getBackGroudColor(const cv::Mat& image, int total) +{ + if (image.channels() == 3) + { + cv::Mat image_bgr[3]; + cv::split(image, image_bgr); + + uchar bgr[3]; + for (size_t i = 0; i < 3; i++) + bgr[i] = getBackGroudChannelMean(image_bgr[i], total); + return cv::Scalar(bgr[0], bgr[1], bgr[2]); + } + else + return cv::Scalar::all(getBackGroudChannelMean(image, total)); +} + +uchar CImageApplyAutoCrop::getBackGroudChannelMean(const cv::Mat& gray, int total) +{ + cv::Mat image_clone; + cv::resize(gray, image_clone, cv::Size(), 0.25, 0.25); + + int threnshold = total / 32; + int channels[] = { 0 }; + int nHistSize[] = { 256 }; + float range[] = { 0, 256 }; + const float* fHistRanges[] = { range }; + cv::Mat hist; + cv::calcHist(&image_clone, 1, channels, cv::Mat(), hist, 1, nHistSize, fHistRanges, true, false); + + int hist_array[256]; + for (int i = 0; i < 256; i++) + hist_array[i] = hist.at(i, 0); + + int length = 1; + const int length_max = 255 - m_threshold; + while (length < length_max) + { + for (size_t i = m_threshold + 1; i < 256 - length; i++) + { + int count = 0; + uint pixSum = 0; + for (size_t j = 0; j < length; j++) + { + count += hist_array[j + i]; + pixSum += hist_array[j + i] * (i + j); + } + + if (count >= threnshold) + return pixSum / count; + } + length++; + } + return 255; +} diff --git a/huagao/ImageProcess/ImageApplyAutoCrop.h b/huagao/ImageProcess/ImageApplyAutoCrop.h index 08028944..52f0e6d9 100644 --- a/huagao/ImageProcess/ImageApplyAutoCrop.h +++ b/huagao/ImageProcess/ImageApplyAutoCrop.h @@ -5,13 +5,13 @@ * 浣滆咃細鍒樹竵缁 * 鐢熸垚鏃堕棿锛2020/4/21 * 鏈杩戜慨鏀规椂闂达細2020/4/21 v1.0 - 2020/7/22 v1.1 澧炲姞鑾峰彇鍥惧儚鏈夋晥鍖哄煙杞粨鐨勬帴鍙axContour锛堢敤浜庨厤鍚堜竴浣撴満鐨勨滆烦杩囩┖鐧介〉鈥濈畻娉曪紝PC绔殏鏃舵棤闇浣跨敤锛 - 2020/10/16 v1.2 淇鑷姩瑁佸壀灏哄绮惧害涓㈠け鐨凚UG锛涙彁楂橀櫎榛戝簳缂╄繘绮惧害銆 - 2020/10/28 v1.2.1 淇鍑瑰嚫澶氳竟褰㈠~鍏呰儗鏅殑閫昏緫BUG銆 - 2020/10/28 v1.2.2 淇鍥惧儚澶勭悊蹇呭畾浼氱缉灏忓昂瀵哥殑BUG銆 - 2020/10/29 v1.2.3 閬垮厤鏃犺皳鐨勭籂鍋忥紙0掳绾犲亸锛夈 - 2020/11/09 v1.2.4 閬垮厤鏃犺皳鐨勫鐞嗭紙瑁佸壀銆佺籂鍋忋侀櫎榛戝簳鍧囦负false锛 - * 鐗堟湰鍙凤細v1.2.4 + 2020/7/22 v1.1 澧炲姞鑾峰彇鍥惧儚鏈夋晥鍖哄煙杞粨鐨勬帴鍙axContour锛堢敤浜庨厤鍚堜竴浣撴満鐨勨滆烦杩囩┖鐧介〉鈥濈畻娉曪紝PC绔殏鏃舵棤闇浣跨敤锛 + 2020/10/16 v1.2 淇鑷姩瑁佸壀灏哄绮惧害涓㈠け鐨凚UG锛涙彁楂橀櫎榛戝簳缂╄繘绮惧害銆 + 2020/10/28 v1.2.1 淇鍑瑰嚫澶氳竟褰㈠~鍏呰儗鏅殑閫昏緫BUG銆 + 2020/10/28 v1.2.2 淇鍥惧儚澶勭悊蹇呭畾浼氱缉灏忓昂瀵哥殑BUG銆 + 2020/10/29 v1.2.3 閬垮厤鏃犺皳鐨勭籂鍋忥紙0掳绾犲亸锛 + 2020/11/30 v1.3.0 澧炲姞鍔熻兘锛屽彲璇嗗埆鏂囩ǹ棰滆壊杩涜濉厖榛戝簳銆 + * 鐗堟湰鍙凤細v1.3.0 * ==================================================== */ @@ -32,11 +32,12 @@ public: * isFillBlank [in]:榛戝簳濉厖浣胯兘锛宼rue涓哄~鍏咃紝false涓轰笉濉厖 * fixedSize [in]:鍥哄畾骞呴潰灏哄锛屽綋isCrop涓篺alse鏃剁敓鏁堬紝缁撴灉灏哄鎸塮ixedSize澶у皬杈撳嚭锛屽崟浣嶅儚绱 * isConvex [in]:榛戝簳濉厖鏃剁殑濉厖鏂瑰紡,true涓哄嚫澶氳竟褰㈠~鍏咃紝false涓哄嚬澶氳竟褰㈠~鍏咃紝榛樿true + * isFillColor [in]:榛戝簳濉厖鏃堕噰鐢ㄨ嚜閫傚簲鑹插僵濉厖锛宖alse涓虹櫧鑹插~鍏咃紝true涓鸿嚜閫傚簲鏂囩ǹ搴曡壊濉厖锛岄粯璁alse * threshold [in]:浜屽煎寲闃堝硷紝鍙栧艰寖鍥(0, 255)锛岄粯璁40 * noise [in]:闄ゅ櫔鍍忕礌锛岃兘澶熸秷闄oise瀹藉害鐨勮儗鏅珫鏉$汗骞叉壈锛岄粯璁40 * indent [in]:杞粨缂╄繘锛岃鍓佺籂鍋忔垨鑰呴粦搴曞~鍏呮椂锛屽鎺㈢储鍒扮殑绾稿紶杞粨杩涜缂╄繘indent鍍忕礌锛岄粯璁5 */ - CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFillBlank, const cv::Size& fixedSize, bool isConvex = true, double threshold = 40, int noise = 40, int indent = 5); + CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFillBlank, const cv::Size& fixedSize, bool isConvex = true, bool isFillColor = false, double threshold = 40, int noise = 40, int indent = 5); virtual ~CImageApplyAutoCrop(); @@ -78,11 +79,17 @@ public: void setFixedSize(cv::Size size) { m_fixedSize = size; } +private: + cv::Scalar getBackGroudColor(const cv::Mat& image, int total); + + uchar getBackGroudChannelMean(const cv::Mat& gray, int total); + private: bool m_isCrop; bool m_isDesaskew; bool m_isFillBlank; bool m_isConvexHull; + bool m_isFillColor; double m_threshold; int m_noise; diff --git a/huagao/ImageProcess/ImageApplyBWBinaray.cpp b/huagao/ImageProcess/ImageApplyBWBinaray.cpp index 3fee7dc7..45095dd3 100644 --- a/huagao/ImageProcess/ImageApplyBWBinaray.cpp +++ b/huagao/ImageProcess/ImageApplyBWBinaray.cpp @@ -36,10 +36,10 @@ void CImageApplyBWBinaray::apply(cv::Mat& pDib, int side) cv::cvtColor(pDib, pDib, cv::COLOR_BGR2GRAY); cv::Mat integ; - int blockSize = 13;//邻域尺寸 + int blockSize = 25;//邻域尺寸 int threshold = 1; - int low = 110; - int up = 230; + int low = 30; + int up = 235; int halfSize = blockSize / 2; int square_blockSize = blockSize * blockSize; switch (m_type) diff --git a/huagao/ImageProcess/ImageApplyBWBinaray.h b/huagao/ImageProcess/ImageApplyBWBinaray.h index 1f0442d7..d52675aa 100644 --- a/huagao/ImageProcess/ImageApplyBWBinaray.h +++ b/huagao/ImageProcess/ImageApplyBWBinaray.h @@ -4,10 +4,12 @@ * 鍔熻兘锛氫簩鍊煎寲澶勭悊 * 浣滆咃細鍒樹竵缁 * 鐢熸垚鏃堕棿锛2020/4/21 - * 鏈杩戜慨鏀规椂闂达細2020/5/28 v1.1 淇敼浼犵粺浜屽煎寲绠楁硶锛屾敼鐢ㄨ嚜瀹氫箟灞閮ㄨ嚜閫傚簲闃堝肩畻娉 - 2020/5/29 v1.2 鍦ㄤ紶缁熶簩鍊煎寲涔嬪墠娣诲姞澧炲己閿愬寲鏁堟灉锛屼簩鍊煎寲涔嬪悗澧炲姞闄ゅ櫔鏁堟灉 - 2020/6/19 v1.3 缂栧啓鑷畾涔夎嚜閫傚簲闃堝间簩鍊煎寲锛涘彇娑堥攼鍖栧鐞嗭紱淇濈暀闄ゅ櫔鏁堟灉 - * 鐗堟湰鍙凤細v1.3 + * 鏈杩戜慨鏀规椂闂达細2020/5/28 v1.1 淇敼浼犵粺浜屽煎寲绠楁硶锛屾敼鐢ㄨ嚜瀹氫箟灞閮ㄨ嚜閫傚簲闃堝肩畻娉 + 2020/5/29 v1.2 鍦ㄤ紶缁熶簩鍊煎寲涔嬪墠娣诲姞澧炲己閿愬寲鏁堟灉锛屼簩鍊煎寲涔嬪悗澧炲姞闄ゅ櫔鏁堟灉 + 2020/6/19 v1.3 缂栧啓鑷畾涔夎嚜閫傚簲闃堝间簩鍊煎寲锛涘彇娑堥攼鍖栧鐞嗭紱淇濈暀闄ゅ櫔鏁堟灉 + 2020/12/21 v1.3.1 璋冩暣鑷傚簲闃堝间笂涓嬮檺 + 2020/12/21 v1.3.2 璋冩暣blockSize,浠庡師鏉ョ殑51璋冩暣鍒25 + * 鐗堟湰鍙凤細v1.3.2 * ==================================================== */ diff --git a/huagao/ImageProcess/ImageApplyChannel.cpp b/huagao/ImageProcess/ImageApplyChannel.cpp index d4e7c6bb..6cb01173 100644 --- a/huagao/ImageProcess/ImageApplyChannel.cpp +++ b/huagao/ImageProcess/ImageApplyChannel.cpp @@ -1,49 +1,43 @@ #include "ImageApplyChannel.h" -//#include "ImageApplyAdjustColors.h" +#include "ImageApplyAdjustColors.h" + CImageApplyChannel::CImageApplyChannel() : m_channel(Invalid) - //, colors(new CImageApplyAdjustColors(0, 30, 1.0)) + , colors(new CImageApplyAdjustColors(0, 30, 1.0)) { } CImageApplyChannel::CImageApplyChannel(Channel channel) : m_channel(channel) - //,colors(new CImageApplyAdjustColors(0, 30, 1.0)) + , colors(new CImageApplyAdjustColors(0, 30, 1.0)) { } -CImageApplyChannel::~CImageApplyChannel(void) +CImageApplyChannel::~CImageApplyChannel() { - //if (colors != NULL) - //delete colors; + if (colors != nullptr) delete colors; } void CImageApplyChannel::apply(cv::Mat& pDib,int side) { -#ifdef LOG - FileTools::write_log("imgprc.txt", "enter CImageApplyChannel apply"); -#endif // LOG - - if (pDib.empty()) - { -#ifdef LOG - FileTools::write_log("imgprc.txt", "exit CImageApplyChannel apply"); -#endif // LOG - return; - } + (void)side; + if (pDib.empty()) return; cv::Mat dst(pDib.rows, pDib.cols, CV_8UC1); switch (m_channel) { case Red: cv::extractChannel(pDib, dst, 2); - //colors->apply(pDib, side); + colors->apply(pDib, side); break; case Green: cv::extractChannel(pDib, dst, 1); break; case Blue: cv::extractChannel(pDib, dst, 0); + break; + case All: + colourless(pDib, dst, 80); break; case Except_Red: except_channel(pDib, dst, 2); @@ -66,21 +60,20 @@ void CImageApplyChannel::apply(cv::Mat& pDib,int side) void CImageApplyChannel::apply(std::vector& mats, bool isTwoSide) { - if (mats.empty()) return; - - if (!mats[0].empty()) { - apply(mats[0], 0); - } - - if (isTwoSide && mats.size() > 1) { - if (!mats[1].empty()) - apply(mats[1], 1); + (void)isTwoSide; + int i = 0; + for (cv::Mat& var : mats) { + if (i != 0 && isTwoSide == false) + break; + if (!var.empty()) + apply(var, 0); + i++; } } void CImageApplyChannel::except_channel(const cv::Mat & src, cv::Mat & dst, int channel) { - int rows = src.total(); + int rows = static_cast(src.total()); cv::Mat src_temp(rows, 3, CV_8UC1, src.data); cv::Mat dst_temp(rows, 1, CV_8UC1, dst.data); @@ -90,19 +83,45 @@ void CImageApplyChannel::except_channel(const cv::Mat & src, cv::Mat & dst, int case 0: temp1 = src_temp(cv::Rect(1, 0, 1, rows)); temp2 = src_temp(cv::Rect(2, 0, 1, rows)); - cv::addWeighted(temp1, 0.84, temp2, 0.16, 0, dst_temp); + cv::addWeighted(temp1, 0.587, temp2, 0.299, 0, dst_temp); break; case 1: temp1 = src_temp(cv::Rect(0, 0, 1, rows)); temp2 = src_temp(cv::Rect(2, 0, 1, rows)); - cv::addWeighted(temp1, 0.73, temp2, 0.27, 0, dst_temp); + cv::addWeighted(temp1, 0.114, temp2, 0.299, 0, dst_temp); break; case 2: temp1 = src_temp(cv::Rect(0, 0, 1, rows)); temp2 = src_temp(cv::Rect(1, 0, 1, rows)); - cv::addWeighted(temp1, 0.33, temp2, 0.67, 0, dst_temp); + cv::addWeighted(temp1, 0.114, temp2, 0.587, 0, dst_temp); break; default: break; } } + +void CImageApplyChannel::colourless(const cv::Mat &src, cv::Mat &dst, uchar threshold) +{ + if (src.channels() != 3) + { + dst = src; + return; + } + + cv::Mat hsv; + cv::cvtColor(src, hsv, cv::COLOR_BGR2HSV_FULL); + cv::Mat mv_hsv[3]; + cv::split(hsv, mv_hsv); + size_t total = mv_hsv[1].total(); + uchar* ptr_s = mv_hsv[1].data; + uchar* ptr_v = mv_hsv[2].data; + for (size_t i = 0; i < total; i++) + if (ptr_s[i] > threshold) + { + ptr_s[i] = 0; + ptr_v[i] = 255; + } + cv::merge(mv_hsv, 3, hsv); + cv::cvtColor(hsv, hsv, cv::COLOR_HSV2BGR_FULL); + cv::cvtColor(hsv, dst, cv::COLOR_BGR2GRAY); +} diff --git a/huagao/ImageProcess/ImageApplyChannel.h b/huagao/ImageProcess/ImageApplyChannel.h index c703eade..39372210 100644 --- a/huagao/ImageProcess/ImageApplyChannel.h +++ b/huagao/ImageProcess/ImageApplyChannel.h @@ -1,21 +1,23 @@ #ifndef IMAGE_APPLY_CHANNEL_H #define IMAGE_APPLY_CHANNEL_H -#include "imageapply.h" -//class CImageApplyAdjustColors; -class CImageApplyChannel : public CImageApply +#include "ImageApply.h" + +class CImageApplyAdjustColors; +class CImageApplyChannel : public CImageApply { public: typedef enum channel { - Red, - Green, - Blue, - Invalid, - Except_Red, - Except_Green, - Except_Blue + Red, //红色通道 + Green, //绿色通道 + Blue, //蓝色通道 + All, //去除所有HSV色彩结构中,S大于80的色彩 + Invalid, //无效 + Except_Red, //绿蓝色通道混合 + Except_Green, //红蓝色通道混合 + Except_Blue //红绿色通道混合 }Channel; public: @@ -34,10 +36,12 @@ private: void except_channel(const cv::Mat& src, cv::Mat& dst, int channel); + void colourless(const cv::Mat& src, cv::Mat& dst, uchar threshold = 80); + private: Channel m_channel; - //CImageApplyAdjustColors* colors; + CImageApplyAdjustColors* colors; }; #endif // !IMAGE_APPLY_CHANNEL_H \ No newline at end of file diff --git a/huagao/ImageProcess/ImageApplyColorRecognition.cpp b/huagao/ImageProcess/ImageApplyColorRecognition.cpp index caded0ca..d85896b6 100644 --- a/huagao/ImageProcess/ImageApplyColorRecognition.cpp +++ b/huagao/ImageProcess/ImageApplyColorRecognition.cpp @@ -28,7 +28,7 @@ bool isColor(const cv::Mat& image) cv::inRange(hsv_channels[2], 100, 255, range_v); cv::Mat thre = (range_h1 | range_h2) & range_s & range_v; - return cv::sum(thre)[0] > 4; + return (cv::sum(thre)[0] / 255)> 4; } bool isGray(const cv::Mat& image) diff --git a/huagao/ImageProcess/ImageApplyConcatenation.cpp b/huagao/ImageProcess/ImageApplyConcatenation.cpp index 4e417507..d7d0b9ed 100644 --- a/huagao/ImageProcess/ImageApplyConcatenation.cpp +++ b/huagao/ImageProcess/ImageApplyConcatenation.cpp @@ -2,11 +2,13 @@ CImageApplyConcatenation::CImageApplyConcatenation() : m_direction(autoDirection) + , m_BG_color(0, 0, 0) { } -CImageApplyConcatenation::CImageApplyConcatenation(ConcatMode dir) +CImageApplyConcatenation::CImageApplyConcatenation(ConcatMode dir, const cv::Scalar& background) : m_direction(dir) + , m_BG_color(background) { } @@ -44,6 +46,7 @@ cv::Mat CImageApplyConcatenation::concat(cv::Mat &front, cv::Mat &back, ConcatMo cv::Mat dst; if (direction == horizontal) { +#if 0 int top, bottom; if (front.rows > back.rows) { @@ -58,9 +61,21 @@ cv::Mat CImageApplyConcatenation::concat(cv::Mat &front, cv::Mat &back, ConcatMo cv::copyMakeBorder(front, front, top, bottom, 0, 0, cv::BORDER_CONSTANT); } cv::hconcat(front, back, dst); +#else + int width = cv::max(front.cols, back.cols) * 2; + int height = cv::max(front.rows, back.rows); + + dst = cv::Mat(height, width, front.type(), m_BG_color); + front.copyTo(dst(cv::Rect(0, 0, front.cols, front.rows))); + int offset = front.cols; + front.release(); + back.copyTo(dst(cv::Rect(offset, 0, back.cols, back.rows))); + back.release(); +#endif } else if (direction == vertical) { +#if 0 int left, right; if (front.cols > back.cols) { @@ -75,6 +90,17 @@ cv::Mat CImageApplyConcatenation::concat(cv::Mat &front, cv::Mat &back, ConcatMo cv::copyMakeBorder(front, front, 0, 0, left, right, cv::BORDER_CONSTANT); } cv::vconcat(front, back, dst); +#else + int width = cv::max(front.cols, back.cols); + int height = cv::max(front.rows, back.rows) * 2; + + dst = cv::Mat(height, width, front.type(), m_BG_color); + front.copyTo(dst(cv::Rect(0, 0, front.cols, front.rows))); + int offset = front.rows; + front.release(); + back.copyTo(dst(cv::Rect(0, offset, back.cols, back.rows))); + back.release(); +#endif } return dst; } diff --git a/huagao/ImageProcess/ImageApplyConcatenation.h b/huagao/ImageProcess/ImageApplyConcatenation.h index 6e7d6e8d..c4ec540b 100644 --- a/huagao/ImageProcess/ImageApplyConcatenation.h +++ b/huagao/ImageProcess/ImageApplyConcatenation.h @@ -1,3 +1,15 @@ +/* + * ==================================================== + + * 功能:拼接,又名对折 + * 作者:刘丁维 + * 生成时间:2020/4/21 + * 最近修改时间:2020/4/29 + * 版本号:v1.0 2020/4/21 + * 版本号:v1.1 2020/4/29 : 1、添加m_BG_color接口,可设置图片背景;2、优化内存消耗 + * ==================================================== + */ + #ifndef IMAGE_APPLY_CONCATENATION_H #define IMAGE_APPLY_CONCATENATION_H @@ -17,15 +29,23 @@ public: public: CImageApplyConcatenation(); //默认m_direction = autoDirection; - CImageApplyConcatenation(ConcatMode dir); + /* + * dir [in]:拼接方向 + * backgroud [in]:背景颜色,默认为黑色 + * */ + CImageApplyConcatenation(ConcatMode dir, const cv::Scalar& backgroud = cv::Scalar(0, 0, 0)); virtual ~CImageApplyConcatenation(void); virtual void apply(std::vector& mats, bool isTwoSide); - inline ConcatMode getConcatDirection() { return m_direction; } + inline ConcatMode getConcatDirection() { return m_direction; } - inline void setFildDirection(ConcatMode dir) { m_direction = dir; } + inline void setFildDirection(ConcatMode dir) { m_direction = dir; } + + inline cv::Scalar getBackGroundColor() const { return m_BG_color; } + + inline void setBackGroundColor(const cv::Scalar& color) { m_BG_color = color; } private: @@ -35,6 +55,7 @@ private: private: ConcatMode m_direction; + cv::Scalar m_BG_color; }; #endif // !IMAGE_APPLY_CONCATENATION_H diff --git a/huagao/ImageProcess/ImageApplyDiscardBlank.cpp b/huagao/ImageProcess/ImageApplyDiscardBlank.cpp index 81a7e846..4f0f1561 100644 --- a/huagao/ImageProcess/ImageApplyDiscardBlank.cpp +++ b/huagao/ImageProcess/ImageApplyDiscardBlank.cpp @@ -1,10 +1,16 @@ #include "ImageApplyDiscardBlank.h" #include "ImageProcess_Public.h" #include "filetools.h" +CImageApplyDiscardBlank::CImageApplyDiscardBlank(int blockSize, int devTh) + : m_res(false) + , m_dSize(blockSize) + , m_devTh(devTh) +{ +} CImageApplyDiscardBlank::CImageApplyDiscardBlank() : m_res(false) - , dSize(200) - , devTh(15, 15, 15, 15) + , m_dSize(200) + , m_devTh(15, 15, 15, 15) { } @@ -95,8 +101,8 @@ int CImageApplyDiscardBlank::processRectR(const cv::Mat& image, cv::RotatedRect& void CImageApplyDiscardBlank::setIntensity(int val) { - val = cv::max(cv::min(100, val), 1); - devTh = cv::Scalar(val, val, val, val); + val = cv::max(cv::min(100, val), 2); + m_devTh = cv::Scalar::all(val); } cv::Mat CImageApplyDiscardBlank::getRoiMat(const cv::Mat& image) @@ -107,12 +113,14 @@ cv::Mat CImageApplyDiscardBlank::getRoiMat(const cv::Mat& image) 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) + 20; + 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); + + if (inRect.width <= 0 || inRect.height <= 0) + return cv::Mat(); return image(inRect); } @@ -135,18 +143,18 @@ void CImageApplyDiscardBlank::apply(cv::Mat& pDib, int side) 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) + 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,dSize, dSize) & imRect; + rect = cv::Rect(i, j, m_dSize, m_dSize) & imRect; if(rect != cv::Rect()) { cv::meanStdDev (image(rect) , mean, dev); - if(!scalar_LE(dev, devTh)) + if(!scalar_LE(dev, m_devTh)) { m_res = false; #ifdef LOG - FileTools::write_log("D:\\imgprc.txt", "CImageApplyDiscardBlank blank"); + FileTools::write_log("imgprc.txt", "exit CImageApplyDiscardBlank apply"); #endif // LOG return; } @@ -172,3 +180,30 @@ void CImageApplyDiscardBlank::apply(std::vector& mats, bool isTwoSide) 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; +} diff --git a/huagao/ImageProcess/ImageApplyDiscardBlank.h b/huagao/ImageProcess/ImageApplyDiscardBlank.h index f1822dcc..2fad4703 100644 --- a/huagao/ImageProcess/ImageApplyDiscardBlank.h +++ b/huagao/ImageProcess/ImageApplyDiscardBlank.h @@ -19,6 +19,8 @@ class CImageApplyDiscardBlank : public CImageApply { public: + CImageApplyDiscardBlank(int blockSize, int devTh); + /* * isnormal [in]:true标准模式,false为票据复写纸模式 * */ @@ -32,21 +34,23 @@ public: void setIntensity(int val); - void setMinArea(int val) { dSize = val; } + void setMinArea(int val) { m_dSize = val; } + + static bool apply(const cv::Mat& pDib, int blockSize = 200, int devTh = 15); private: - int processRectR(const cv::Mat& image, cv::RotatedRect& rotatedRect, std::vector& maxContour, + static int processRectR(const cv::Mat& image, cv::RotatedRect& rotatedRect, std::vector& maxContour, double scale, double thresh, int blobAreaSize); - bool scalar_LE(const cv::Scalar& val1, const cv::Scalar& val2); + static bool scalar_LE(const cv::Scalar& val1, const cv::Scalar& val2); - cv::Mat getRoiMat(const cv::Mat& pDib); + static cv::Mat getRoiMat(const cv::Mat& pDib); private: bool m_res; - bool isNormalDiscard; - int dSize; - cv::Scalar devTh; + bool m_isNormalDiscard; + int m_dSize; + cv::Scalar m_devTh; }; #endif // !IMAGE_APPLY_DISCARD_BLANK_H \ No newline at end of file diff --git a/huagao/ImageProcess/ImageApplyOutHole.cpp b/huagao/ImageProcess/ImageApplyOutHole.cpp index 3cde1b59..c9945e68 100644 --- a/huagao/ImageProcess/ImageApplyOutHole.cpp +++ b/huagao/ImageProcess/ImageApplyOutHole.cpp @@ -25,7 +25,11 @@ CImageOutHole::~CImageOutHole(void) { } -void CImageOutHole::apply(cv::Mat& pDib, int side) {} +void CImageOutHole::apply(cv::Mat& pDib, int side) +{ + (void)pDib; + (void)side; +} void CImageOutHole::apply(std::vector& mats, bool isTwoSide) { @@ -99,8 +103,8 @@ void CImageOutHole::apply(std::vector& mats, bool isTwoSide) //过滤非孔洞的联通区域 std::vector> hole_contours = filterPoly(contours_mask, b1_mask, mask_rotatedRect, m_edgeScale, m_borderSize); - for (int i = 0; i < hole_contours.size(); i++) - cv::drawContours(mask, hole_contours, i, cv::Scalar(127), 2); + for (size_t i = 0; i < hole_contours.size(); i++) + cv::drawContours(mask, hole_contours, static_cast(i), cv::Scalar(127), 2); for (size_t i = 0; i < hole_contours.size(); i++) { @@ -247,5 +251,7 @@ cv::Scalar CImageOutHole::getBackGroudColor(const cv::Mat &image, const std::vec temp[j] += ptr[j]; } - return cv::Scalar(temp[0] / pixelPoints.size(), temp[1] / pixelPoints.size(), temp[2] / pixelPoints.size()); + return cv::Scalar(temp[0] / static_cast(pixelPoints.size()), + temp[1] / static_cast(pixelPoints.size()), + temp[2] / static_cast(pixelPoints.size())); } diff --git a/huagao/ImageProcess/ImageApplyOutHole.h b/huagao/ImageProcess/ImageApplyOutHole.h index 20aebb4e..9ed49b3f 100644 --- a/huagao/ImageProcess/ImageApplyOutHole.h +++ b/huagao/ImageProcess/ImageApplyOutHole.h @@ -26,7 +26,7 @@ public: void setEdgeScale(float scale) { m_edgeScale = scale; } - void setThreshold(double threshold) { m_threshold = std::min(std::max(threshold, 1.0), 254.0); } + void setThreshold(double threshold) { m_threshold = (std::min)((std::max)(threshold, 1.0), 254.0); } private: diff --git a/huagao/ImageProcess/ImageApplyResize.cpp b/huagao/ImageProcess/ImageApplyResize.cpp index 34073789..3405eaaa 100644 --- a/huagao/ImageProcess/ImageApplyResize.cpp +++ b/huagao/ImageProcess/ImageApplyResize.cpp @@ -23,37 +23,25 @@ CImageApplyResize::~CImageApplyResize(void) void CImageApplyResize::apply(cv::Mat& pDib,int side) { -#ifdef LOG - FileTools::write_log("imgprc.txt", "enter CImageApplyResize apply"); -#endif // LOG - - if (pDib.empty()) - { -#ifdef LOG - FileTools::write_log("imgprc.txt", "exit CImageApplyResize apply"); -#endif // LOG - return; - } + (void)side; + if (pDib.empty()) return; if (m_type == ResizeType::RATIO) cv::resize(pDib, pDib, cv::Size(0, 0), m_fx, m_fy); else - cv::resize(pDib, pDib, m_dSize); -#ifdef LOG - FileTools::write_log("imgprc.txt", "exit CImageApplyResize apply"); -#endif // LOG + cv::resize(pDib, pDib, m_dSize); } void CImageApplyResize::apply(std::vector& mats, bool isTwoSide) { - if (mats.empty()) return; + (void)isTwoSide; - if (!mats[0].empty()) { - apply(mats[0], 0); - } - - if (isTwoSide && mats.size() > 1) { - if (!mats[1].empty()) - apply(mats[1], 1); + int i = 0; + for (cv::Mat& var : mats) { + if (i != 0 && isTwoSide == false) + break; + if (!var.empty()) + apply(var, 0); + i++; } } diff --git a/huagao/ImageProcess/ImageApplyResize.h b/huagao/ImageProcess/ImageApplyResize.h index 6b694bb6..c4dad8b1 100644 --- a/huagao/ImageProcess/ImageApplyResize.h +++ b/huagao/ImageProcess/ImageApplyResize.h @@ -16,6 +16,12 @@ public: public: CImageApplyResize(); + /* + * type [in]:缩放类型 + * size [in]:目标尺寸,当type为DSIZE时生效 + * fx [in]:横向目标比例,当type为RATIO时生效 + * fy [in]:纵向目标比例,当type为RATIO时生效 + */ CImageApplyResize(ResizeType type, const cv::Size& size, double fx, double fy); virtual ~CImageApplyResize(void); diff --git a/huagao/ImageProcess/ImageApplyRotation.h b/huagao/ImageProcess/ImageApplyRotation.h index 0e86e1d4..2c706318 100644 --- a/huagao/ImageProcess/ImageApplyRotation.h +++ b/huagao/ImageProcess/ImageApplyRotation.h @@ -1,3 +1,16 @@ +/* + * ==================================================== + + * 功能:旋转图像 + * 作者:刘丁维 + * 生成时间:2020/4/21 + * 最近修改时间:v1.0 2020/4/21 + v1.1 2020/8/12 修复文稿方向自动识别导致崩溃的BUG + * 版本号:v1.1 + + * ==================================================== + */ + #ifndef IMAGE_APPLY_ROTATION_H #define IMAGE_APPLY_ROTATION_H @@ -8,16 +21,22 @@ class CImageApplyRotation : public CImageApply public: enum class RotationType { - Invalid, - Rotate_90_clockwise, - Rotate_180, - Rotate_90_anti_clockwise, + Invalid, //无效 + Rotate_90_clockwise, //顺时针90° + Rotate_180, //180° + Rotate_90_anti_clockwise, //逆时针90°,即270° - AutoTextOrientation + AutoTextOrientation //自动文稿方向识别旋转 }; public: + /* + * rotation [in]:旋转类型 + * isBackTransposed [in]:true为背面180°旋转,反之亦然 + * dpi [in]:当前图像的DPI,该参数在rotation为AutoTextOrientation时生效。在识别文稿方向时,会默认将图像变换为200DPI进行识别 + * tessadataPath [in]:训练库文件路径,该参数在rotation为AutoTextOrientation时生效 + */ CImageApplyRotation(RotationType rotation, bool isBackTransposed = false, int dpi = 200, const char* tessdataPath = nullptr); virtual ~CImageApplyRotation(); diff --git a/huagao/ImageProcess/ImageProcess_Public.cpp b/huagao/ImageProcess/ImageProcess_Public.cpp index 9634693f..54ecc216 100644 --- a/huagao/ImageProcess/ImageProcess_Public.cpp +++ b/huagao/ImageProcess/ImageProcess_Public.cpp @@ -21,8 +21,7 @@ namespace hg //dst dst.clear(); - int hullCount = hull->total; - for (int i = 0; i < hullCount; i++) + for (int i = 0, hullCount = hull->total; i < hullCount; i++) dst.push_back(**CV_GET_SEQ_ELEM(CvPoint*, hull, i)); //storage @@ -297,7 +296,7 @@ namespace hg cv::threshold(src, dst, thre, 255, cv::THRESH_BINARY); } - cv::Point warpPoint(cv::Point p, const cv::Mat& warp_mat) + cv::Point warpPoint(const cv::Point& p, const cv::Mat& warp_mat) { double src_data[3] = { static_cast(p.x), static_cast(p.y), 1 }; cv::Mat src(3, 1, warp_mat.type(), src_data); //warp_mat.type() == CV_64FC1 @@ -306,4 +305,20 @@ namespace hg double* ptr = reinterpret_cast(dst.data); return cv::Point(static_cast(ptr[0]), static_cast(ptr[1])); } + + int distanceP2P(const cv::Point& p1, const cv::Point& p2) + { + return cv::sqrt(cv::pow(p1.x - p2.x, 2) + cv::pow(p1.y - p2.y, 2)); + } + + float distanceP2L(const cv::Point& p, const cv::Point& l1, const cv::Point& l2) + { + //求直线方程 + int A = 0, B = 0, C = 0; + A = l1.y - l2.y; + B = l2.x - l1.x; + C = l1.x * l2.y - l1.y * l2.x; + //代入点到直线距离公式 + return ((float)abs(A * p.x + B * p.y + C)) / ((float)sqrtf(A * A + B * B)); + } } \ No newline at end of file diff --git a/huagao/ImageProcess/ImageProcess_Public.h b/huagao/ImageProcess/ImageProcess_Public.h index db792cfd..94c7b8af 100644 --- a/huagao/ImageProcess/ImageProcess_Public.h +++ b/huagao/ImageProcess/ImageProcess_Public.h @@ -1,3 +1,15 @@ +/* + * ==================================================== + + * 功能:公共图像处理算法。部分功能可能会在ImageProcess里面多个类反复使用 + * 作者:刘丁维 + * 生成时间:2020/4/21 + * 最近修改时间:2020/4/21 + * 版本号:v1.0 + + * ==================================================== + */ + #ifndef IMAGE_PROCESS_PUBLIC_H #define IMAGE_PROCESS_PUBLIC_H @@ -6,28 +18,106 @@ namespace hg { + /* + * 功能:计算源点集的凸多边形轮廓,输出轮廓点集 + * src: 源点集 + * dst: 目标点集 + * clockwise: true为顺时针排序,false为逆时针排序 + */ void convexHull(const std::vector& src, std::vector& dst, bool clockwise = false); + /* + * 功能:填充凸多边形,默认颜色为白色 + * image: 填充图像 + * points: 凸多边形轮廓点集(逆时针排序) + */ void fillConvexHull(cv::Mat& image, const std::vector& points); + /* + * 功能:填充凹多边形 + * image: 填充图像 + * contours: 凹多边形轮廓点集(逆时针排序) + * color: 填充颜色 + */ void fillPolys(cv::Mat& image, const std::vector>& contours, const cv::Scalar& color); + /* + * 功能:获取连通区域轮廓 + * src: 源图像 + * contours: 结果轮廓集 + * hierarchy: 轮廓集的排序关系。与contours的数量对应,受retr选项不同,排序会有变化 + * retr: 轮廓集排序方式,默认为链式排序 + * method: 查找算法选择,默认为普通查找 + * offset: 查找起始点,默认为(0,0)点 + */ void findContours(const cv::Mat& src, std::vector>& contours, std::vector& hierarchy, int retr = cv::RETR_LIST, int method = cv::CHAIN_APPROX_SIMPLE, cv::Point offset = cv::Point(0, 0)); cv::RotatedRect getBoundingRect(const std::vector& contour); + /* + * 功能: 获取覆盖轮廓集的最小外接凸多边形轮廓 + * contours: 轮廓集(每个轮廓由点集组成) + * hierarchy: 轮廓集中,轮廓之间的关系。数量与contours对应 + * 返回值: 凸多边形轮廓点集 + */ std::vector getMaxContour(const std::vector>& contours, const std::vector& hierarchy); + /* + * 功能: 获取覆盖轮廓集的最小外接凸多边形轮廓 + * contours: 轮廓集(每个轮廓由点集组成) + * hierarchy: 轮廓集中,轮廓之间的关系。数量与contours对应 + * 返回值: 凸多边形轮廓点集 + */ std::vector getVertices(const cv::RotatedRect& rect); + /* + * 功能: 轮廓缩进 + * points: 轮廓点集 + * center: 围绕center点缩进 + * indent: 缩进像素 + */ void polyIndent(std::vector& points, const cv::Point& center, int indent); + /* + * 功能: 二值化,能够处理彩色和灰度图像。src为彩色图像时,灰度图取三个通道的最大值 + * src: 源图 + * dst: 目标图 + * thre: 阈值 + */ void threshold_Mat(const cv::Mat& src, cv::Mat& dst, double thre); + /* + * 功能: 彩色转灰度,灰度图取三个通道的最大值 + * src: 源图 + * 返回值: 灰度图 + */ cv::Mat transforColor(const cv::Mat& src); - cv::Point warpPoint(cv::Point p, const cv::Mat& warp_mat); + /* + * 功能: 获取点的仿射变换 + * p: 原点 + * warp_mat: 仿射变换系数矩阵 + * 返回值: 变换后的点 + */ + cv::Point warpPoint(const cv::Point& p, const cv::Mat& warp_mat); + + /* + * 功能: 点到点距离 + * p1: 点1 + * p2: 点2 + * 返回值: 点到点距离 + */ + int distanceP2P(const cv::Point& p1, const cv::Point& p2); + + /* + * 功能: 点到直线距离 + * p: 点 + * l1: 直线端点1 + * l2: 直线端点2 + * 返回值: 点到直线距离 + */ + float distanceP2L(const cv::Point& p, const cv::Point& l1, const cv::Point& l2); } #endif // !IMAGE_PROCESS_C_H diff --git a/huagao/huagaods.cpp b/huagao/huagaods.cpp index 782b5d0e..c9c3576a 100644 --- a/huagao/huagaods.cpp +++ b/huagao/huagaods.cpp @@ -70,7 +70,7 @@ using namespace std::placeholders; TWPP_ENTRY_MFC(HuagaoDs) static constexpr const Identity srcIdent( - Version(3, 3, Language::English, Country::China, "v3.3.2.4"), + Version(3, 3, Language::English, Country::China, "v3.3.4.1"), DataGroup::Image, #ifdef MAKEHUAGAO "HUAGO", @@ -2919,6 +2919,8 @@ Twpp::Result HuagaoDs::startScan() scanner->ResetScanner(); std::string info = "\n m_scanparam->is_autocrop :" + to_string(m_scanparam->is_autocrop); + info += "\n m_scanparam->colorenable :" + to_string(m_scanparam->automaticcolor); + info += "\n m_scanparam->colorenabletype :" + to_string(m_scanparam->automaticcolortype); info += "\n m_scanparam->papertype :" + to_string(m_scanparam->papertype); info += "\n m_scanparam->fillbackground :" + to_string(m_scanparam->fillbackground); info += "\n m_scanparam->autodescrew :" + to_string(m_scanparam->autodescrew); diff --git a/huagao/stdafx.h b/huagao/stdafx.h index 1753bc5cae2bdf51208c13df7959c1d125ff0287..46db6d3080fc94df43ab6aa7863d249534c2f793 100644 GIT binary patch delta 40 ycmV+@0N4MLRFYJ%wg?3@05AYBlYs#lv(yNX1OYLVVHBN`5F(Qx751|l5BM4mrVVTW delta 40 ycmV+@0N4MLRFYJ%wg?3>05AYBlYs#lv(yNX1OYOWVHBN`5F(Qx751|l5BM4mcMWR*