Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev
This commit is contained in:
commit
e6080d803f
|
@ -1,11 +1,17 @@
|
|||
#include "ImageApplyDiscardBlank.h"
|
||||
#include "ImageProcess_Public.h"
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
|
||||
CImageApplyDiscardBlank::CImageApplyDiscardBlank(double threshold, int edge, double devTh, double meanTh)
|
||||
#define FX 0.5
|
||||
#define FY 0.5
|
||||
|
||||
CImageApplyDiscardBlank::CImageApplyDiscardBlank(double threshold, int edge, double devTh, double meanTh, int dilate)
|
||||
: m_threshold(threshold)
|
||||
, m_edge(edge)
|
||||
, m_devTh(devTh)
|
||||
, m_meanTh(meanTh)
|
||||
, m_dilate(dilate)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -15,7 +21,7 @@ CImageApplyDiscardBlank::~CImageApplyDiscardBlank(void)
|
|||
|
||||
void CImageApplyDiscardBlank::apply(cv::Mat& pDib, int side)
|
||||
{
|
||||
if (apply(pDib, m_threshold, m_edge, m_devTh, m_meanTh))
|
||||
if (apply(pDib, m_threshold, m_edge, m_devTh, m_meanTh, m_dilate))
|
||||
pDib.release();
|
||||
}
|
||||
|
||||
|
@ -32,14 +38,6 @@ void CImageApplyDiscardBlank::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
|||
}
|
||||
}
|
||||
|
||||
bool 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;
|
||||
}
|
||||
|
||||
bool maxMinCompare(const cv::Mat& img, const cv::Mat& mask, double devTh, double meanTh)
|
||||
{
|
||||
double min, max;
|
||||
|
@ -49,18 +47,32 @@ bool maxMinCompare(const cv::Mat& img, const cv::Mat& mask, double devTh, double
|
|||
return (max - min) < devTh;
|
||||
}
|
||||
|
||||
bool CImageApplyDiscardBlank::apply(const cv::Mat& pDib, double threshold, int edge, double devTh, double meanTh)
|
||||
bool CImageApplyDiscardBlank::apply(const cv::Mat& pDib, double threshold, int edge, double devTh, double meanTh, int dilate)
|
||||
{
|
||||
if (pDib.empty())
|
||||
return true;
|
||||
|
||||
cv::Mat img_resize;
|
||||
cv::resize(pDib, img_resize, cv::Size(), 0.2, 0.2);
|
||||
cv::resize(pDib, img_resize, cv::Size(), FX, FY);
|
||||
|
||||
if (img_resize.channels() == 3)
|
||||
cv::cvtColor(img_resize, img_resize, cv::COLOR_BGR2GRAY);
|
||||
|
||||
if (dilate > 2)
|
||||
{
|
||||
cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(1, dilate));
|
||||
cv::Mat img_temp1;
|
||||
cv::morphologyEx(img_resize, img_temp1, cv::MORPH_DILATE, element);
|
||||
|
||||
element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(dilate, 1));
|
||||
cv::Mat img_temp2;
|
||||
cv::morphologyEx(img_resize, img_temp2, cv::MORPH_DILATE, element);
|
||||
|
||||
img_resize = img_temp1 & img_temp2;
|
||||
}
|
||||
|
||||
cv::Mat threshold_img;
|
||||
if (img_resize.channels() == 3)
|
||||
cv::cvtColor(img_resize, threshold_img, cv::COLOR_BGR2GRAY);
|
||||
cv::threshold(img_resize.channels() == 3 ? threshold_img : img_resize, threshold_img, threshold, 255, cv::THRESH_BINARY);
|
||||
cv::threshold(img_resize, threshold_img, threshold, 255, cv::THRESH_BINARY);
|
||||
|
||||
std::vector<std::vector<cv::Point>> contours;
|
||||
std::vector<cv::Vec4i> h1;
|
||||
|
@ -72,7 +84,7 @@ bool CImageApplyDiscardBlank::apply(const cv::Mat& pDib, double threshold, int e
|
|||
contour.push_back(p);
|
||||
|
||||
cv::RotatedRect rect = hg::getBoundingRect(contour);
|
||||
rect.size = cv::Size2f(rect.size.width - edge / 2.5, rect.size.height - edge / 2.5);
|
||||
rect.size = cv::Size2f(rect.size.width - edge * FX, rect.size.height - edge * FX);
|
||||
cv::Point2f box[4];
|
||||
rect.points(box);
|
||||
contour.clear();
|
||||
|
@ -83,9 +95,6 @@ bool CImageApplyDiscardBlank::apply(const cv::Mat& pDib, double threshold, int e
|
|||
contours.push_back(contour);
|
||||
cv::Mat mask = cv::Mat::zeros(img_resize.size(), CV_8UC1);
|
||||
hg::fillPolys(mask, contours, cv::Scalar::all(255));
|
||||
int kSize = (devTh / 20) / 2 * 2 + 1;
|
||||
if (kSize > 1)
|
||||
cv::blur(img_resize, img_resize, cv::Size(kSize, kSize));
|
||||
|
||||
bool b = true;
|
||||
if (img_resize.channels() == 3)
|
||||
|
@ -100,17 +109,29 @@ bool CImageApplyDiscardBlank::apply(const cv::Mat& pDib, double threshold, int e
|
|||
}
|
||||
else
|
||||
b &= maxMinCompare(img_resize, mask, devTh, meanTh);
|
||||
/*
|
||||
if (b)
|
||||
{
|
||||
cv::imwrite("¿Õ°×Ò³/img1/" + std::to_string(index) + ".bmp", img_resize);
|
||||
cv::imwrite("¿Õ°×Ò³/mask1/" + std::to_string(index) + ".bmp", mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
cv::imwrite("¿Õ°×Ò³/img2/" + std::to_string(index) + ".bmp", img_resize);
|
||||
cv::imwrite("¿Õ°×Ò³/mask2/" + std::to_string(index) + ".bmp", mask);
|
||||
}*/
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
bool CImageApplyDiscardBlank::apply(int fileSize, const cv::Size& imageSize, FileType flag)
|
||||
{
|
||||
switch (flag)
|
||||
{
|
||||
case JPEG_COLOR:
|
||||
if (static_cast<double>(fileSize) / static_cast<double>(imageSize.width * imageSize.height) > 0.039)
|
||||
return true;
|
||||
break;
|
||||
case JPEG_GRAY:
|
||||
if (static_cast<double>(fileSize) / static_cast<double>(imageSize.width * imageSize.height) > 0.018)
|
||||
return true;
|
||||
break;
|
||||
case PNG_COLOR:
|
||||
break;
|
||||
case PNG_GRAY:
|
||||
break;
|
||||
case PNG_BINARAY:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,11 @@
|
|||
2022/09/19 v1.4 增加模糊处理,提高空白页的过滤能力
|
||||
2022/09/19 v1.4.1 调整模糊处理步骤
|
||||
2022/11/18 v1.4.2 调整默认参数
|
||||
* 版本号:v1.4.2
|
||||
2022/11/29 v1.5 增加纸张杂点忽略功能
|
||||
2022/12/03 v1.5.1 调整纸张杂点忽略逻辑,避免把细条纹(有效信息)给忽略掉;默认将图像按照灰度图进行识别。
|
||||
2023/10/12 v1.6 添加新的空白页识别方案。采用JEPG文件大小判断是否为空白页。
|
||||
2023/10/20 v1.6.1 优化JEPG文件大小判断空白页
|
||||
* 版本号:v1.6.1
|
||||
|
||||
* ====================================================
|
||||
*/
|
||||
|
@ -31,17 +35,25 @@
|
|||
class GIMGPROC_LIBRARY_API CImageApplyDiscardBlank : public CImageApply
|
||||
{
|
||||
public:
|
||||
enum FileType
|
||||
{
|
||||
JPEG_COLOR,
|
||||
JPEG_GRAY,
|
||||
PNG_COLOR,
|
||||
PNG_GRAY,
|
||||
PNG_BINARAY
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 空白页识别
|
||||
/// </summary>
|
||||
/// <param name="pDib">原图</param>
|
||||
/// <param name="threshold">轮廓阈值</param>
|
||||
/// <param name="edge">边缘缩进</param>
|
||||
/// <param name="devTh">笔迹判定阈值。该阈值越低,越容易判定存在笔迹。</param>
|
||||
/// <param name="meanTh">文稿底色阈值。低于该阈值的文稿底色,直接视为非空白页。</param>
|
||||
/// <returns></returns>
|
||||
CImageApplyDiscardBlank(double threshold = 40, int edge = 50, double devTh = 30, double meanTh = 200);
|
||||
/// <param name="threshold">轮廓阈值。取值范围[0, 255]</param>
|
||||
/// <param name="edge">边缘缩进。取值范围[0, +∞]</param>
|
||||
/// <param name="devTh">笔迹判定阈值。该阈值越低,越容易判定存在笔迹。取值范围[0, +∞]</param>
|
||||
/// <param name="meanTh">文稿底色阈值。低于该阈值的文稿底色,直接视为非空白页。取值范围[0, 255]</param>
|
||||
/// <param name="dilate">忽略纸张杂点。≤1时不生效,值越大越容易忽略杂点。取值范围[1, +∞]</param>
|
||||
CImageApplyDiscardBlank(double threshold = 40, int edge = 50, double devTh = 30, double meanTh = 200, int dilate = 11);
|
||||
|
||||
virtual ~CImageApplyDiscardBlank(void);
|
||||
|
||||
|
@ -50,21 +62,32 @@ public:
|
|||
virtual void apply(std::vector<cv::Mat>& mats, bool isTwoSide);
|
||||
|
||||
/// <summary>
|
||||
/// 空白页识别
|
||||
/// 空白页识别。根据图像内容进行识别。
|
||||
/// </summary>
|
||||
/// <param name="pDib">原图</param>
|
||||
/// <param name="threshold">轮廓阈值</param>
|
||||
/// <param name="edge">边缘缩进</param>
|
||||
/// <param name="devTh">笔迹判定阈值。该阈值越低,越容易判定存在笔迹。</param>
|
||||
/// <param name="meanTh">文稿底色阈值。低于该阈值的文稿底色,直接视为非空白页。</param>
|
||||
/// <param name="dilate">忽略纸张杂点。≤1时不生效,值越大越容易忽略杂点</param>
|
||||
/// <returns>true为空白页,false为非空白页</returns>
|
||||
static bool apply(const cv::Mat& pDib, double threshold = 40, int edge = 50, double devTh = 30, double meanTh = 200, int dilate = 3);
|
||||
|
||||
/// <summary>
|
||||
/// 空白页识别。根据jpeg文件大小进行判断。
|
||||
/// </summary>
|
||||
/// <param name="fileSize">J文件大小</param>
|
||||
/// <param name="imageSize">图像大小</param>
|
||||
/// <param name="flag">0为JPG + 彩色,1为JPG + 灰度,2为PNG + 彩色, 3为PNG + 灰度, 4为PNG + </param>
|
||||
/// <returns></returns>
|
||||
static bool apply(const cv::Mat& pDib, double threshold = 40, int edge = 50, double devTh = 30, double meanTh = 200);
|
||||
static bool apply(int fileSize, const cv::Size& imageSize, FileType type);
|
||||
|
||||
private:
|
||||
double m_threshold;
|
||||
int m_edge;
|
||||
double m_devTh;
|
||||
double m_meanTh;
|
||||
int m_dilate;
|
||||
};
|
||||
|
||||
#endif // !IMAGE_APPLY_DISCARD_BLANK_H
|
|
@ -2920,7 +2920,54 @@ int hg_scanner::setting_get_initial_boot_time(void* data, long* len)
|
|||
int hg_scanner::setting_set_discardblank(void* data, long* len)
|
||||
{
|
||||
is_discardblank = *(bool*)data;
|
||||
return SCANNER_ERR_OK;
|
||||
|
||||
//discard_blank and fold_in_half are mutually exclusive.
|
||||
if (is_discardblank)
|
||||
{
|
||||
std::string str(page_string(PAGE_FOLIO));
|
||||
int id = lang_get_string_id(str.c_str(), false);
|
||||
if (id == -1)
|
||||
{
|
||||
setting_jsn_.at(SANE_STD_OPT_NAME_PAGE).at("range").erase(str.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < setting_jsn_.at(SANE_STD_OPT_NAME_PAGE).at("range").size(); ++i)
|
||||
{
|
||||
int val = 0;
|
||||
setting_jsn_.at(SANE_STD_OPT_NAME_PAGE).at("range").at(i).get_to(val);
|
||||
if (val == id)
|
||||
{
|
||||
setting_jsn_.at(SANE_STD_OPT_NAME_PAGE).at("range").erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string str(page_string(PAGE_FOLIO));
|
||||
int id = lang_get_string_id(str.c_str(), false), val = 0;
|
||||
bool add = true;
|
||||
for (int i = 0; i < setting_jsn_.at(SANE_STD_OPT_NAME_PAGE).at("range").size(); ++i)
|
||||
{
|
||||
setting_jsn_.at(SANE_STD_OPT_NAME_PAGE).at("range").at(i).get_to(val);
|
||||
if (val == id)
|
||||
{
|
||||
add = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (add)
|
||||
{
|
||||
if (id == -1)
|
||||
setting_jsn_.at(SANE_STD_OPT_NAME_PAGE).at("range").push_back(str);
|
||||
else
|
||||
setting_jsn_.at(SANE_STD_OPT_NAME_PAGE).at("range").push_back(id);
|
||||
}
|
||||
}
|
||||
|
||||
return SCANNER_ERR_RELOAD_OPT_PARAM;
|
||||
}
|
||||
int hg_scanner::on_color_mode_changed(int& color_mode)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#pragma once
|
||||
#pragma once
|
||||
|
||||
// hg_scanner is the base class of kinds of scanners
|
||||
//
|
||||
|
@ -31,6 +31,7 @@
|
|||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#include "../../../sdk/include/huagao/brand.h"
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1708,6 +1708,7 @@ SANE_Status hg_sane_middleware::read(SANE_Handle h, void* buf, int* bytes)
|
|||
}
|
||||
SANE_Status hg_sane_middleware::stop(SANE_Handle h)
|
||||
{
|
||||
LOG_INFO(LOG_LEVEL_ALL, "sane_cancel\n");
|
||||
scanner_handle hs = find_openning_device(h);
|
||||
|
||||
if(hs)
|
||||
|
@ -2602,8 +2603,6 @@ extern "C" { // avoid compiler exporting name in C++ style !!!
|
|||
}
|
||||
void inner_sane_cancel(SANE_Handle handle)
|
||||
{
|
||||
LOG_INFO(LOG_LEVEL_ALL, "sane_cancel\n");
|
||||
|
||||
hg_sane_middleware::instance()->stop(handle);
|
||||
}
|
||||
SANE_Status inner_sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking)
|
||||
|
|
Loading…
Reference in New Issue