From 7e4bcca9df9ca18b8d72805dc4bbb018f147336a Mon Sep 17 00:00:00 2001 From: masayume_ht <1936714878@qq.com> Date: Sat, 14 Aug 2021 17:35:01 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=89=AB=E6=8F=8F=E5=8F=96?= =?UTF-8?q?=E5=9B=BE=E6=B5=81=E7=A8=8B=EF=BC=8C=E5=88=A0=E9=99=A4=E9=83=A8?= =?UTF-8?q?=E5=88=86=E4=B8=8D=E5=BF=85=E8=A6=81=E5=8D=8F=E8=AE=AE=E4=BA=A4?= =?UTF-8?q?=E4=BA=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- huagao/Device/GScanO1003399.cpp | 57 ++++++++-------- huagao/Device/IConfig.h | 3 + huagao/Device/UsbScanEx.cpp | 12 +++- .../ImageProcess/ImageApplyDiscardBlank.cpp | 66 ++++++++++++++----- huagao/ImageProcess/ImageApplyDiscardBlank.h | 19 ++++-- huagao/ImageProcess/ImageApplyRotation.cpp | 42 +++++++++++- 6 files changed, 140 insertions(+), 59 deletions(-) diff --git a/huagao/Device/GScanO1003399.cpp b/huagao/Device/GScanO1003399.cpp index 11ef92b0..65c4b352 100644 --- a/huagao/Device/GScanO1003399.cpp +++ b/huagao/Device/GScanO1003399.cpp @@ -125,7 +125,7 @@ int GScanO1003399::aquire_bmpdata(std::vector& bmpdata) StopWatch sw; while (true) { - if ((imagecount == 0) && (!is_runing()) && (!scanflag) || (sw.elapsed_s() > 30)) + if ((imagecount == 0) && (!scanflag) || (sw.elapsed_s() > 30)) { DoEvents(); this_thread::sleep_for(chrono::milliseconds(1)); @@ -138,7 +138,7 @@ int GScanO1003399::aquire_bmpdata(std::vector& bmpdata) set_scannum(abs(roller_num_new - roller_num)); return AQUIRE_IMAGE_TIMEOUT; } - if (!is_runing()) + if (!scanflag) { int roller_num_new = count(); set_scannum(abs(roller_num_new - roller_num)); @@ -213,8 +213,8 @@ bool GScanO1003399::is_scan() BOOL GScanO1003399::Get_Scanner_PaperOn() { - //return scanner_read_reg(m_usb, SR_PAPER_READY); - return true; + return scanner_read_reg(m_usb, SR_GET_PAPERON); + //return true; } int GScanO1003399::Get_Roller_num() @@ -332,13 +332,13 @@ void GScanO1003399::Scanner_StartScan(UINT16 count) keeplastimg = true; reset(); devState = DEV_ISRUNNING; - //if (scanner_read_reg(m_usb, SR_GET_SLEEP_STAUTUS) != 1) - //{ - // devState = DEV_WRONG; - // Set_ErrorCode(SLEEPING); - // scanflag = false; - // return; - //} + if (scanner_read_reg(m_usb, SR_GET_SLEEP_STAUTUS) != 1) + { + devState = DEV_WRONG; + Set_ErrorCode(SLEEPING); + scanflag = false; + return; + } if (scan_mode()) { devState = DEV_WRONG; @@ -346,12 +346,13 @@ void GScanO1003399::Scanner_StartScan(UINT16 count) scanflag = false; return; } - //if (!Get_Scanner_PaperOn()) - //{ - // devState = DEV_WRONG; - // Set_ErrorCode(NO_FEED); - // return; - //} + if (!Get_Scanner_PaperOn()) + { + devState = DEV_WRONG; + Set_ErrorCode(NO_FEED); + scanflag = false; + return; + } start(); bool procmode = (m_param.resolution_dst > 200.0f || m_param.papertype == 52 || m_param.papertype == 54 || m_param.papertype == 131); @@ -505,14 +506,14 @@ void GScanO1003399::usb_run() if ((codeconvter(info) == -1)) { - if ((get_ErrorCode() != PAPER_JAM) && (get_ErrorCode() != DETECT_DOUBLE_FEED) && (get_ErrorCode() != DETECT_STAPLE)) - { - keeplastimg = false; - while (im_dev_count()) - im_rx(); - scanflag = false; - } - else { + //if ((get_ErrorCode() != PAPER_JAM) && (get_ErrorCode() != DETECT_DOUBLE_FEED) && (get_ErrorCode() != DETECT_STAPLE)) + //{ + // keeplastimg = false; + // while (im_dev_count()) + // im_rx(); + // scanflag = false; + //} + //else { while (!scanner_read_reg(m_usb, SR_GET_IMAGEPROCESSDONE)) this_thread::sleep_for(chrono::microseconds(30)); if (scanner_read_reg(m_usb, SR_GET_KEEP_LAST_PAPER)) @@ -531,7 +532,7 @@ void GScanO1003399::usb_run() im_rx(); } scanflag = false; - } + //} if ((devState != DEV_WRONG) && (get_ErrorCode()<=0)) devState = DEV_STOP; @@ -668,7 +669,7 @@ int GScanO1003399::read_data(void* data, int length, int timeout) FileTools::writelog(log_INFO, "if (!m_usb.get() && !m_usb->is_connected())"); return 0; } - timeout = std::max(500, timeout); + timeout = std::max(1000, timeout); int readed = 0; int reading = 0; @@ -739,7 +740,6 @@ void GScanO1003399::imgproce(std::shared_ptr>& buff) FileTools::writelog(log_ERROR, e.what()); } } - FileTools::writelog(log_DEBUG, "图像解码耗时 " + to_string(sw.elapsed_ms())); sw.reset(); buffs.clear(); if (m_param.is_autotext) @@ -771,7 +771,6 @@ void GScanO1003399::imgproce(std::shared_ptr>& buff) CImageApplyRotation(type, m_param.is_backrotate180, m_param.resolution_dst, chRtn).apply(mats,m_param.is_duplex); delete[] chRtn; } - FileTools::writelog(log_DEBUG, "图像旋转耗时 " + to_string(sw.elapsed_ms())); if (m_param.automaticcolor) { CImageApplyColorRecognition(m_param.automaticcolortype == 1 ? CImageApplyColorRecognition::ColorRecognitionMode::Color_Gray : CImageApplyColorRecognition::ColorRecognitionMode::Color_Mono).apply(mats,m_param.is_duplex); diff --git a/huagao/Device/IConfig.h b/huagao/Device/IConfig.h index 75a0205b..1958ff0e 100644 --- a/huagao/Device/IConfig.h +++ b/huagao/Device/IConfig.h @@ -181,6 +181,9 @@ enum Scanner_Reg_Defs SR_GET_SLEEP_STAUTUS, SR_GET_IMAGEPROCESSDONE, SR_GET_KEEP_LAST_PAPER, + SR_GET_PAPERON, + SR_SET_SPEEDMODE, + SR_GET_SPEEDMODE, SR_GET_CUO_ERROR = 0x50, SR_GET_DOU_ERROR, SR_GET_JAM_ERROR, diff --git a/huagao/Device/UsbScanEx.cpp b/huagao/Device/UsbScanEx.cpp index 8b1d520b..dc382834 100644 --- a/huagao/Device/UsbScanEx.cpp +++ b/huagao/Device/UsbScanEx.cpp @@ -166,9 +166,13 @@ int UsbScanEx::read_bulk(void* data, int len) int error_code = GetLastError(); switch (error_code) { - case ERROR_IO_PENDING: - GetOverlappedResult(h_pipe, lp_overlap, &pdw_ret, TRUE); + case ERROR_IO_PENDING: { + auto ret = WaitForSingleObject(lp_overlap->hEvent, 300); + //FileTools::writelog(log_FATAL, "WaitForSingleObject return " + std::to_string(ret));; + GetOverlappedResult(h_pipe, lp_overlap, &pdw_ret, FALSE); + //GetOverlappedResult(h_pipe, lp_overlap, &pdw_ret, TRUE); return pdw_ret; + } case ERROR_FILE_NOT_FOUND: case ERROR_ACCESS_DENIED: m_b_is_connected = false; @@ -206,7 +210,9 @@ int UsbScanEx::write_bulk(void* data, int len) switch (GetLastError()) { case ERROR_IO_PENDING: - GetOverlappedResult(h_pipe, lp_overlap, &dw_size, TRUE); + WaitForSingleObject(lp_overlap->hEvent, 500); + GetOverlappedResult(h_pipe, lp_overlap, &dw_size, FALSE); + //GetOverlappedResult(h_pipe, lp_overlap, &dw_size, TRUE); return dw_size; case ERROR_FILE_NOT_FOUND: case ERROR_ACCESS_DENIED: diff --git a/huagao/ImageProcess/ImageApplyDiscardBlank.cpp b/huagao/ImageProcess/ImageApplyDiscardBlank.cpp index f7d144cc..ef23b506 100644 --- a/huagao/ImageProcess/ImageApplyDiscardBlank.cpp +++ b/huagao/ImageProcess/ImageApplyDiscardBlank.cpp @@ -1,17 +1,26 @@ #include "ImageApplyDiscardBlank.h" #include "ImageProcess_Public.h" -#include "filetools.h" + +CImageApplyDiscardBlank::CImageApplyDiscardBlank() + : m_res(false) + , m_dSize(20) + , m_devTh(15, 15, 15, 15) +{ +} + CImageApplyDiscardBlank::CImageApplyDiscardBlank(int blockSize, int devTh) : m_res(false) , m_dSize(blockSize) , m_devTh(devTh) { } -CImageApplyDiscardBlank::CImageApplyDiscardBlank() + +CImageApplyDiscardBlank::CImageApplyDiscardBlank(bool isnormal) : m_res(false) - , m_dSize(200) - , m_devTh(15, 15, 15, 15) + , m_isNormalDiscard(isnormal) { + m_dSize = m_isNormalDiscard ? 200 : 300; + m_devTh = m_isNormalDiscard ? cv::Scalar::all(8) : cv::Scalar::all(20); } CImageApplyDiscardBlank::~CImageApplyDiscardBlank(void) @@ -76,6 +85,13 @@ int CImageApplyDiscardBlank::processRectR(const cv::Mat& image, cv::RotatedRect& rotatedRect.size.width = rotatedRect.size.height; rotatedRect.size.height = l_temp; } + 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); @@ -91,7 +107,7 @@ int CImageApplyDiscardBlank::processRectR(const cv::Mat& image, cv::RotatedRect& return blockCount; } - bool CImageApplyDiscardBlank::scalar_LE(const cv::Scalar& val1, const cv::Scalar& val2) +bool CImageApplyDiscardBlank::scalar_LE(const cv::Scalar& val1, const cv::Scalar& val2) { for (int i = 0; i < 3; i++) if (val1[i] > val2[i]) @@ -101,7 +117,7 @@ int CImageApplyDiscardBlank::processRectR(const cv::Mat& image, cv::RotatedRect& void CImageApplyDiscardBlank::setIntensity(int val) { - val = cv::max(cv::min(100, val), 2); + val = cv::max(cv::min(100, val), 2); m_devTh = cv::Scalar::all(val); } @@ -116,36 +132,46 @@ cv::Mat CImageApplyDiscardBlank::getRoiMat(const cv::Mat& image) 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) + if (inRect.width <= 0 || inRect.height <= 0) return cv::Mat(); 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; } - cv::Scalar mean; - cv::Scalar dev; + 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) + 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()) + 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)) + 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; } } @@ -153,11 +179,14 @@ void CImageApplyDiscardBlank::apply(cv::Mat& pDib, int side) 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; + (void)isTwoSide; int i = 0; for (cv::Mat& var : mats) { if (i != 0 && isTwoSide == false) @@ -177,7 +206,7 @@ bool CImageApplyDiscardBlank::apply(const cv::Mat& pDib, int blockSize, int devT cv::Scalar dev; cv::Scalar s_devTh = cv::Scalar::all(devTh); cv::Mat image = getRoiMat(pDib); - if (image.empty()) + if (image.empty()) return false; cv::Rect rect; cv::Rect imRect(0, 0, image.cols, image.rows); @@ -194,3 +223,4 @@ bool CImageApplyDiscardBlank::apply(const cv::Mat& pDib, int blockSize, int devT } return true; } + diff --git a/huagao/ImageProcess/ImageApplyDiscardBlank.h b/huagao/ImageProcess/ImageApplyDiscardBlank.h index 2fad4703..da86352e 100644 --- a/huagao/ImageProcess/ImageApplyDiscardBlank.h +++ b/huagao/ImageProcess/ImageApplyDiscardBlank.h @@ -5,8 +5,13 @@ * 作者:刘丁维 * 生成时间:2020/4/21 * 最近修改时间:2020/4/21 v1.0 - 2020/8/12 v1.1 开放setIntensity和setMinArea;取消isNormal标识位;扩大setIntensity的设置范围,从[2, 20]扩大到[1, 100] - * 版本号:v1.1 + 2020/8/12 v1.1 开放setIntensity和setMinArea;取消isNormal标识位;扩大setIntensity的设置范围,从[2, 20]扩大到[1, 100] + 2020/8/25 v1.1.1 纸张检测缩进,从100像素调整到20像素 + 2020/10/16 v1.2 添加新接口,能够高效便捷判断图片是否为空白页 + 2020/10/19 v1.2.1 修复静态空白页判断识别误判的BUG + 2021/04/13 v1.3.0 增加标准/票据标识位 + 2021/08/12 v1.3.1 添加防止不同opencv版本导致计算结果存在差异的代码。 + * 版本号:v1.3.1 * ==================================================== */ @@ -19,16 +24,18 @@ class CImageApplyDiscardBlank : public CImageApply { public: + CImageApplyDiscardBlank(); + CImageApplyDiscardBlank(int blockSize, int devTh); /* * isnormal [in]:true标准模式,false为票据复写纸模式 * */ - CImageApplyDiscardBlank(); + CImageApplyDiscardBlank(bool isnormal); virtual ~CImageApplyDiscardBlank(void); - virtual void apply(cv::Mat& pDib,int side); + virtual void apply(cv::Mat& pDib, int side); virtual void apply(std::vector& mats, bool isTwoSide); @@ -40,9 +47,9 @@ public: private: - static 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); - + static bool scalar_LE(const cv::Scalar& val1, const cv::Scalar& val2); static cv::Mat getRoiMat(const cv::Mat& pDib); diff --git a/huagao/ImageProcess/ImageApplyRotation.cpp b/huagao/ImageProcess/ImageApplyRotation.cpp index 4a83d57b..eb05c4b5 100644 --- a/huagao/ImageProcess/ImageApplyRotation.cpp +++ b/huagao/ImageProcess/ImageApplyRotation.cpp @@ -1,10 +1,10 @@ #include "ImageApplyRotation.h" #define USE_TESSERCAT -#ifdef USE_TESSERCAT +//#define USE_HANWANG + //#define HG_GPDF_API_BUILD #include "hg_gpdf.h" -#endif CImageApplyRotation::CImageApplyRotation(RotationType rotation, bool isBackTransposed, int dpi, const char* tessdataPath) : m_rotation(rotation) @@ -38,6 +38,42 @@ void CImageApplyRotation::apply(cv::Mat& pDib, int side) if (m_rotation == RotationType::AutoTextOrientation) //锟皆讹拷锟侥憋拷锟斤拷锟斤拷识锟斤拷 { +#ifdef USE_HANWANG + cv::Mat temp; + if (m_dpi != 200) + { + double scale = 200 / static_cast(m_dpi); + int new_w = static_cast(pDib.cols * scale) / 4 * 4; + int new_h = pDib.rows * scale; + cv::resize(pDib, temp, cv::Size(new_w, new_h)); + } + else + temp = pDib(cv::Rect(0, 0, pDib.cols / 4 * 4, pDib.rows)).clone(); + + if (temp.channels() == 3) + cv::cvtColor(temp, temp, cv::COLOR_BGR2GRAY); + cv::threshold(temp, temp, 180, 255, cv::THRESH_OTSU); + + int orientation = HG_OCR::orientation(temp.data, temp.cols, temp.rows, temp.channels()); + + switch (orientation) + { + case 90: + cv::transpose(pDib, pDib); + cv::flip(pDib, pDib, 0); + break; + case 180: + cv::flip(pDib, pDib, 0); + cv::flip(pDib, pDib, 1); + break; + case 270: + cv::transpose(pDib, pDib); + cv::flip(pDib, pDib, 1); + break; + default: + break; + } +#endif #ifdef USE_TESSERCAT if (osd) { @@ -45,7 +81,7 @@ void CImageApplyRotation::apply(cv::Mat& pDib, int side) if (m_dpi != 200) { double scale = 200 / static_cast(m_dpi); - int new_w = (pDib.cols * scale + 3) / 4 * 4; + int new_w = (static_cast(pDib.cols * scale) + 3) / 4 * 4; int new_h = pDib.rows * scale; cv::resize(pDib, temp, cv::Size(new_w, new_h)); }