diff --git a/changelog.txt b/changelog.txt index ed352740..e225ff87 100644 --- a/changelog.txt +++ b/changelog.txt @@ -88,4 +88,6 @@ 9.适配卓育云ODM厂商 --23.04.24 10.对接爱云校做协议适配 --23.04.24 11.调整文件编码格式修复指示器乱码问题 --23.04.27 - 12.添加分纸模式设置功能 --23.05.05 \ No newline at end of file + 12.添加分纸模式设置功能 --23.05.05 + 13.更新裁切纠偏算法到1.5版本 --23.05.15 + 14.区分待纸扫描提示和扫描上传信息提示,防止扫描结束图像未上传完时两者争抢提示框 -23.05.26 \ No newline at end of file diff --git a/huagao/CIndicatorDlg.cpp b/huagao/CIndicatorDlg.cpp index 92b679c1..e000bb2d 100644 --- a/huagao/CIndicatorDlg.cpp +++ b/huagao/CIndicatorDlg.cpp @@ -57,7 +57,7 @@ void CIndicatorDlg::setindicatortext(int aquire, int updata) void CIndicatorDlg::setindicatortext(CString text) { - SetDlgItemText(IDC_STATIC_TIPS, text); + SetDlgItemText(IDC_STATIC_TIPS2, text); } diff --git a/huagao/CTwainUI.cpp b/huagao/CTwainUI.cpp index b9c5a1bb..7b2f0aab 100644 --- a/huagao/CTwainUI.cpp +++ b/huagao/CTwainUI.cpp @@ -129,6 +129,13 @@ BOOL CTwainUI::OnInitDialog() else { setvisable_autopaper(false); } + if ((m_hardwareVersion[5] == 'C' && atoi(m_hardwareVersion.substr(6, 4).c_str()) >= 103) || (m_hardwareVersion[5] > 'C')) + m_pageBasic->GetDlgItem(IDC_CKCOLORCAST)->ShowWindow(SW_SHOW); + else + { + ((CButton*)m_pageBasic->GetDlgItem(IDC_CKCOLORCAST))->SetCheck(FALSE); + m_pageBasic->GetDlgItem(IDC_CKCOLORCAST)->ShowWindow(SW_HIDE); + } setvisable_dogear(true); setvisable_size(true); setvisable_fixedpaper(false); @@ -145,6 +152,7 @@ BOOL CTwainUI::OnInitDialog() { setvisable_size(false); } + ((CButton*)m_pageBasic->GetDlgItem(IDC_RDQUALITYPRIORITY))->ShowWindow(SW_HIDE); ((CButton*)m_pageBasic->GetDlgItem(IDC_RDSPEEDPRIORITY))->ShowWindow(SW_HIDE); #ifdef G400 diff --git a/huagao/Device/GScanO1003399.cpp b/huagao/Device/GScanO1003399.cpp index 4c3ad309..960679ae 100644 --- a/huagao/Device/GScanO1003399.cpp +++ b/huagao/Device/GScanO1003399.cpp @@ -303,6 +303,8 @@ void GScanO1003399::config_params(GScanCap& param) //cfg.g200params.is_fixedpaper = param.en_fixedpaper; cfg.g200params.is_fixedpaper = true; //220513 ӰĬϹ̶ɼ cfg.g200params.en_anlogic_key = true; + //cfg.g200params.enabledsp_cache = true; + #ifdef G200 if ((fwversion[5] == 'A' && (atoi(fwversion.substr(6, 4).c_str()) > 1220)) || (fwversion[5] == 'B' && (atoi(fwversion.substr(6, 4).c_str()) <= 430))) @@ -370,6 +372,7 @@ void GScanO1003399::config_params(GScanCap& param) param39.fillholeratio_right = param.fillholeratio_right; param39.is_colorcast = param.is_colorcast; param39.fillhole.fillholeratio = std::max(std::max(std::max(param.fillholeratio_down, param.fillholeratio_up), std::max(param.fillholeratio_left, param.fillholeratio_right)),1); + m_usb->write_bulk(¶m39, sizeof(param39)); m_param .resolution_native = param.resolution_dst >= 500.0f ? 300.0f : 200.0f; @@ -606,9 +609,10 @@ void GScanO1003399::usb_run() this->UpdateScanInfo(str); std::this_thread::sleep_for(std::chrono::milliseconds(30)); } + this->UpdateScanInfo(L" "); if ((m_autopaper_timeout == false) || scanner_read_reg(m_usb, SR_STATUS)) return; - else + else Stop_scan(); }); } diff --git a/huagao/Device/GScanO400.cpp b/huagao/Device/GScanO400.cpp index b83f74e2..8083ed4e 100644 --- a/huagao/Device/GScanO400.cpp +++ b/huagao/Device/GScanO400.cpp @@ -785,8 +785,10 @@ void GScanO400::usbmain() } if (sw_p.elapsed_s() < gcap.autopaper_timeout && (!autopaper_stop)) break; - else + else { autopaper_stop = true; + } + UpdateScanInfo(L" "); } m_pImages->setscanflags(false); std::this_thread::sleep_for(std::chrono::milliseconds(500)); diff --git a/huagao/ImageProcess/ImageApplyAutoCrop.cpp b/huagao/ImageProcess/ImageApplyAutoCrop.cpp index 24500f9c..e222bebe 100644 --- a/huagao/ImageProcess/ImageApplyAutoCrop.cpp +++ b/huagao/ImageProcess/ImageApplyAutoCrop.cpp @@ -4,6 +4,10 @@ #include #include "ImageApplyDispersion.h" +#define COLOR_SCALE_THRE 0.5 +#define FRONT_TOP 70 +#define FX_FY 0.5f + CImageApplyAutoCrop::CImageApplyAutoCrop() : m_isCrop(false) , m_isDesaskew(false) @@ -15,11 +19,13 @@ CImageApplyAutoCrop::CImageApplyAutoCrop() , m_indent(5) , m_normalCrop(false) , m_isDispersion(true) + , m_fx(1.0) + , m_fy(1.0) { } CImageApplyAutoCrop::CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFillBlank, const cv::Size& fixedSize, bool isConvex, bool isFillColor, - double threshold, int noise, int indent, bool normalCrop, bool dispersion) + double threshold, int noise, int indent, bool normalCrop, bool dispersion, double fx, double fy) : m_isCrop(isCrop) , m_isDesaskew(isDesaskew) , m_isFillBlank(isFillBlank) @@ -31,6 +37,8 @@ CImageApplyAutoCrop::CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFi , m_fixedSize(fixedSize) , m_normalCrop(normalCrop) , m_isDispersion(dispersion) + , m_fx(fx) + , m_fy(fy) { } @@ -42,7 +50,7 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side) { cv::Mat dst; autoCrop_desaskew_fillBlank(pDib, dst, m_isCrop, m_isDesaskew, m_isFillBlank, m_fixedSize.width, m_fixedSize.height, - m_isConvexHull, m_isFillColor, m_threshold, m_noise, m_indent, m_normalCrop, m_isDispersion); + m_isConvexHull, m_isFillColor, m_threshold, m_noise, m_indent, m_normalCrop, m_isDispersion, m_fx, m_fy); pDib = dst; } @@ -59,10 +67,7 @@ void CImageApplyAutoCrop::apply(std::vector& mats, bool isTwoSide) } } -#define FRONT_TOP 70 -#define FX_FY 0.5f - -void myWarpAffine(cv::InputArray _src, cv::OutputArray _dst, cv::InputArray _M0, cv::Size dsize, int flags, int borderType, const cv::Scalar& borderValue) +void CImageApplyAutoCrop::myWarpAffine(cv::InputArray _src, cv::OutputArray _dst, cv::InputArray _M0, cv::Size dsize, int flags, int borderType, const cv::Scalar& borderValue) { int interpolation = flags; cv::Mat src = _src.getMat(), M0 = _M0.getMat(); @@ -94,7 +99,7 @@ void myWarpAffine(cv::InputArray _src, cv::OutputArray _dst, cv::InputArray _M0, M, interpolation, borderType, borderValue.val); } -uchar getBackGroudChannelMean(const cv::Mat& gray, int total, int threshold) +uchar CImageApplyAutoCrop::getBackGroudChannelMean(const cv::Mat& gray, int total, int threshold) { cv::Mat image_clone; cv::resize(gray, image_clone, cv::Size(), 0.25, 0.25); @@ -133,29 +138,74 @@ uchar getBackGroudChannelMean(const cv::Mat& gray, int total, int threshold) return 255; } -cv::Scalar getBackGroudColor(const cv::Mat& image, int total, int threshold) +cv::Scalar CImageApplyAutoCrop::getBackGroudColor(const cv::Mat& image, int threshold) { if (image.channels() == 3) { - cv::Mat image_bgr[3]; - cv::split(image, image_bgr); + uchar table[768] = { 0 }; + int hist_bgr[3][256] = { 0 }; + int width = image.cols, height = image.rows, bytesPerLine = image.step; + memset(table + threshold * 3, 255, 768 - threshold * 3); - uchar bgr[3]; - for (size_t i = 0; i < 3; i++) - bgr[i] = getBackGroudChannelMean(image_bgr[i], total, threshold); - return cv::Scalar(bgr[0], bgr[1], bgr[2]); + unsigned char* ptr_data = image.data; + unsigned char b = 0; + for (uint i = 0; i < height; i++, ptr_data += bytesPerLine) + for (uint j = 0, x = 0; j < width; j++, x += 3) + { + b = table[ptr_data[x] + ptr_data[x + 1] + ptr_data[x + 2]]; + for (uint k = 0; k < 3; k++) + hist_bgr[k][ptr_data[x + k] & b]++; + } + + int max_vals[3] = { 0 }; + cv::Scalar max_indexes(0, 0, 0); + + for (uint i = 5; i < 256; i++) + for (uint j = 0; j < 3; j++) + if (hist_bgr[j][i] > max_vals[j]) + { + max_vals[j] = hist_bgr[j][i]; + max_indexes[j] = i; + } + + return max_indexes; } else - return cv::Scalar::all(getBackGroudChannelMean(image, total, threshold)); + { + uchar table[256] = { 0 }; + int hist_bgr[256] = { 0 }; + int width = image.cols, height = image.rows, bytesPerLine = image.step; + memset(table + threshold, 255, 256 - threshold); + unsigned char* ptr_data = image.data; + unsigned char b = 0; + for (uint i = 0; i < height; i++, ptr_data += bytesPerLine) + for (uint j = 0, x = 0; j < width; j++, x++) + hist_bgr[ptr_data[x] & table[ptr_data[x]]]++; + + int max_vals = 5; + for (uint i = 5; i < 256; i++) + if (hist_bgr[i] > hist_bgr[max_vals]) + max_vals = i; + + return cv::Scalar(max_vals); + } } -CImageApplyDispersion dispersion_apply; -#define COLOR_SCALE_THRE 0.5 -void autoCrop_desaskew_fillBlank(const cv::Mat& src, cv::Mat& dst, bool isAutoCrop, bool isDesaskew, bool isFillBlank, int dWidth, int dHeight, - bool isConvex, bool isColorBlank, double threshold, int noise, int indent, bool isNormalCrop, bool dispersion) +CImageApplyDispersion m_dispersion_apply; +void CImageApplyAutoCrop::autoCrop_desaskew_fillBlank(cv::Mat& src, cv::Mat& dst, bool isAutoCrop, bool isDesaskew, bool isFillBlank, int dWidth, int dHeight, + bool isConvex, bool isColorBlank, double threshold, int noise, int indent, bool isNormalCrop, bool dispersion, double fx, double fy) { if (src.empty()) return; + if (fx < 0.999999 || fx > 1.000001 || fy < 0.999999 || fy > 1.000001) + cv::resize(src, src, cv::Size(), fx, fy, cv::INTER_LINEAR); + + if (!isAutoCrop && !isDesaskew && !isFillBlank && dWidth == 0 && dHeight == 0) + { + dst = src; + return; + } + if (isNormalCrop) { cv::Rect roi = cv::Rect((src.cols - dWidth) / 2, FRONT_TOP, dWidth, dHeight) & cv::Rect(0, 0, src.cols, src.rows); @@ -207,13 +257,13 @@ void autoCrop_desaskew_fillBlank(const cv::Mat& src, cv::Mat& dst, bool isAutoCr if (dispersion) { cv::Mat mat_dispersion = src(cv::boundingRect(maxContour)); - dispersion_apply.apply(mat_dispersion, 0); + m_dispersion_apply.apply(mat_dispersion, 0); } cv::Scalar blankColor; if (isFillBlank) if (isColorBlank) - blankColor = getBackGroudColor(resizeMat, rect.size.area() * FX_FY * FX_FY, COLOR_SCALE_THRE); + blankColor = getBackGroudColor(resizeMat, 20); else blankColor = cv::Scalar::all(255); else @@ -327,4 +377,4 @@ void autoCrop_desaskew_fillBlank(const cv::Mat& src, cv::Mat& dst, bool isAutoCr contours[contours.size() - 1].push_back(cv::Point(dstROI.cols, dst.rows)); hg::fillPolys(dstROI, contours, blankColor); } -} +} \ No newline at end of file diff --git a/huagao/ImageProcess/ImageApplyAutoCrop.h b/huagao/ImageProcess/ImageApplyAutoCrop.h index 63fa3616..057cd4ae 100644 --- a/huagao/ImageProcess/ImageApplyAutoCrop.h +++ b/huagao/ImageProcess/ImageApplyAutoCrop.h @@ -26,7 +26,8 @@ 2022/04/24 v1.4 重构算法,增加除色散功能 2022/05/03 v1.4.1 完善逻辑 2022/06/09 v1.4.2 修复获取文稿底色时,threshold值,设为固定值0.5 - * 版本号:v1.4.2 + 2022/10/31 v1.5 增加横纵DPI缩放参数fx,fy。 + * 版本号:v1.5 * ==================================================== */ @@ -36,6 +37,7 @@ #include "ImageApply.h" +class CImageApplyDispersion; class CImageApplyAutoCrop : public CImageApply { public: @@ -53,9 +55,11 @@ public: * indent [in]:轮廓缩进,裁剪、纠偏或者黑底填充时,对探索到的纸张轮廓进行缩进indent像素,默访 * normalCrop [in]:为true时,m_isCrop m_isDesaskew m_isFillBlank失效,固定裁切采用最传统的裁切方式,默认false * dispersion [in]:为true时,除色散;false时不除色散。默认为true + * fx [in]:横向缩放比例。默认1.0 + * fy [in]:纵向缩放比例。默认1.0 */ CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFillBlank, const cv::Size& fixedSize, bool isConvex = true, - bool isFillColor = false, double threshold = 40, int noise = 8, int indent = 5, bool normalCrop = false, bool dispersion = true); + bool isFillColor = false, double threshold = 40, int noise = 8, int indent = 5, bool normalCrop = false, bool dispersion = true, double fx = 1.0, double fy = 1.0); virtual ~CImageApplyAutoCrop(); @@ -101,6 +105,16 @@ public: void setDispersion(bool enable) { m_isDispersion = enable; } + static void autoCrop_desaskew_fillBlank(cv::Mat& src, cv::Mat& dst, bool isAutoCrop, bool isDesaskew, bool isFillBlank, int dWidth, int dHeight, + bool isConvex = true, bool isColorBlank = false, double threshold = 40, int noise = 8, int indent = 5, bool isNormalCrop = false, bool dispersion = true, + double fx = 1.0, double fy = 1.0); + +private: + static void myWarpAffine(cv::InputArray _src, cv::OutputArray _dst, cv::InputArray _M0, cv::Size dsize, int flags, int borderType, const cv::Scalar& borderValue); + + static uchar getBackGroudChannelMean(const cv::Mat& gray, int total, int threshold); + + static cv::Scalar getBackGroudColor(const cv::Mat& image, int threshold); private: bool m_isCrop; bool m_isDesaskew; @@ -117,9 +131,9 @@ private: cv::RotatedRect m_rect; std::vector m_rects; std::vector m_maxContour; + + double m_fx; + double m_fy; }; - -void autoCrop_desaskew_fillBlank(const cv::Mat& src, cv::Mat& dst, bool isAutoCrop, bool isDesaskew, bool isFillBlank, int dWidth, int dHeight, - bool isConvex = true, bool isColorBlank = false, double threshold = 40, int noise = 8, int indent = 5, bool isNormalCrop = false, bool dispersion = true); -#endif // !IMAGE_APPLY_AUTO_CROP_H +#endif // !IMAGE_APPLY_AUTO_CROP_H \ No newline at end of file diff --git a/huagao/huagaods.cpp b/huagao/huagaods.cpp index 67eaf598..1ccb7906 100644 --- a/huagao/huagaods.cpp +++ b/huagao/huagaods.cpp @@ -1568,6 +1568,10 @@ Result HuagaoDs::identityOpenDs(const Identity& origin) { m_scanparam->is_switchfrontback = 0; m_scanparam->is_autodiscradblank_normal = m_scanparam->is_autodiscradblank_vince = m_scanparam->en_fold = 0; } +//#ifdef LANXUM +// if (mech) m_scanparam->is_autodiscradblank_normal = true; +// else m_scanparam->is_autodiscradblank_normal = false; +//#endif return success(); } return CapSupGetAllReset(msg, data, m_scanparam->is_duplex, Bool(true)); diff --git a/huagao/huagaotwds.rc b/huagao/huagaotwds.rc index 465f6338..d9e91347 100644 Binary files a/huagao/huagaotwds.rc and b/huagao/huagaotwds.rc differ diff --git a/huagao/resource.h b/huagao/resource.h index 5f6da6fb..4dbe0919 100644 Binary files a/huagao/resource.h and b/huagao/resource.h differ