Compare commits
226 Commits
96cbfed48d
...
b7f9a0b8e4
Author | SHA1 | Date |
---|---|---|
yangjiaxuan | b7f9a0b8e4 | |
yangjiaxuan | 9109a04eaa | |
yangjiaxuan | d2bde90022 | |
yangjiaxuan | 86cd595177 | |
yangjiaxuan | f5ae44fbcb | |
yangjiaxuan | 0d64b48c3a | |
13038267101 | a9e9899319 | |
13038267101 | f33d1f7df5 | |
yangjiaxuan | 297d5ed27b | |
yangjiaxuan | 75aaa0c475 | |
yangjiaxuan | fb3b6bbe74 | |
yangjiaxuan | e8e8e484e4 | |
yangjiaxuan | 9c916485ea | |
yangjiaxuan | 11c902f23e | |
yangjiaxuan | 4d53672e6e | |
yangjiaxuan | 4322c14be2 | |
13038267101 | 4d93d6bb1a | |
13038267101 | 5104218ace | |
yangjiaxuan | eaa0fb02a6 | |
13038267101 | 6a0fd39747 | |
13038267101 | 8ee68aa7e9 | |
13038267101 | e7608d308d | |
yangjiaxuan | e5a92d9585 | |
gb | ddf6b6e4d1 | |
yangjiaxuan | 13b4327281 | |
yangjiaxuan | 0d2c7d79f7 | |
13038267101 | 2727b272da | |
13038267101 | 924fc028f6 | |
13038267101 | f0c1287ddb | |
13038267101 | e2abedf820 | |
13038267101 | d2f3a7e45a | |
yangjiaxuan | 6b067189ed | |
yangjiaxuan | 38a7e40296 | |
yangjiaxuan | 96b91254b4 | |
yangjiaxuan | ea07433491 | |
yangjiaxuan | 5669ff2464 | |
yangjiaxuan | 7de448dca7 | |
13038267101 | 913b16b21e | |
13038267101 | 21d59af26c | |
yangjiaxuan | f3a06285ff | |
gb | b0274c4b31 | |
yangjiaxuan | d8ade4c912 | |
yangjiaxuan | bb4b577f14 | |
yangjiaxuan | e3eb140fcf | |
yangjiaxuan | 90fb6f5955 | |
gb | 436dc23db6 | |
yangjiaxuan | bcd6475f1b | |
13038267101 | c6b255a18a | |
13038267101 | f8cf547512 | |
gb | d0093d6199 | |
gb | ed5f19354b | |
gb | 43ef322c20 | |
yangjiaxuan | bfe3819be3 | |
yangjiaxuan | 800fca0a0e | |
gb | 4f78f416b5 | |
yangjiaxuan | c99d07c1a4 | |
yangjiaxuan | 24cd6b5c10 | |
yangjiaxuan | 21c0ddec8f | |
gb | 3ce9a65ae6 | |
gb | f3514d0792 | |
gb | ecf7e2e071 | |
13038267101 | 6a6b24d07a | |
13038267101 | fc016443cf | |
13038267101 | 62a0dec39d | |
gb | 27fa305c9a | |
yangjiaxuan | 57de6617b4 | |
yangjiaxuan | 35999b8f16 | |
yangjiaxuan | cf1f7621e5 | |
yangjiaxuan | 3c520920d2 | |
yangjiaxuan | fea65386e8 | |
yangjiaxuan | 3fadf2de42 | |
yangjiaxuan | 7ab95e272e | |
yangjiaxuan | b7b85e44a8 | |
yangjiaxuan | b1b5ed44e0 | |
yangjiaxuan | 57082a9efe | |
yangjiaxuan | 6fc4df0550 | |
gb | ca041a1005 | |
gb | 9b10e91dba | |
gb | db0a5b7db3 | |
gb | ebd227d27d | |
gb | b78afdc9a0 | |
gb | d5325e9a4c | |
yangjiaxuan | 7de2077960 | |
yangjiaxuan | cfb1431efd | |
yangjiaxuan | f30f227860 | |
13038267101 | 3d865fa895 | |
13038267101 | ef3792b131 | |
13038267101 | e6026342bc | |
yangjiaxuan | 9590e61da2 | |
yangjiaxuan | a423b0c8ba | |
yangjiaxuan | 7f4bb50a57 | |
yangjiaxuan | 9e30fa0db0 | |
13038267101 | 7de96f6dff | |
13038267101 | 833048a97c | |
13038267101 | c8e913569f | |
13038267101 | 3dca020d69 | |
yangjiaxuan | c7581c84fb | |
13038267101 | e5a395d1fc | |
13038267101 | 0d2f75d070 | |
yangjiaxuan | 2d1d10f722 | |
13038267101 | 4c75e42f01 | |
13038267101 | c2e438544d | |
yangjiaxuan | e6468b42c0 | |
yangjiaxuan | 7333a2b964 | |
13038267101 | cbeb2f5653 | |
13038267101 | 07e1c0921c | |
yangjiaxuan | 52097e47e7 | |
gb | 2400239e55 | |
yangjiaxuan | 89b2fc4777 | |
yangjiaxuan | 47cf2a4ae8 | |
yangjiaxuan | ff3a782f4e | |
yangjiaxuan | a65e1455b5 | |
gb | 8c5cba338c | |
13038267101 | 6b53aed32e | |
13038267101 | d0cf834b95 | |
gb | e2939d5c46 | |
yangjiaxuan | 3ff93b1dca | |
yangjiaxuan | 0599191708 | |
yangjiaxuan | c0bfb66ad1 | |
yangjiaxuan | d7ec535fdd | |
gb | a41de93724 | |
yangjiaxuan | bc6fdc836d | |
yangjiaxuan | 6cc022191c | |
yangjiaxuan | b3a7503be9 | |
yangjiaxuan | e79bed40dd | |
yangjiaxuan | 9ecaf00146 | |
yangjiaxuan | 4c9dd9462b | |
yangjiaxuan | 54598d4a54 | |
yangjiaxuan | 34dd2b8178 | |
yangjiaxuan | 57af551e4e | |
yangjiaxuan | 524a9b2af7 | |
yangjiaxuan | cb7e9ebd8e | |
yangjiaxuan | 7da6736e0e | |
13038267101 | 3faed87207 | |
13038267101 | 1fcd17c167 | |
gb | 0b41d9f30a | |
13038267101 | 49cb1e71b5 | |
13038267101 | 2031ee25ab | |
13038267101 | ccd91dc0d6 | |
yangjiaxuan | ef81bb11df | |
13038267101 | 95f01e66d3 | |
13038267101 | bcd6a7ff39 | |
yangjiaxuan | 18669d32ef | |
luoliangyi | 4e99f49c72 | |
yangjiaxuan | c5b1afb88d | |
yangjiaxuan | 6f363096bb | |
yangjiaxuan | 0bbbe41c3e | |
yangjiaxuan | b4b363720f | |
yangjiaxuan | 36b334f3ff | |
13038267101 | 28962b775c | |
13038267101 | 54bc87c119 | |
yangjiaxuan | 70fc147c6e | |
yangjiaxuan | 57814455dc | |
yangjiaxuan | c8354cf858 | |
yangjiaxuan | 87874c6cc4 | |
yangjiaxuan | 28b7395b68 | |
yangjiaxuan | ebaace74a1 | |
yangjiaxuan | 142e957507 | |
yangjiaxuan | 8cebf0d586 | |
yangjiaxuan | 77a0c7e176 | |
yangjiaxuan | e522398781 | |
yangjiaxuan | 4a94b460dd | |
yangjiaxuan | d5d33d8bdb | |
yangjiaxuan | c1d2196656 | |
yangjiaxuan | 8aebb9c4eb | |
yangjiaxuan | 5c19147246 | |
yangjiaxuan | ea2768c16d | |
yangjiaxuan | c746e58c82 | |
13038267101 | 73227fd45a | |
13038267101 | 5846ced765 | |
13038267101 | 567d030f02 | |
13038267101 | 0b439c26e3 | |
yangjiaxuan | 325f3c2888 | |
yangjiaxuan | 41ebdc282f | |
yangjiaxuan | 9ea63dd1ec | |
yangjiaxuan | 96d7466aca | |
gb | 927b0199d3 | |
13038267101 | 3af53b5dae | |
13038267101 | 88ac5e7839 | |
yangjiaxuan | e0696bd9b6 | |
13038267101 | 12ae6591b9 | |
13038267101 | 5332cc6d2a | |
yangjiaxuan | ec7782126b | |
yangjiaxuan | 382ef8be76 | |
yangjiaxuan | ee35cf042f | |
yangjiaxuan | 0db35e4b3b | |
yangjiaxuan | a3334457bf | |
yangjiaxuan | 716d5db92b | |
13038267101 | d172dc3685 | |
13038267101 | c4bb56fc79 | |
yangjiaxuan | bb4fd7fc3d | |
yangjiaxuan | 392fc37f30 | |
13038267101 | e6080d803f | |
13038267101 | 7d48f11935 | |
yangjiaxuan | eb443e353f | |
gb | ce05ef521e | |
gb | d0a267adb4 | |
yangjiaxuan | bb6c1cdf6e | |
13038267101 | 5f1c2f45fd | |
13038267101 | 4592b81370 | |
13038267101 | c770715397 | |
13038267101 | 679cb0ffef | |
yangjiaxuan | 34d078eb2d | |
gb | f6ed0211ea | |
gb | 78f5a7baa7 | |
gb | 07d094acd0 | |
gb | af593e3376 | |
gb | 483703fa95 | |
gb | 13cb6ad835 | |
yangjiaxuan | a2002ac455 | |
13038267101 | 5aecdef38a | |
13038267101 | 16bd0223c0 | |
gb | 6e43985480 | |
gb | dad78e3b20 | |
yangjiaxuan | cc0d64f17d | |
yangjiaxuan | 66276e6c9f | |
yangjiaxuan | eaf4243787 | |
yangjiaxuan | e5f3e22cdd | |
yangjiaxuan | 2d7d9b5e52 | |
yangjiaxuan | 34d854cc56 | |
13038267101 | f9b31130ac | |
13038267101 | 7aa481f811 | |
yangjiaxuan | f29ab1d599 | |
gb | a47d895109 | |
gb | 1b54667d92 | |
gb | 6f5bde5cc4 |
|
@ -4,7 +4,6 @@
|
|||
#include <opencv2/imgproc/hal/hal.hpp>
|
||||
#include "ImageApplyDispersion.h"
|
||||
|
||||
#define COLOR_BACKGROUND_THRE 20
|
||||
#define FRONT_TOP 70
|
||||
#define FX_FY 0.5f
|
||||
|
||||
|
@ -18,14 +17,13 @@ CImageApplyAutoCrop::CImageApplyAutoCrop()
|
|||
, m_noise(8)
|
||||
, 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 fx, double fy)
|
||||
double threshold, int noise, int indent, bool normalCrop, double fx, double fy)
|
||||
: m_isCrop(isCrop)
|
||||
, m_isDesaskew(isDesaskew)
|
||||
, m_isFillBlank(isFillBlank)
|
||||
|
@ -36,7 +34,6 @@ CImageApplyAutoCrop::CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFi
|
|||
, m_indent(indent)
|
||||
, m_fixedSize(fixedSize)
|
||||
, m_normalCrop(normalCrop)
|
||||
, m_isDispersion(dispersion)
|
||||
, m_fx(fx)
|
||||
, m_fy(fy)
|
||||
{
|
||||
|
@ -50,7 +47,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_fx, m_fy);
|
||||
m_isConvexHull, m_isFillColor, m_threshold, m_noise, m_indent, m_normalCrop, m_fx, m_fy);
|
||||
pDib = dst;
|
||||
}
|
||||
|
||||
|
@ -99,61 +96,8 @@ void CImageApplyAutoCrop::myWarpAffine(cv::InputArray _src, cv::OutputArray _dst
|
|||
M, interpolation, borderType, borderValue.val);
|
||||
}
|
||||
|
||||
cv::Scalar CImageApplyAutoCrop::getBackGroudColor(const cv::Mat& image, int threshold)
|
||||
{
|
||||
if (image.channels() == 3)
|
||||
{
|
||||
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);
|
||||
|
||||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
bool isConvex, bool isColorBlank, double threshold, int noise, int indent, bool isNormalCrop, double fx, double fy)
|
||||
{
|
||||
if (src.empty()) return;
|
||||
|
||||
|
@ -186,7 +130,7 @@ void CImageApplyAutoCrop::autoCrop_desaskew_fillBlank(cv::Mat& src, cv::Mat& dst
|
|||
hg::threshold_Mat(resizeMat, thre, threshold);
|
||||
|
||||
if (noise > 0)
|
||||
cv::morphologyEx(thre, thre, cv::MORPH_OPEN, getStructuringElement(cv::MORPH_RECT, cv::Size(noise * FX_FY, 1)),
|
||||
cv::morphologyEx(thre, thre, cv::MORPH_OPEN, getStructuringElement(cv::MORPH_RECT, cv::Size(cv::max(static_cast<int>(noise * FX_FY), 1), 1)),
|
||||
cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0));
|
||||
|
||||
std::vector<cv::Vec4i> hierarchy;
|
||||
|
@ -213,18 +157,26 @@ void CImageApplyAutoCrop::autoCrop_desaskew_fillBlank(cv::Mat& src, cv::Mat& dst
|
|||
}
|
||||
|
||||
cv::RotatedRect rect = hg::getBoundingRect(maxContour);
|
||||
|
||||
if (dispersion)
|
||||
if (rect.size.width < 1 || rect.size.height < 1)
|
||||
{
|
||||
CImageApplyDispersion m_dispersion_apply;
|
||||
cv::Mat mat_dispersion = src(cv::boundingRect(maxContour));
|
||||
m_dispersion_apply.apply(mat_dispersion, 0);
|
||||
dst = src;
|
||||
return;
|
||||
}
|
||||
|
||||
cv::Scalar blankColor;
|
||||
if (isFillBlank)
|
||||
if (isColorBlank)
|
||||
blankColor = getBackGroudColor(resizeMat, COLOR_BACKGROUND_THRE);
|
||||
{
|
||||
cv::Rect boudingRect = cv::boundingRect(maxContour);
|
||||
boudingRect.x *= FX_FY;
|
||||
boudingRect.y *= FX_FY;
|
||||
boudingRect.width *= FX_FY;
|
||||
boudingRect.height *= FX_FY;
|
||||
|
||||
cv::Mat temp_bgc;
|
||||
cv::resize(resizeMat(boudingRect), temp_bgc, cv::Size(200, 200));
|
||||
blankColor = hg::getBackGroundColor(temp_bgc, cv::Mat(), 10);
|
||||
}
|
||||
else
|
||||
blankColor = cv::Scalar::all(255);
|
||||
else
|
||||
|
@ -234,21 +186,27 @@ void CImageApplyAutoCrop::autoCrop_desaskew_fillBlank(cv::Mat& src, cv::Mat& dst
|
|||
if (isDesaskew)
|
||||
dst = cv::Mat(cv::Size(rect.size), src.type(), blankColor);
|
||||
else
|
||||
dst = cv::Mat(rect.boundingRect().size(), src.type(), blankColor);
|
||||
dst = cv::Mat(/*rect.boundingRect().size()*/ cv::boundingRect(maxContour).size(), src.type(), blankColor);
|
||||
else
|
||||
dst = cv::Mat(dHeight, dWidth, src.type(), blankColor);
|
||||
|
||||
cv::Mat dstROI;
|
||||
if (isDesaskew && rect.angle != 0)
|
||||
{
|
||||
cv::RotatedRect rect_temp = rect;
|
||||
if (rect_temp.size.width > dst.cols)
|
||||
rect_temp.size.width = dst.cols;
|
||||
if (rect_temp.size.height > dst.rows)
|
||||
rect_temp.size.height = dst.rows;
|
||||
|
||||
cv::Point2f srcTri[4], dstTri[3];
|
||||
rect.points(srcTri);
|
||||
rect_temp.points(srcTri);
|
||||
srcTri[0].x -= 1;
|
||||
srcTri[1].x -= 1;
|
||||
srcTri[2].x -= 1;
|
||||
|
||||
int w = rect.size.width;
|
||||
int h = rect.size.height;
|
||||
int w = rect_temp.size.width;
|
||||
int h = rect_temp.size.height;
|
||||
int x = (dst.cols - w) / 2;
|
||||
int y = (dst.rows - h) / 2;
|
||||
dstTri[0] = cv::Point2f(0, h);
|
||||
|
@ -256,7 +214,7 @@ void CImageApplyAutoCrop::autoCrop_desaskew_fillBlank(cv::Mat& src, cv::Mat& dst
|
|||
dstTri[2] = cv::Point2f(w, 0);
|
||||
|
||||
dstROI = dst(cv::Rect(x, y, w, h) & cv::Rect(0, 0, dst.cols, dst.rows));
|
||||
myWarpAffine(src, dstROI, cv::getAffineTransform(srcTri, dstTri), dstROI.size(), cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar::all(0));
|
||||
myWarpAffine(src, dstROI, cv::getAffineTransform(srcTri, dstTri), dstROI.size(), cv::INTER_LINEAR, cv::BORDER_CONSTANT, blankColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -276,6 +234,8 @@ void CImageApplyAutoCrop::autoCrop_desaskew_fillBlank(cv::Mat& src, cv::Mat& dst
|
|||
|
||||
dstROI = dst(cv::Rect((dst.cols - bounding.width) / 2, (dst.rows - bounding.height) / 2, bounding.width, bounding.height));
|
||||
src(bounding).copyTo(dstROI);
|
||||
|
||||
//cv::imwrite("dst.bmp", dst);
|
||||
}
|
||||
|
||||
if (isFillBlank)
|
||||
|
@ -300,7 +260,8 @@ void CImageApplyAutoCrop::autoCrop_desaskew_fillBlank(cv::Mat& src, cv::Mat& dst
|
|||
}
|
||||
else
|
||||
{
|
||||
cv::Rect bounding = rect.boundingRect();
|
||||
//cv::Rect bounding = rect.boundingRect();
|
||||
cv::Rect bounding = cv::boundingRect(maxContour);
|
||||
srcTri[0] = cv::Point(bounding.x, bounding.br().y - 1);
|
||||
srcTri[1] = cv::Point(bounding.x, bounding.y);
|
||||
srcTri[2] = cv::Point(bounding.br().x - 1, bounding.y);
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
* ====================================================
|
||||
|
||||
* 功能:自动裁剪、纠偏、除黑底
|
||||
* 作者:刘丁绿
|
||||
* 生成时间_020/4/21
|
||||
* 作者:刘丁维
|
||||
* 生成时间:2020/4/21
|
||||
* 最近修改时间:2020/4/21 v1.0
|
||||
2020/7/22 v1.1 增加获取图像有效区域轮廓的接口maxContour(用于配合一体机的“跳过空白页”算法,PC端暂时无需使用_
|
||||
2020/10/16 v1.2 修复自动裁剪尺寸精度丢失的BUG;提高除黑底缩进精度
|
||||
|
@ -29,7 +29,15 @@
|
|||
2022/10/31 v1.5 增加横纵DPI缩放参数fx,fy。
|
||||
2022/11/19 v1.5.1 修复文稿背景色识别算法的BUG。
|
||||
2022/11/19 v1.5.2 修复灰度文稿背景色识别算法的BUG。
|
||||
* 版本号:v1.5.2
|
||||
2023/03/17 v1.5.3 修复背景除噪时,形态学处理kSize可能为0的BUG。
|
||||
2023/04/19 v1.5.4 取消集成色散功能。
|
||||
2023/05/15 v1.5.5 优化文稿背景色识别算法。
|
||||
2023/05/23 v1.5.6 修复纯黑图找不到外界轮廓会导致崩溃的BUG。
|
||||
2023/11/02 v1.6 优化抗噪能力。采用自适应背景色二值化。
|
||||
2023/12/05 v1.6.1 替换获取背景色方案;修复固定幅面裁切纠偏的坐标计算BUG。
|
||||
2023/12/06 v1.6.2 修复固定幅面裁切纠偏的坐标计算BUG。
|
||||
2023/12/07 v1.6.3 修复无纠偏条件下,图像越界导致坐标计算错误的BUG。
|
||||
* 版本号:v1.6.3
|
||||
|
||||
* ====================================================
|
||||
*/
|
||||
|
@ -39,29 +47,28 @@
|
|||
|
||||
#include "ImageApply.h"
|
||||
|
||||
class CImageApplyDispersion;
|
||||
class GIMGPROC_LIBRARY_API CImageApplyAutoCrop : public CImageApply
|
||||
{
|
||||
public:
|
||||
CImageApplyAutoCrop();
|
||||
|
||||
/*
|
||||
* isCrop [in]:自动幅面裁剪使能,true自动裁剪,false为固定裁剿
|
||||
* isDesaskew [in]:自动纠偏使能,true自动纠偏,false为不纠偏
|
||||
* isFillBlank [in]:黑底填充使能,true为填充,false为不填充
|
||||
* fixedSize [in]:固定幅面尺寸,当isCrop为false时生效,结果尺寸按fixedSize大小输出,单位像紿
|
||||
* isConvex [in]:黑底填充时的填充方式,true为凸多边形填充,false为凹多边形填充,默认true
|
||||
* isFillColor [in]:黑底填充时采用自适应色彩填充,false为白色填充,true为自适应文稿底色填充,默认false
|
||||
* threshold [in]:二值化阈值,取值范囿0, 255),默访0
|
||||
* noise [in]:除噪像素,能够消除noise宽度的背景竖条纹干扰,默访
|
||||
* 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
|
||||
*/
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="isCrop">自动幅面裁剪使能,true自动裁剪,false为固定裁切</param>
|
||||
/// <param name="isDesaskew">自动纠偏使能,true自动纠偏,false为不纠偏</param>
|
||||
/// <param name="isFillBlank">黑底填充使能,true为填充,false为不填充</param>
|
||||
/// <param name="fixedSize">固定幅面尺寸,当isCrop为false时生效,结果尺寸按fixedSize大小输出,单位像素</param>
|
||||
/// <param name="isConvex">黑底填充时的填充方式,true为凸多边形填充,false为凹多边形填充,默认true</param>
|
||||
/// <param name="isFillColor">黑底填充时采用自适应色彩填充,false为白色填充,true为自适应文稿底色填充,默认false</param>
|
||||
/// <param name="threshold">二值化阈值,取值范囿[-1, 255],默认40。当threshold<0时,采用根据背景自适应二值化。</param>
|
||||
/// <param name="noise">除噪像素,能够消除noise宽度的背景竖条纹干扰,默认8。</param>
|
||||
/// <param name="indent">轮廓缩进,裁剪、纠偏或者黑底填充时,对探索到的纸张轮廓进行缩进indent像素,默认8</param>
|
||||
/// <param name="normalCrop">为true时,m_isCrop m_isDesaskew m_isFillBlank失效,固定裁切采用最传统的裁切方式,默认false</param>
|
||||
/// <param name="fx">横向缩放比例。默认1.0</param>
|
||||
/// <param name="fy">纵向缩放比例。默认1.0</param>
|
||||
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, double fx = 1.0, double fy = 1.0);
|
||||
bool isFillColor = false, double threshold = 40, int noise = 8, int indent = 5, bool normalCrop = false, double fx = 1.0, double fy = 1.0);
|
||||
|
||||
virtual ~CImageApplyAutoCrop();
|
||||
|
||||
|
@ -105,23 +112,18 @@ public:
|
|||
|
||||
void setFixedSize(cv::Size size) { m_fixedSize = size; }
|
||||
|
||||
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,
|
||||
bool isConvex = true, bool isColorBlank = false, double threshold = 40, int noise = 8, int indent = 5, bool isNormalCrop = false,
|
||||
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 cv::Scalar getBackGroudColor(const cv::Mat& image, int threshold);
|
||||
private:
|
||||
bool m_isCrop;
|
||||
bool m_isDesaskew;
|
||||
bool m_isFillBlank;
|
||||
bool m_isConvexHull;
|
||||
bool m_isFillColor;
|
||||
bool m_isDispersion;
|
||||
|
||||
double m_threshold;
|
||||
int m_noise;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "ImageApplyBWBinaray.h"
|
||||
|
||||
#define THRESHOLD_LOW 30
|
||||
#define THRESHOLD_UP 245
|
||||
CImageApplyBWBinaray::CImageApplyBWBinaray(ThresholdType type, int threshold, int blockSize, int constant)
|
||||
: m_threshold(threshold)
|
||||
, m_type(type)
|
||||
|
@ -27,8 +29,6 @@ CImageApplyBWBinaray::~CImageApplyBWBinaray(void)
|
|||
delete[] m_table;
|
||||
}
|
||||
|
||||
#define THRESHOLD_LOW 30
|
||||
#define THRESHOLD_UP 245
|
||||
void CImageApplyBWBinaray::apply(cv::Mat& pDib, int side)
|
||||
{
|
||||
(void)side;
|
||||
|
@ -40,7 +40,7 @@ void CImageApplyBWBinaray::apply(cv::Mat& pDib, int side)
|
|||
cv::Mat integ;
|
||||
int blockSize = m_blockSize;//邻域尺寸
|
||||
int threshold = m_constant;
|
||||
int low = THRESHOLD_LOW;
|
||||
int low = m_threshold;
|
||||
int up = THRESHOLD_UP;
|
||||
int halfSize = blockSize / 2;
|
||||
int square_blockSize = blockSize * blockSize;
|
||||
|
@ -71,13 +71,13 @@ void CImageApplyBWBinaray::apply(cv::Mat& pDib, int side)
|
|||
cv::threshold(pDib(cv::Rect(0, pDib.rows - halfSize, pDib.cols, halfSize)), pDib(cv::Rect(0, pDib.rows - halfSize, pDib.cols, halfSize)), m_threshold, 255, cv::THRESH_BINARY);
|
||||
break;
|
||||
case ThresholdType::THRESH_OTSU:
|
||||
cv::threshold(pDib, pDib, m_threshold, 255, CV_THRESH_OTSU);
|
||||
cv::threshold(pDib, pDib, m_threshold, 255, cv::THRESH_OTSU);
|
||||
break;
|
||||
case ThresholdType::ADAPTIVE_GAUSSIAN:
|
||||
cv::adaptiveThreshold(pDib, pDib, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, m_blockSize, m_constant);
|
||||
cv::adaptiveThreshold(pDib, pDib, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, m_blockSize, m_constant);
|
||||
break;
|
||||
case ThresholdType::ADAPTIVE_MEAN:
|
||||
cv::adaptiveThreshold(pDib, pDib, 255, cv::ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, m_blockSize, m_constant);
|
||||
cv::adaptiveThreshold(pDib, pDib, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, m_blockSize, m_constant);
|
||||
break;
|
||||
case ThresholdType::ERROR_DIFFUSION:
|
||||
errorDiffuse(pDib);
|
||||
|
@ -108,7 +108,7 @@ void CImageApplyBWBinaray::errorDiffuse(cv::Mat& image)
|
|||
{
|
||||
if (image.rows < 3 || image.cols < 3)
|
||||
{
|
||||
cv::threshold(image, image, m_threshold, 255, CV_THRESH_BINARY);
|
||||
cv::threshold(image, image, m_threshold, 255, cv::THRESH_BINARY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
2020/12/21 v1.3.1 调整自适应阈值上下限
|
||||
2020/12/21 v1.3.2 调整blockSize,从原来的51调整到25
|
||||
2022/05/25 v1.3.3 调整blockSize和constant,对THRESH_BINARY同样有效
|
||||
* 版本号:v1.3.3
|
||||
2023/11/22 v1.4 当THRESH_BINARY模式时,参数m_threshold作为THRESHOLD_LOW使用。
|
||||
* 版本号:v1.4
|
||||
|
||||
* ====================================================
|
||||
*/
|
||||
|
|
|
@ -2,67 +2,152 @@
|
|||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#define JIANG_BAOHE
|
||||
|
||||
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||
constexpr auto SIZE_OF_TABLE = 256;
|
||||
|
||||
CImageApplyColorCastCorrect::CImageApplyColorCastCorrect(PreScheme ps)
|
||||
: m_table_h(new uchar[SIZE_OF_TABLE])
|
||||
, m_table_l(new uchar[SIZE_OF_TABLE])
|
||||
, m_table_s(new uchar[SIZE_OF_TABLE])
|
||||
{
|
||||
std::vector<double> points_x, points_y;
|
||||
|
||||
switch (ps)
|
||||
{
|
||||
case CImageApplyColorCastCorrect::G200:
|
||||
points_x = { 2, 9, 15, 18, 22, 34, 50, 63, 78, 92, 103, 114, 126, 137, 140, 147, 154, 163, 176, 200, 225, 248, 251, 254 };
|
||||
points_y = { 11, 17, 24, 28, 32, 41, 56, 81, 106, 115, 119, 124, 131, 138, 141, 145, 153, 166, 186, 201, 217, 251, 259, 264 };
|
||||
break;
|
||||
case CImageApplyColorCastCorrect::G300:
|
||||
points_x = { 1, 7, 12, 18, 33, 52, 68, 81, 91, 100, 111, 125, 138, 142, 147, 153, 161, 172, 198, 230, 248, 250, 252, 253 };
|
||||
points_y = { 26, 31, 33, 36, 40, 44, 56, 92, 104, 114, 126, 135, 141, 143, 146, 151, 169, 198, 218, 227, 252, 266, 272, 276 };
|
||||
break;
|
||||
case CImageApplyColorCastCorrect::G300_D8:
|
||||
points_x = { 0, 2, 5, 9, 15, 20, 26, 39, 54, 70, 83, 94, 102, 113, 128, 139, 146, 151, 156, 164, 177, 199, 232, 253 };
|
||||
points_y = { 11, 17, 21, 26, 31, 33, 36, 40, 44, 56, 92, 104, 114, 126, 135, 141, 143, 146, 151, 169, 198, 218, 227, 252 };
|
||||
break;
|
||||
case CImageApplyColorCastCorrect::G400_402:
|
||||
points_x = { 2, 8, 15, 20, 27, 41, 50, 67, 80, 91, 99, 109, 124, 138, 145, 150, 157, 164, 177, 202, 232, 250, 252, 255 };
|
||||
points_y = { 21, 26, 31, 33, 36, 40, 44, 56, 92, 104, 114, 126, 135, 141, 143, 146, 151, 169, 198, 218, 227, 252, 266, 272 };
|
||||
break;
|
||||
case CImageApplyColorCastCorrect::G400_3288:
|
||||
points_x = { 2, 3, 5, 7, 11, 16, 19, 25, 40, 57, 72, 84, 95, 101, 111, 126, 144, 148, 152, 157, 165, 179, 203, 234 };
|
||||
points_y = { -3, 11, 17, 21, 26, 31, 33, 36, 40, 44, 56, 92, 104, 114, 126, 135, 141, 143, 146, 151, 169, 198, 218, 227 };
|
||||
break;
|
||||
case CImageApplyColorCastCorrect::Android302:
|
||||
points_x = { 0, 6, 11, 19, 37, 48, 66, 79, 89, 97, 108, 122, 138, 143, 147, 150, 158, 170, 199, 233, 248, 249, 250, 252 };
|
||||
points_y = { 26, 31, 33, 36, 40, 44, 56, 92, 104, 114, 126, 135, 141, 143, 146, 151, 169, 198, 218, 227, 252, 266, 272, 276 };
|
||||
break;
|
||||
case CImageApplyColorCastCorrect::G300_7010:
|
||||
points_x = { 1, 4, 6, 9, 13, 19, 23, 29, 40, 55, 72, 86, 97, 106, 117, 133, 143, 149, 155, 160, 170, 182, 206, 233 };
|
||||
points_y = { 252, 11, 17, 21, 26, 31, 33, 36, 40, 44, 56, 92, 104, 114, 126, 135, 141, 143, 146, 151, 169, 198, 218, 227 };
|
||||
break;
|
||||
default:
|
||||
points_x = { 0, 255 };
|
||||
points_y = { 0, 255 };
|
||||
break;
|
||||
}
|
||||
|
||||
createTable_h(points_x, points_y);
|
||||
|
||||
points_x = { 0, 180, 255 };
|
||||
points_y = { 0, 175, 220 };
|
||||
createTable_l(points_x, points_y);
|
||||
|
||||
points_x = { 0, 230, 255 };
|
||||
points_y = { 0, 210, 255 };
|
||||
createTable_s(points_x, points_y);
|
||||
}
|
||||
|
||||
CImageApplyColorCastCorrect::CImageApplyColorCastCorrect(const std::vector<double>& h_x, const std::vector<double>& h_y,
|
||||
const std::vector<double>& l_x, const std::vector<double>& l_y,
|
||||
const std::vector<double>& s_x, const std::vector<double>& s_y)
|
||||
: m_table_h(new uchar[SIZE_OF_TABLE])
|
||||
, m_table_l(new uchar[SIZE_OF_TABLE])
|
||||
, m_table_s(new uchar[SIZE_OF_TABLE])
|
||||
{
|
||||
if (!h_x.empty() && !h_y.empty())
|
||||
createTable_h(h_x, h_y);
|
||||
if (!l_x.empty() && !l_y.empty())
|
||||
createTable_l(l_x, l_y);
|
||||
if (!s_x.empty() && !s_y.empty())
|
||||
createTable_s(s_x, s_y);
|
||||
}
|
||||
|
||||
CImageApplyColorCastCorrect::CImageApplyColorCastCorrect(const std::vector<double>& points_x, const std::vector<double>& points_y)
|
||||
: m_table(new uchar[SIZE_OF_TABLE])
|
||||
: m_table_h(new uchar[SIZE_OF_TABLE])
|
||||
, m_table_l(new uchar[SIZE_OF_TABLE])
|
||||
, m_table_s(new uchar[SIZE_OF_TABLE])
|
||||
{
|
||||
createTable(points_x, points_y);
|
||||
createTable_h(points_x, points_y);
|
||||
|
||||
for (size_t i = 0; i < SIZE_OF_TABLE; i++)
|
||||
m_table_l[i] = m_table_s[i] = i;
|
||||
}
|
||||
|
||||
CImageApplyColorCastCorrect::CImageApplyColorCastCorrect(const std::string& fileName)
|
||||
: m_table(new uchar[SIZE_OF_TABLE])
|
||||
: m_table_h(new uchar[SIZE_OF_TABLE])
|
||||
, m_table_l(new uchar[SIZE_OF_TABLE])
|
||||
, m_table_s(new uchar[SIZE_OF_TABLE])
|
||||
{
|
||||
std::fstream file(fileName, std::ios::in | std::ios::binary);
|
||||
if (file)
|
||||
file.read(reinterpret_cast<char*>(m_table), SIZE_OF_TABLE);
|
||||
file.read(reinterpret_cast<char*>(m_table_h), SIZE_OF_TABLE);
|
||||
file.close();
|
||||
|
||||
for (size_t i = 0; i < SIZE_OF_TABLE; i++)
|
||||
m_table_l[i] = m_table_s[i] = i;
|
||||
}
|
||||
|
||||
CImageApplyColorCastCorrect::CImageApplyColorCastCorrect(const uchar* table_h)
|
||||
: m_table(new uchar[SIZE_OF_TABLE])
|
||||
: m_table_h(new uchar[SIZE_OF_TABLE])
|
||||
, m_table_l(new uchar[SIZE_OF_TABLE])
|
||||
, m_table_s(new uchar[SIZE_OF_TABLE])
|
||||
{
|
||||
memcpy(m_table, table_h, SIZE_OF_TABLE);
|
||||
}
|
||||
|
||||
CImageApplyColorCastCorrect::CImageApplyColorCastCorrect(const int type)
|
||||
: m_table(new uchar[SIZE_OF_TABLE])
|
||||
{
|
||||
if(type == 1)
|
||||
memcpy(m_table,CIS_DN_PATCH1,SIZE_OF_TABLE);
|
||||
else
|
||||
memcpy(m_table,CIS_DN_PATCH2,SIZE_OF_TABLE);
|
||||
memcpy(m_table_h, table_h, SIZE_OF_TABLE);
|
||||
for (size_t i = 0; i < SIZE_OF_TABLE; i++)
|
||||
m_table_l[i] = m_table_s[i] = i;
|
||||
}
|
||||
|
||||
CImageApplyColorCastCorrect::~CImageApplyColorCastCorrect(void)
|
||||
{
|
||||
delete[] m_table;
|
||||
}
|
||||
|
||||
void CImageApplyColorCastCorrect::setlutdata(const int type)
|
||||
{
|
||||
if(type == 1) memcpy(m_table,CIS_DN_PATCH1,SIZE_OF_TABLE);
|
||||
else memcpy(m_table,CIS_DN_PATCH2,SIZE_OF_TABLE);
|
||||
delete[] m_table_h;
|
||||
delete[] m_table_l;
|
||||
delete[] m_table_s;
|
||||
}
|
||||
|
||||
void CImageApplyColorCastCorrect::apply(cv::Mat& pDib, int side)
|
||||
{
|
||||
if (pDib.channels() != 3)
|
||||
return;
|
||||
|
||||
cv::Mat hsv;
|
||||
cv::cvtColor(pDib, hsv, cv::COLOR_BGR2HSV_FULL);
|
||||
cv::cvtColor(pDib, hsv, cv::COLOR_BGR2HLS_FULL);
|
||||
|
||||
cv::Mat hsv_mv[3];
|
||||
cv::split(hsv, hsv_mv);
|
||||
|
||||
cv::Mat lut(256, 1, CV_8UC1, m_table);
|
||||
//cv::imwrite("hsv_0.jpg", hsv_mv[0]);
|
||||
cv::Mat lut(256, 1, CV_8UC1, m_table_h);
|
||||
cv::LUT(hsv_mv[0], lut, hsv_mv[0]);
|
||||
|
||||
#ifdef JIANG_BAOHE
|
||||
//hsv_mv[2] -= 20;
|
||||
//cv::imwrite("hsv_0.jpg", hsv_mv[0]);
|
||||
//cv::imwrite("hsv_1.jpg", hsv_mv[1]);
|
||||
//cv::imwrite("hsv_2.jpg", hsv_mv[2]);
|
||||
cv::Mat lut2(256, 1, CV_8UC1, m_table_l);
|
||||
cv::LUT(hsv_mv[2], lut2, hsv_mv[2]);
|
||||
|
||||
//hsv_mv[1] -= 20;
|
||||
//cv::Mat lut3(256, 1, CV_8UC1, m_table3);
|
||||
//cv::LUT(hsv_mv[1], lut3, hsv_mv[1]);
|
||||
#endif
|
||||
cv::merge(hsv_mv, 3, pDib);
|
||||
|
||||
cv::cvtColor(pDib, pDib, cv::COLOR_HSV2BGR_FULL);
|
||||
cv::cvtColor(pDib, pDib, cv::COLOR_HLS2BGR_FULL);
|
||||
}
|
||||
|
||||
void CImageApplyColorCastCorrect::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
||||
|
@ -82,11 +167,11 @@ void CImageApplyColorCastCorrect::exportTableData(const std::string& fileName)
|
|||
{
|
||||
std::fstream file(fileName, std::ios::out | std::ios::binary);
|
||||
if (file)
|
||||
file.write(reinterpret_cast<char*>(m_table), SIZE_OF_TABLE);
|
||||
file.write(reinterpret_cast<char*>(m_table_h), SIZE_OF_TABLE);
|
||||
file.close();
|
||||
}
|
||||
|
||||
void CImageApplyColorCastCorrect::createTable(const std::vector<double>& points_x, const std::vector<double>& points_y)
|
||||
void CImageApplyColorCastCorrect::createTable_h(const std::vector<double>& points_x, const std::vector<double>& points_y)
|
||||
{
|
||||
int table_temp[256]{};
|
||||
|
||||
|
@ -118,9 +203,48 @@ void CImageApplyColorCastCorrect::createTable(const std::vector<double>& points_
|
|||
|
||||
for (size_t j = 0; j < 256; j++)
|
||||
if (table_temp[j] > 255)
|
||||
m_table[j] = table_temp[j] - 255;
|
||||
m_table_h[j] = table_temp[j] - 255;
|
||||
else
|
||||
m_table[j] = table_temp[j];
|
||||
m_table_h[j] = table_temp[j];
|
||||
}
|
||||
}
|
||||
|
||||
void CImageApplyColorCastCorrect::createTable_l(const std::vector<double>& points_x, const std::vector<double>& points_y)
|
||||
{
|
||||
memset(m_table_l, 255, 256);
|
||||
memset(m_table_l, 0, 127);
|
||||
int s = 1;
|
||||
for (int i = 0; i < points_x.size() - s; i += s)
|
||||
{
|
||||
double low = points_y[i];
|
||||
double up = points_y[i + s];
|
||||
|
||||
int start = points_x[i];
|
||||
int end = points_x[i + s];
|
||||
|
||||
int length = end - start;
|
||||
double step = (up - low) / length;
|
||||
for (int j = 0; j < length; j++)
|
||||
m_table_l[start + j] = max(0.0, min(255.0, low + j * step));
|
||||
}
|
||||
}
|
||||
|
||||
void CImageApplyColorCastCorrect::createTable_s(const std::vector<double>& points_x, const std::vector<double>& points_y)
|
||||
{
|
||||
memset(m_table_s, 255, 256);
|
||||
memset(m_table_s, 0, 127);
|
||||
int s = 1;
|
||||
for (int i = 0; i < points_x.size() - s; i += s)
|
||||
{
|
||||
double low = points_y[i];
|
||||
double up = points_y[i + s];
|
||||
|
||||
int start = points_x[i];
|
||||
int end = points_x[i + s];
|
||||
|
||||
int length = end - start;
|
||||
double step = (up - low) / length;
|
||||
for (int j = 0; j < length; j++)
|
||||
m_table_s[start + j] = max(0.0, min(255.0, low + j * step));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* ====================================================
|
||||
|
||||
* 功能:色偏校正
|
||||
|
@ -10,7 +10,12 @@
|
|||
* v1.2 2023/04/04 提高曲线拐点数,增加预设方案CIS_DN_PATCH3
|
||||
* v1.3 2023/04/17 增加新查值表导入方式。
|
||||
* v2.0 2023/05/15 重构查值表算法。
|
||||
* 版本号:v2.0
|
||||
* v2.1 2023/10/07 添加饱和度、亮度调节,当前暂不开放参数设置接口。
|
||||
* v2.2 2023/11/13 增加预设方案
|
||||
* v2.2.1 2023/11/13 调整枚举类型词条
|
||||
* v2.2.2 2023/11/17 屏蔽无用代码
|
||||
* v2.2.3 2023/11/17 调整饱和度校正系数
|
||||
* 版本号:v2.2.3
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
|
@ -23,45 +28,24 @@ class GIMGPROC_LIBRARY_API CImageApplyColorCastCorrect : public CImageApply
|
|||
{
|
||||
public:
|
||||
|
||||
const uchar CIS_DN_PATCH2[256] = //摩尔纹慢速扫描色偏参数
|
||||
//预设方案
|
||||
enum PreScheme
|
||||
{
|
||||
0x10, 0x11, 0x13, 0x14, 0x16, 0x17, 0x1B, 0x1B, 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F,
|
||||
0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x24, 0x24, 0x24, 0x25, 0x25, 0x25,
|
||||
0x26, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x2A, 0x2A, 0x2A, 0x2B, 0x2B,
|
||||
0x2B, 0x2C, 0x2C, 0x2C, 0x2D, 0x2D, 0x2D, 0x2E, 0x2E, 0x2E, 0x2F, 0x2F, 0x2F, 0x30, 0x30, 0x30,
|
||||
0x31, 0x31, 0x31, 0x32, 0x33, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E, 0x40, 0x42, 0x44, 0x46, 0x48,
|
||||
0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5A, 0x5C, 0x5E, 0x62, 0x63, 0x65, 0x66, 0x68,
|
||||
0x69, 0x6B, 0x6C, 0x6E, 0x6F, 0x71, 0x72, 0x74, 0x75, 0x77, 0x78, 0x7A, 0x7B, 0x7D, 0x7E, 0x82,
|
||||
0x82, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x88, 0x89, 0x89,
|
||||
0x8A, 0x8A, 0x8B, 0x8B, 0x8C, 0x8C, 0x8D, 0x8D, 0x8E, 0x8E, 0x8F, 0x90, 0x90, 0x90, 0x91, 0x91,
|
||||
0x92, 0x92, 0x93, 0x93, 0x94, 0x94, 0x95, 0x96, 0x97, 0x99, 0x9B, 0x9D, 0x9F, 0xA1, 0xA3, 0xA4,
|
||||
0xA6, 0xA8, 0xAA, 0xAC, 0xAE, 0xB2, 0xB3, 0xB4, 0xB6, 0xB7, 0xB8, 0xBA, 0xBB, 0xBC, 0xBE, 0xBF,
|
||||
0xC1, 0xC2, 0xC3, 0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCD, 0xCE, 0xD0, 0xD1, 0xD2, 0xD4, 0xD5,
|
||||
0xD6, 0xD8, 0xD9, 0xDA, 0xDC, 0xDF, 0xDF, 0xE0, 0xE0, 0xE1, 0xE1, 0xE2, 0xE3, 0xE3, 0xE4, 0xE4,
|
||||
0xE5, 0xE6, 0xE6, 0xE7, 0xE7, 0xE8, 0xE9, 0xE9, 0xEA, 0xEA, 0xEB, 0xEC, 0xEC, 0xED, 0xED, 0xEE,
|
||||
0xEF, 0xEF, 0xF0, 0xF0, 0xF1, 0xF1, 0xF2, 0xF3, 0xF3, 0xF4, 0xF4, 0xF5, 0xF6, 0xF6, 0xF7, 0xF7,
|
||||
0xF8, 0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0x02, 0x05, 0x08, 0x0A, 0x0D
|
||||
G200,
|
||||
G300,
|
||||
G300_D8,
|
||||
G300_7010,
|
||||
G400_402,
|
||||
G400_3288,
|
||||
Android302
|
||||
};
|
||||
|
||||
const uchar CIS_DN_PATCH1[256] = //正常扫描色偏参数
|
||||
{
|
||||
0x10, 0x11, 0x13, 0x14, 0x16, 0x17, 0x1B, 0x1B, 0x1B, 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F,
|
||||
0x1F, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25, 0x25,
|
||||
0x26, 0x26, 0x26, 0x27, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x2A, 0x2A, 0x2A, 0x2B, 0x2B, 0x2B,
|
||||
0x2C, 0x2C, 0x2C, 0x2D, 0x2D, 0x2D, 0x2E, 0x2E, 0x2E, 0x2F, 0x2F, 0x2F, 0x30, 0x30, 0x30, 0x31,
|
||||
0x31, 0x31, 0x32, 0x32, 0x33, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E, 0x40, 0x42, 0x44, 0x46, 0x48,
|
||||
0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5A, 0x5C, 0x5E, 0x62, 0x63, 0x65, 0x66, 0x68,
|
||||
0x6A, 0x6B, 0x6D, 0x6E, 0x70, 0x72, 0x73, 0x75, 0x76, 0x78, 0x7A, 0x7B, 0x7D, 0x7E, 0x82, 0x82,
|
||||
0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x88, 0x89, 0x89, 0x89,
|
||||
0x8A, 0x8A, 0x8B, 0x8B, 0x8C, 0x8C, 0x8D, 0x8D, 0x8E, 0x8E, 0x8F, 0x90, 0x90, 0x90, 0x91, 0x91,
|
||||
0x92, 0x92, 0x93, 0x93, 0x94, 0x94, 0x95, 0x96, 0x98, 0x9A, 0x9C, 0x9E, 0xA0, 0xA2, 0xA4, 0xA6,
|
||||
0xA8, 0xAA, 0xAC, 0xAE, 0xB2, 0xB3, 0xB4, 0xB6, 0xB7, 0xB8, 0xBA, 0xBB, 0xBC, 0xBE, 0xBF, 0xC1,
|
||||
0xC2, 0xC3, 0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCD, 0xCE, 0xD0, 0xD1, 0xD2, 0xD4, 0xD5, 0xD6,
|
||||
0xD8, 0xD9, 0xDA, 0xDC, 0xDF, 0xDF, 0xE0, 0xE0, 0xE1, 0xE1, 0xE2, 0xE3, 0xE3, 0xE4, 0xE4, 0xE5,
|
||||
0xE5, 0xE6, 0xE7, 0xE7, 0xE8, 0xE8, 0xE9, 0xE9, 0xEA, 0xEB, 0xEB, 0xEC, 0xEC, 0xED, 0xED, 0xEE,
|
||||
0xEF, 0xEF, 0xF0, 0xF0, 0xF1, 0xF1, 0xF2, 0xF3, 0xF3, 0xF4, 0xF4, 0xF5, 0xF5, 0xF6, 0xF7, 0xF7,
|
||||
0xF8, 0xF8, 0xF9, 0xF9, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0x02, 0x05, 0x08, 0x0A
|
||||
};
|
||||
CImageApplyColorCastCorrect(PreScheme ps = G200);
|
||||
|
||||
CImageApplyColorCastCorrect(const std::vector<double>& h_x, const std::vector<double>& h_y,
|
||||
const std::vector<double>& l_x, const std::vector<double>& l_y,
|
||||
const std::vector<double>& s_x, const std::vector<double>& s_y);
|
||||
|
||||
/// <summary>
|
||||
/// 用户自定义查值表
|
||||
/// </summary>
|
||||
|
@ -81,14 +65,6 @@ public:
|
|||
/// <param name="table_h"></param>
|
||||
CImageApplyColorCastCorrect(const uchar* table_h);
|
||||
|
||||
/// <summary>
|
||||
/// 选择设置HSV中H通道的LUT校正数据
|
||||
/// </summary>
|
||||
/// <param name="table_h"></param>
|
||||
CImageApplyColorCastCorrect(const int type);
|
||||
|
||||
void setlutdata(const int type);
|
||||
|
||||
virtual ~CImageApplyColorCastCorrect(void);
|
||||
|
||||
virtual void apply(cv::Mat& pDib, int side);
|
||||
|
@ -103,9 +79,11 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
void createTable(const std::vector<double>& points_x, const std::vector<double>& points_y);
|
||||
void createTable_h(const std::vector<double>& points_x, const std::vector<double>& points_y);
|
||||
void createTable_l(const std::vector<double>& points_x, const std::vector<double>& points_y);
|
||||
void createTable_s(const std::vector<double>& points_x, const std::vector<double>& points_y);
|
||||
private:
|
||||
uchar* m_table;
|
||||
uchar* m_table_h, *m_table_l, *m_table_s;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,45 +1,4 @@
|
|||
#include "ImageApplyColorRecognition.h"
|
||||
#include "ImageApplyHeaders.h"
|
||||
|
||||
//static CImageApplyBWBinaray m_bw;
|
||||
//static CImageApplyAdjustColors m_ac(0, 50, 1.0f);
|
||||
|
||||
/// <summary>
|
||||
/// 检测图像是否是彩色。当前逻辑仅针对红色像素进行判断,即存在红色像素则为彩色,否则为非彩色
|
||||
/// </summary>
|
||||
/// <param name="image">待测图像</param>
|
||||
/// <returns>true为彩色,false为非彩色</returns>
|
||||
bool isColor(const cv::Mat& image)
|
||||
{
|
||||
if (image.channels() != 3) return false;
|
||||
|
||||
cv::Mat pDib_resize;
|
||||
cv::resize(image, pDib_resize, cv::Size(image.cols / 4, image.rows / 4), 0, 0, cv::INTER_NEAREST);
|
||||
|
||||
cv::Mat hsv;
|
||||
cv::cvtColor(pDib_resize, hsv, cv::COLOR_BGR2HSV_FULL);
|
||||
std::vector<cv::Mat> hsv_channels;
|
||||
cv::split(hsv, hsv_channels);
|
||||
|
||||
cv::Mat range_s1, range_s2;
|
||||
cv::inRange(hsv_channels[1], 220, 255, range_s1); //饱和度在[220, 255]的像素
|
||||
cv::inRange(hsv_channels[1], 50, 220, range_s2); //饱和度在[50, 220]的像素
|
||||
#if 0
|
||||
cv::imwrite("range_s1.bmp", range_s1);
|
||||
cv::imwrite("range_s2.bmp", range_s2);
|
||||
#endif
|
||||
double sum = cv::sum(range_s1)[0] / 255;
|
||||
double total = range_s1.total();
|
||||
|
||||
// if (sum / total > 0.0001)
|
||||
if (sum / total > 0.001)
|
||||
return true;
|
||||
sum += cv::sum(range_s2)[0] / 255;
|
||||
// if (sum / total > 0.001)
|
||||
if (sum / total > 0.03)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isGray(const cv::Mat& image)
|
||||
{
|
||||
|
@ -80,6 +39,7 @@ CImageApplyColorRecognition::~CImageApplyColorRecognition(void)
|
|||
{
|
||||
}
|
||||
|
||||
#define HSV_S_THRE 30
|
||||
void CImageApplyColorRecognition::apply(cv::Mat& pDib, int side)
|
||||
{
|
||||
if (pDib.channels() != 3)
|
||||
|
@ -87,7 +47,7 @@ void CImageApplyColorRecognition::apply(cv::Mat& pDib, int side)
|
|||
m_result = Gray;
|
||||
return;
|
||||
}
|
||||
m_result = isColor(pDib) ? Color : Gray;
|
||||
m_result = isColor(pDib, HSV_S_THRE) ? Color : Gray;
|
||||
if (m_result == Gray && pDib.channels() == 3)
|
||||
cv::cvtColor(pDib, pDib, cv::COLOR_BGR2GRAY);
|
||||
|
||||
|
@ -153,3 +113,26 @@ std::vector<CImageApplyColorRecognition::ColorType> CImageApplyColorRecognition:
|
|||
{
|
||||
return m_results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测图像是否是彩色。当前逻辑仅针对红色像素进行判断,即存在红色像素则为彩色,否则为非彩色
|
||||
/// </summary>
|
||||
/// <param name="image">待测图像</param>
|
||||
/// <returns>true为彩色,false为非彩色</returns>
|
||||
bool CImageApplyColorRecognition::isColor(const cv::Mat& image, double threshold)
|
||||
{
|
||||
if (image.channels() != 3) return false;
|
||||
|
||||
cv::Mat pDib_resize;
|
||||
cv::resize(image, pDib_resize, cv::Size(200, 200), 0, 0, cv::INTER_AREA);
|
||||
//cv::imwrite("pDib_resize.bmp", pDib_resize);
|
||||
cv::Mat hsv;
|
||||
cv::cvtColor(pDib_resize, hsv, cv::COLOR_BGR2HSV_FULL);
|
||||
std::vector<cv::Mat> hsv_channels;
|
||||
cv::split(hsv, hsv_channels);
|
||||
|
||||
double minVal, maxVal;
|
||||
cv::minMaxLoc(hsv_channels[1], &minVal, &maxVal);
|
||||
|
||||
return maxVal > threshold;
|
||||
}
|
||||
|
|
|
@ -4,12 +4,14 @@
|
|||
* 功能:色彩识别,将识别会“灰度”的24位图转化为256色8位图, 把识别为“黑白”图转化为二值化的8位图
|
||||
* 作者:刘丁维
|
||||
* 生成时间:2020/7/17
|
||||
* 最近修改时间:2021/04/19
|
||||
* 版本号:v1.0 2020/7/17
|
||||
* v1.1 2020/12/15 调整策略,仅判断红色像素,存在红色像素为彩色,否则为灰度;删除输出结果,直接转换图像。
|
||||
* v1.2 2020/12/16 增加颜色限制模式(输出结果只可能两种),增加结果访问接口
|
||||
* v1.3 2021/04/19 修改识别策略,能够识别占比1‰的彩色图像。只区分彩色和灰度图。
|
||||
* v1.4 2021/06/18 调整二级色彩区间,从原来的[90, 200]调整为[50, 200]。
|
||||
* 最近修改时间:v1.0 2020/7/17
|
||||
* v1.1 2020/12/15 调整策略,仅判断红色像素,存在红色像素为彩色,否则为灰度;删除输出结果,直接转换图像。
|
||||
* v1.2 2020/12/16 增加颜色限制模式(输出结果只可能两种),增加结果访问接口
|
||||
* v1.3 2021/04/19 修改识别策略,能够识别占比1‰的彩色图像。只区分彩色和灰度图。
|
||||
* v1.4 2021/06/18 调整二级色彩区间,从原来的[90, 200]调整为[50, 200]。
|
||||
* v1.5 2023/11/22 调整彩色判定策略。
|
||||
* v1.5.1 2023//11/28 调整饱和度判定阈值
|
||||
* 版本号:v1.5.1
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
|
@ -59,6 +61,9 @@ public:
|
|||
/// <returns>色彩类型数组</returns>
|
||||
std::vector<ColorType> getResults();
|
||||
|
||||
private:
|
||||
bool isColor(const cv::Mat& image, double threshold = 30);
|
||||
|
||||
private:
|
||||
ColorType m_result;
|
||||
std::vector<ColorType> m_results;
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
#include "ImageApplyDiscardBlank.h"
|
||||
#include "ImageProcess_Public.h"
|
||||
|
||||
CImageApplyDiscardBlank::CImageApplyDiscardBlank(double threshold, int edge, double devTh, double meanTh)
|
||||
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 +16,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,35 +33,46 @@ 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)
|
||||
bool maxMinCompare(const cv::Mat& img, const cv::Mat& mask, double devTh, double bgc)
|
||||
{
|
||||
double min, max;
|
||||
cv::minMaxLoc(img, &min, &max, 0, 0, mask);
|
||||
if (cv::mean(img, mask)[0] < meanTh)
|
||||
return false;
|
||||
return (max - min) < devTh;
|
||||
|
||||
return abs(max - bgc) < devTh && abs(min - bgc) < devTh;
|
||||
}
|
||||
|
||||
bool CImageApplyDiscardBlank::apply(const cv::Mat& pDib, double threshold, int edge, double devTh, double meanTh)
|
||||
static int a = 0;
|
||||
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);
|
||||
double resizeScale = 1.0;
|
||||
while ((pDib.cols * resizeScale > 500) && (pDib.rows * resizeScale > 500))
|
||||
resizeScale /= 2;
|
||||
|
||||
cv::Mat img_resize;
|
||||
cv::resize(pDib, img_resize, cv::Size(), resizeScale, resizeScale, cv::INTER_LINEAR);
|
||||
//cv::dilate(img_resize, img_resize, cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(dilate, dilate)));
|
||||
cv::blur(img_resize, img_resize, cv::Size(dilate, dilate));
|
||||
|
||||
cv::Scalar bgc = hg::getBackGroundColor(img_resize, cv::Mat(), 20);
|
||||
if (pDib.channels() == 3)
|
||||
if ((bgc[0] + bgc[1] + bgc[2]) < meanTh * 3)
|
||||
return false;
|
||||
if (pDib.channels() == 1)
|
||||
if (bgc[0] < meanTh )
|
||||
return false;
|
||||
|
||||
//cv::imwrite(std::to_string(a) + "r.jpg", img_resize);
|
||||
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(threshold_img, threshold_img, threshold, 255, cv::THRESH_BINARY);
|
||||
}
|
||||
else
|
||||
cv::threshold(img_resize, threshold_img, threshold, 255, cv::THRESH_BINARY);
|
||||
|
||||
std::vector<std::vector<cv::Point>> contours;
|
||||
std::vector<cv::Vec4i> h1;
|
||||
|
@ -72,21 +84,20 @@ 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 * resizeScale * 2, rect.size.height - edge * resizeScale * 2);
|
||||
cv::Point2f box[4];
|
||||
rect.points(box);
|
||||
|
||||
contour.clear();
|
||||
contours.clear();
|
||||
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
contour.push_back(box[i]);
|
||||
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));
|
||||
|
||||
//cv::imwrite(std::to_string(a) + "m.jpg", mask);
|
||||
a++;
|
||||
bool b = true;
|
||||
if (img_resize.channels() == 3)
|
||||
{
|
||||
|
@ -94,23 +105,11 @@ bool CImageApplyDiscardBlank::apply(const cv::Mat& pDib, double threshold, int e
|
|||
cv::split(img_resize, bgr);
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
{
|
||||
b &= maxMinCompare(bgr[i], mask, devTh, meanTh);
|
||||
b &= maxMinCompare(bgr[i], mask, devTh, bgc[i]);
|
||||
if (!b) break;
|
||||
}
|
||||
}
|
||||
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);
|
||||
}*/
|
||||
|
||||
b &= maxMinCompare(img_resize, mask, devTh, bgc[0]);
|
||||
return b;
|
||||
}
|
||||
|
|
|
@ -5,20 +5,30 @@
|
|||
* 作者:刘丁维
|
||||
* 生成时间:2020/4/21
|
||||
* 最近修改时间:2020/4/21 v1.0
|
||||
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版本导致计算结果存在差异的代码。
|
||||
2021/12/14 v1.3.2 重构算法。
|
||||
2021/12/15 v1.3.3 微调参数。
|
||||
2021/12/17 v1.3.4 增加背景色接口,实现对纯色纸张的空白页判定
|
||||
2022/09/07 v1.3.5 修复部分参数传递的BUG
|
||||
2022/09/19 v1.4 增加模糊处理,提高空白页的过滤能力
|
||||
2022/09/19 v1.4.1 调整模糊处理步骤
|
||||
2022/11/18 v1.4.2 调整默认参数
|
||||
* 版本号:v1.4.2
|
||||
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版本导致计算结果存在差异的代码。
|
||||
2021/12/14 v1.3.2 重构算法。
|
||||
2021/12/15 v1.3.3 微调参数。
|
||||
2021/12/17 v1.3.4 增加背景色接口,实现对纯色纸张的空白页判定
|
||||
2022/09/07 v1.3.5 修复部分参数传递的BUG
|
||||
2022/09/19 v1.4 增加模糊处理,提高空白页的过滤能力
|
||||
2022/09/19 v1.4.1 调整模糊处理步骤
|
||||
2022/11/18 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 优化JPEG文件大小判断空白页
|
||||
2023/10/30 v1.7 调整JPEG文件大小判断空白页的算法接口
|
||||
2023/11/04 v1.7.1 增加PNG二值化文件大小判断空白页的选项
|
||||
2023/12/01 v1.8 取消JPEG/PNG文件大小判断空白页方案
|
||||
2023/12/04 v1.9 提高算法效率。
|
||||
2023/12/05 v1.9.1 修改错误代码;修改参数注释。
|
||||
2023/12/08 v1.10 调整空白页判定条件。修复mask精度bug。
|
||||
* 版本号:v1.10
|
||||
|
||||
* ====================================================
|
||||
*/
|
||||
|
@ -31,17 +41,16 @@
|
|||
class GIMGPROC_LIBRARY_API CImageApplyDiscardBlank : public CImageApply
|
||||
{
|
||||
public:
|
||||
|
||||
/// <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时,纯色文稿均为非空白页)。取值范围[0, 255]</param>
|
||||
/// <param name="dilate">忽略纸张杂点。取值3、5、7、9...</param>
|
||||
CImageApplyDiscardBlank(double threshold = 40, int edge = 50, double devTh = 30, double meanTh = 0, int dilate = 3);
|
||||
|
||||
virtual ~CImageApplyDiscardBlank(void);
|
||||
|
||||
|
@ -50,21 +59,23 @@ 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>
|
||||
/// <returns></returns>
|
||||
static bool apply(const cv::Mat& pDib, double threshold = 40, int edge = 50, double devTh = 30, double meanTh = 200);
|
||||
/// <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);
|
||||
|
||||
private:
|
||||
double m_threshold;
|
||||
int m_edge;
|
||||
double m_devTh;
|
||||
double m_meanTh;
|
||||
int m_dilate;
|
||||
};
|
||||
|
||||
#endif // !IMAGE_APPLY_DISCARD_BLANK_H
|
|
@ -1,17 +1,11 @@
|
|||
#include "ImageApplyFadeBackGroundColor.h"
|
||||
|
||||
#include "ImageProcess_Public.h"
|
||||
|
||||
CImageApplyFadeBackGroudColor::CImageApplyFadeBackGroudColor(int threshold, int offset, int range)
|
||||
: m_threshold(threshold)
|
||||
, m_offset(offset)
|
||||
, m_range(range)
|
||||
{
|
||||
memset(m_table1, 255, 768);
|
||||
memset(m_table1, 0, m_threshold * 3);
|
||||
|
||||
memset(m_table2, 255, 256 * 3);
|
||||
for (size_t i = 0; i < 256; i++)
|
||||
m_table2[i] = i;
|
||||
}
|
||||
|
||||
CImageApplyFadeBackGroudColor::~CImageApplyFadeBackGroudColor()
|
||||
|
@ -48,98 +42,33 @@ void CImageApplyFadeBackGroudColor::apply(cv::Mat& pDib, int side)
|
|||
|
||||
cv::add(pDib, cv::Scalar::all(255 + m_offset) - mean_bgr, pDib, mask);
|
||||
#else
|
||||
#if 0
|
||||
fadeBackground(pDib.data, pDib.cols, pDib.rows, pDib.step, m_threshold, m_offset, m_range);
|
||||
#else
|
||||
fadeBackground(pDib, m_threshold, m_offset, m_range);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 除文稿底色算法,仅支持24位图像
|
||||
/// </summary>
|
||||
/// <param name="data">图像数据头指针</param>
|
||||
/// <param name="bytesPerLine">每行数据大小</param>
|
||||
/// <param name="height">图像高度</param>
|
||||
/// <param name="threshold">阈值,参考值为100</param>
|
||||
/// <param name="offset">文稿底色增亮偏移量,默认为0。值越大,背景越白,反之越暗</param>
|
||||
void CImageApplyFadeBackGroudColor::fadeBackground(unsigned char* data, int width, int height, int bytesPerLine, int threshold, int offset, int range)
|
||||
void CImageApplyFadeBackGroudColor::fadeBackground(cv::Mat& image, int threshold, int offset, int range)
|
||||
{
|
||||
memset(m_table1, 255, 768);
|
||||
memset(m_table1, 0, threshold * 3);
|
||||
memset(m_table2, 255, 256 * 3);
|
||||
cv::Mat resizeMat;
|
||||
cv::resize(image, resizeMat, cv::Size(200, 200));
|
||||
cv::Mat mask;
|
||||
cv::cvtColor(resizeMat, mask, cv::COLOR_BGR2GRAY);
|
||||
cv::threshold(mask, mask, threshold, 255, cv::THRESH_BINARY);
|
||||
|
||||
for (uint i = 0; i < 256; i++)
|
||||
m_table2[i] = i;
|
||||
cv::Scalar bgc = hg::getBackGroundColor(resizeMat, mask, threshold);
|
||||
|
||||
int hist_bgr[3][256] = { 0 };
|
||||
|
||||
unsigned char* mask = new unsigned char[width * height];
|
||||
unsigned char* ptr_data = data;
|
||||
unsigned char* ptr_mask = mask;
|
||||
unsigned char b = 0;
|
||||
|
||||
for (uint i = 0; i < height; i++, ptr_data += bytesPerLine, ptr_mask += width)
|
||||
for (uint j = 0, x = 0; j < width; j++, x += 3)
|
||||
{
|
||||
b = m_table1[ptr_data[x] + ptr_data[x + 1] + ptr_data[x + 2]];
|
||||
ptr_mask[j] = b;
|
||||
for (uint k = 0; k < 3; k++)
|
||||
hist_bgr[k][ptr_data[x + k] & b]++;
|
||||
}
|
||||
|
||||
int max_vals[3] = { 0 };
|
||||
int max_indexes[3] = { 0 };
|
||||
|
||||
for (uint i = 1; 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;
|
||||
}
|
||||
|
||||
uchar table_rgb[3][256] = { 0 };
|
||||
for (uint i = 0; i < 3; i++)
|
||||
std::vector<int> low, up;
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
{
|
||||
int start = cv::max(max_indexes[i] - range, 0);
|
||||
int end = cv::min(max_indexes[i] + range, 255);
|
||||
memset(table_rgb[i] + start, 255, cv::min(end - start + 1, 256 - start));
|
||||
low.push_back(cv::max((int)bgc[i] - range, 0));
|
||||
up.push_back(cv::min((int)bgc[i] + range, 255));
|
||||
}
|
||||
|
||||
ptr_data = data;
|
||||
ptr_mask = mask;
|
||||
for (uint i = 0; i < height; i++, ptr_data += bytesPerLine, ptr_mask += width)
|
||||
for (uint j = 0, x = 0; j < width; j++, x += 3)
|
||||
ptr_mask[j] &= table_rgb[0][ptr_data[x]] & table_rgb[1][ptr_data[x + 1]] & table_rgb[2][ptr_data[x + 2]];
|
||||
|
||||
unsigned char offset_rgb[3];
|
||||
for (uint i = 0; i < 3; i++)
|
||||
offset_rgb[i] = 255 + offset - max_indexes[i];
|
||||
|
||||
#if 1
|
||||
ptr_data = data;
|
||||
ptr_mask = mask;
|
||||
for (uint i = 0; i < height; i++, ptr_data += bytesPerLine, ptr_mask += width)
|
||||
for (uint j = 0, x = 0; j < width; j++, x += 3)
|
||||
for (uint k = 0; k < 3; k++)
|
||||
ptr_data[x + k] = m_table2[(int)ptr_data[x + k] + (offset_rgb[k] & ptr_mask[j])];
|
||||
#else
|
||||
for (uint c = 0; c < 3; c++)
|
||||
{
|
||||
ptr_data = data + c;
|
||||
ptr_mask = mask;
|
||||
for (uint y = 0; y < height; y++)
|
||||
{
|
||||
int ptr_x = 0;
|
||||
for (uint x = 0; x < width; x++)
|
||||
{
|
||||
ptr_data[ptr_x] = m_table2[(int)ptr_data[ptr_x] + (offset_rgb[c] & ptr_mask[x])];
|
||||
ptr_x += 3;
|
||||
}
|
||||
ptr_data += bytesPerLine;
|
||||
ptr_mask += width;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
delete[] mask;
|
||||
cv::inRange(image, low, up, mask);
|
||||
cv::add(image, cv::Scalar::all(offset), image, mask);
|
||||
}
|
||||
|
||||
void CImageApplyFadeBackGroudColor::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
* 2021/10/29 v3.3 优化算法,增加range参数。针对复杂内容的图像,能够有效甄别背景和非背景内容。
|
||||
* 2022/03/08 v3.4 修复变量未初始化的BUG。
|
||||
* 2022/10/22 v3.5 使opencv ROI的内存机制。
|
||||
* 版本号:v3.5
|
||||
* 2023/11/22 v3.6 修复数值越界BUG。
|
||||
* 2023/12/01 v3.7 优化算法,提高效能。
|
||||
* 版本号:v3.7
|
||||
|
||||
* ====================================================
|
||||
*/
|
||||
|
@ -25,7 +27,6 @@
|
|||
|
||||
#include "ImageApply.h"
|
||||
|
||||
class CImageApplyAdjustColors;
|
||||
class GIMGPROC_LIBRARY_API CImageApplyFadeBackGroudColor : public CImageApply
|
||||
{
|
||||
public:
|
||||
|
@ -42,25 +43,20 @@ public:
|
|||
virtual void apply(std::vector<cv::Mat>& mats, bool isTwoSide);
|
||||
|
||||
private:
|
||||
|
||||
/// <summary>
|
||||
/// 除文稿底色算法,仅支持24位图像
|
||||
/// </summary>
|
||||
/// <param name="data">图像数据头指针</param>
|
||||
/// <param name="width">图像宽度</param>
|
||||
/// <param name="height">图像高度</param>
|
||||
/// <param name="bytesPerLine">每行数据大小</param>
|
||||
/// <param name="image">图像</param>
|
||||
/// <param name="threshold">阈值。区分文稿和黑色背景。取值范围[0, 255],参考值为100</param>
|
||||
/// <param name="offset">文稿底色增亮偏移量,默认为0。值越大,背景越白,反之越暗</param>
|
||||
/// <param name="range">背景色彩的浮动范围。要求大于等于1。值越大范围越大,更多的色彩被判定为底色并除色。参考值40</param>
|
||||
void fadeBackground(unsigned char* data, int width, int height, int bytesPerLine, int threshold, int offset, int range);
|
||||
void fadeBackground(cv::Mat& image, int threshold, int offset, int range);
|
||||
|
||||
private:
|
||||
int m_threshold;
|
||||
int m_offset;
|
||||
int m_range;
|
||||
uchar m_table1[768];
|
||||
uchar m_table2[768];
|
||||
uchar m_table_rgb[3][256];
|
||||
};
|
||||
|
||||
#endif // !IMAGE_APPLY_FADE_BACKGROUND_COLOR_H
|
||||
|
|
|
@ -1,18 +1,36 @@
|
|||
#include "ImageApplyHSVCorrect.h"
|
||||
#include <omp.h>
|
||||
|
||||
CImageApplyHSVCorrect::CImageApplyHSVCorrect(CorrectOption mode, bool cvtColor, uint bgr)
|
||||
CImageApplyHSVCorrect::CImageApplyHSVCorrect(CorrectOption mode, bool cvtColor, uint bgr, uint alpha)
|
||||
: m_table(new uint[256 * 256 * 256])
|
||||
{
|
||||
initLUT();
|
||||
uint temp;
|
||||
switch (mode)
|
||||
{
|
||||
case CImageApplyHSVCorrect::Red_Removal:
|
||||
set_HSV_value(std::pair<uchar, uchar>(0, 63), std::pair<uchar, uchar>(30, 255), std::pair<uchar, uchar>(120, 255), bgr, cvtColor);
|
||||
set_HSV_value(std::pair<uchar, uchar>(0, 10), std::pair<uchar, uchar>(30, 255), std::pair<uchar, uchar>(120, 255), bgr, cvtColor);
|
||||
set_HSV_value(std::pair<uchar, uchar>(200, 255), std::pair<uchar, uchar>(30, 255), std::pair<uchar, uchar>(120, 255), bgr, cvtColor);
|
||||
break;
|
||||
case CImageApplyHSVCorrect::LowSaturation_Removal:
|
||||
set_HSV_value(std::pair<uchar, uchar>(0, 255), std::pair<uchar, uchar>(0, 30), std::pair<uchar, uchar>(0, 255), bgr, cvtColor);
|
||||
if (alpha < 0)
|
||||
temp = 35;
|
||||
else
|
||||
temp = alpha;
|
||||
set_HSV_value(std::pair<uchar, uchar>(0, 255), std::pair<uchar, uchar>(0, temp), std::pair<uchar, uchar>(0, 255), bgr, cvtColor);
|
||||
break;
|
||||
case CImageApplyHSVCorrect::FXB_Color_Cast:
|
||||
set_HSV_value(std::pair<uchar, uchar>(45, 105), std::pair<uchar, uchar>(0, 255), std::pair<uchar, uchar>(0, 255), 0x00FFFFFF, true);
|
||||
set_HSV_value(std::pair<uchar, uchar>(180, 235), std::pair<uchar, uchar>(0, 255), std::pair<uchar, uchar>(0, 255), 0x00FFFFFF, true);
|
||||
set_HSV_value(std::pair<uchar, uchar>(0, 30), std::pair<uchar, uchar>(0, 50), std::pair<uchar, uchar>(0, 255), 0x00FFFFFF, true);
|
||||
break;
|
||||
case CImageApplyHSVCorrect::LM_Color_Cast:
|
||||
set_HSV_value(std::pair<uchar, uchar>(45, 105), std::pair<uchar, uchar>(0, 255), std::pair<uchar, uchar>(0, 255), 0x00FFFFFF, true);
|
||||
set_HSV_value(std::pair<uchar, uchar>(180, 235), std::pair<uchar, uchar>(0, 100), std::pair<uchar, uchar>(0, 255), 0x00FFFFFF, true);
|
||||
set_HSV_value(std::pair<uchar, uchar>(0, 30), std::pair<uchar, uchar>(0, 60), std::pair<uchar, uchar>(0, 255), 0x00FFFFFF, true);
|
||||
break;
|
||||
case CImageApplyHSVCorrect::RESERVE_RED:
|
||||
set_HSV_value(std::pair<uchar, uchar>(45, 220), std::pair<uchar, uchar>(0, 255), std::pair<uchar, uchar>(0, 255), 0x00FFFFFF, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -149,7 +167,7 @@ void CImageApplyHSVCorrect::RGB_2_HSV_full(int r, int g, int b, uchar& h, uchar&
|
|||
return;
|
||||
}
|
||||
else
|
||||
s = static_cast<uchar>(delta * 255 / maxx);
|
||||
s = delta;
|
||||
|
||||
if (r == maxx)
|
||||
_h = static_cast<float>(g - b) / static_cast<float>(delta);
|
||||
|
|
|
@ -11,7 +11,12 @@
|
|||
v1.4 2022/04/22 增加功能,支持用像素灰度值填充原来彩色像素;删除默认构造函数;增加校正选项Deafault和LowSaturation_Removal
|
||||
v1.4.1 2022/04/25 调整数据类型,避免数据访问越界。
|
||||
v1.4.2 2022/06/09 修复一个内存大小的错误。
|
||||
* 版本号:v1.4.2
|
||||
v1.5 2022/08/22 调整饱和度计算方式;构造函数增加参数alpha,用于微调部分模式的参数。
|
||||
v1.5.1 2022/09/23 添加风向标除偏色预设方案
|
||||
v1.5.2 2022/10/26 添加鹿鸣除偏色预设方案
|
||||
v1.5.3 2023/03/22 添加保留红色像素预设方案
|
||||
v1.5.4 2023/12/01 微调除红H范围
|
||||
* 版本号:v1.5.4
|
||||
*
|
||||
* ====================================================
|
||||
*/
|
||||
|
@ -26,17 +31,21 @@ class GIMGPROC_LIBRARY_API CImageApplyHSVCorrect : public CImageApply
|
|||
public:
|
||||
enum CorrectOption
|
||||
{
|
||||
Deafault, //默认,无任何除色效果
|
||||
LowSaturation_Removal, //除掉低饱和度像素
|
||||
Red_Removal //除掉红色。红色定义H:[0, 85]∪[170, 255],S:[10, 255],V:[120,255]
|
||||
Default, //默认,无任何除色效果
|
||||
LowSaturation_Removal, //除掉低饱和度像素
|
||||
Red_Removal, //除掉红色。红色定义H:[0, 85]∪[170, 255],S:[10, 255],V:[120,255]
|
||||
FXB_Color_Cast, //风向标消除偏色
|
||||
LM_Color_Cast, //鹿鸣消除偏色
|
||||
RESERVE_RED //保留红色像素
|
||||
};
|
||||
public:
|
||||
/*
|
||||
* mode [in]:预设初色模式
|
||||
* cvtColor [in]:替代像素使用默认值,还是使用灰度值。true为灰度值,false为默认值
|
||||
* bgr:[in] 用uint表示BGR值,B在低位,R在高位。(当cvtGray 为false时生效)
|
||||
* bgr [in] 用uint表示BGR值,B在低位,R在高位。(当cvtGray 为false时生效)
|
||||
* alpha [int] 用于调整LowSaturation_Removal模式的强度。当alpha为负时,饱和度区间默认为[0, 35];当alpha为非负时,饱和度区间为[0, alpha]。
|
||||
*/
|
||||
CImageApplyHSVCorrect(CorrectOption mode = CorrectOption::Deafault, bool cvtColor = false, uint bgr = 0x00FFFFFF);
|
||||
CImageApplyHSVCorrect(CorrectOption mode = CorrectOption::Default, bool cvtColor = false, uint bgr = 0x00FFFFFF, uint alpha = -1);
|
||||
|
||||
virtual ~CImageApplyHSVCorrect();
|
||||
|
||||
|
|
|
@ -32,4 +32,5 @@
|
|||
#include "ImageApplySplit.h"
|
||||
#include "CISTestImageProcess.h"
|
||||
#include "ImageApplyColorCastCorrect.h"
|
||||
#include "LineContinuityDetection.h"
|
||||
#endif
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
#include "ImageApplyOutHole.h"
|
||||
#include "ImageProcess_Public.h"
|
||||
//#include <QDebug>
|
||||
|
||||
#ifdef LOG
|
||||
#include "Device/filetools.h"
|
||||
#endif // LOG
|
||||
//#define DRAW_PIC
|
||||
|
||||
CImageApplyOutHole::CImageApplyOutHole(void)
|
||||
: CImageApply()
|
||||
|
@ -32,10 +29,24 @@ void CImageApplyOutHole::apply(cv::Mat& pDib, int side)
|
|||
(void)side;
|
||||
}
|
||||
|
||||
#define MIN_CONTOUR_SIZE 10
|
||||
void CImageApplyOutHole::dilateContour(std::vector<cv::Point>& contour, int distance)
|
||||
{
|
||||
cv::Moments mu = cv::moments(contour);
|
||||
|
||||
cv::Point2f center(mu.m10 / mu.m00, mu.m01 / mu.m00), p_temp;
|
||||
for (size_t i = 0; i < contour.size(); i++)
|
||||
{
|
||||
p_temp = contour[i];
|
||||
double dis = cv::sqrt(cv::pow(p_temp.x - center.x, 2) + cv::pow(p_temp.y - center.y, 2));
|
||||
double scale = dis / (distance + dis);
|
||||
double x = (p_temp.x - center.x) / scale + center.x;
|
||||
double y = (p_temp.y - center.y) / scale + center.y;
|
||||
contour[i] = cv::Point(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
#define RESIZE_FIXED_WIDTH 2448.0
|
||||
#define LINE_WIDTH 18
|
||||
#define DILATE_SIZE 16
|
||||
void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
||||
{
|
||||
#ifdef LOG
|
||||
|
@ -73,17 +84,44 @@ void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
|||
back = mats[1];
|
||||
}
|
||||
|
||||
cv::Mat thumbnail;
|
||||
cv::resize(front, thumbnail, cv::Size(200, 200));
|
||||
cv::Scalar color_front = hg::getBackGroundColor(thumbnail, cv::Mat(), 20);
|
||||
if (color_front[1] == 0)
|
||||
if (color_front[0] < m_threshold)
|
||||
return;
|
||||
|
||||
if (color_front[1] != 0)
|
||||
if ((color_front[0] + color_front[1] + color_front[2]) < m_threshold * 3)
|
||||
return;
|
||||
|
||||
cv::resize(back, thumbnail, cv::Size(200, 200));
|
||||
cv::Scalar color_back = hg::getBackGroundColor(thumbnail, cv::Mat(), 20);
|
||||
if (color_back[1] == 0)
|
||||
if (color_back[0] < m_threshold)
|
||||
return;
|
||||
|
||||
if (color_back[1] != 0)
|
||||
if ((color_back[0] + color_back[1] + color_back[2]) < m_threshold * 3)
|
||||
return;
|
||||
|
||||
cv::Mat front_thre, back_thre;
|
||||
hg::threshold_Mat(front, front_thre, m_threshold);
|
||||
hg::threshold_Mat(back, back_thre, m_threshold);
|
||||
//cv::imwrite("front_thre.jpg", front_thre);
|
||||
//cv::imwrite("back_thre.jpg", back_thre);
|
||||
|
||||
cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(5 * resize_scale, 1));
|
||||
#ifdef DRAW_PIC
|
||||
cv::imwrite("front_thre.jpg", front_thre);
|
||||
cv::imwrite("back_thre.jpg", back_thre);
|
||||
#endif
|
||||
|
||||
cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(m_borderSize * resize_scale / 4, 1));
|
||||
cv::morphologyEx(front_thre, front_thre, cv::MORPH_OPEN, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0));
|
||||
cv::morphologyEx(back_thre, back_thre, cv::MORPH_OPEN, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0));
|
||||
//cv::imwrite("front_thre2.jpg", front_thre);
|
||||
//cv::imwrite("back_thre2.jpg", back_thre);
|
||||
|
||||
#ifdef DRAW_PIC
|
||||
cv::imwrite("front_thre2.jpg", front_thre);
|
||||
cv::imwrite("back_thre2.jpg", back_thre);
|
||||
#endif
|
||||
|
||||
//反面二值化图像水平翻转
|
||||
cv::flip(back_thre, back_thre, 1); //1:Horizontal
|
||||
|
@ -94,23 +132,7 @@ void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
|||
hg::findContours(front_thre.clone(), contours_front, b1_front, cv::RETR_CCOMP);
|
||||
hg::findContours(back_thre.clone(), contours_back, b1_back, cv::RETR_CCOMP);
|
||||
|
||||
//提取正反面图像最大轮廓
|
||||
for (size_t i = 0; i < contours_front.size(); i++)
|
||||
if (contours_front[i].size() < MIN_CONTOUR_SIZE)
|
||||
{
|
||||
contours_front.erase(contours_front.begin() + i);
|
||||
b1_front.erase(b1_front.begin() + i);
|
||||
i--;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < contours_back.size(); i++)
|
||||
if (contours_back[i].size() < MIN_CONTOUR_SIZE)
|
||||
{
|
||||
contours_back.erase(contours_back.begin() + i);
|
||||
b1_back.erase(b1_back.begin() + i);
|
||||
i--;
|
||||
}
|
||||
|
||||
////提取正反面图像最大轮廓
|
||||
std::vector<cv::Point> maxContour_front = hg::getMaxContour(contours_front, b1_front);
|
||||
std::vector<cv::Point> maxContour_back = hg::getMaxContour(contours_back, b1_back);
|
||||
|
||||
|
@ -132,26 +154,37 @@ void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
|||
|
||||
cv::Mat roiMat_front(front_thre, roi_front); //在正面二值图像中截取重叠部分
|
||||
cv::Mat roiMat_back(back_thre, roi_back); //在反面二值图像中截取重叠部分
|
||||
//cv::imwrite("roiMat_front.jpg", roiMat_front);
|
||||
//cv::imwrite("roiMat_back.jpg", roiMat_back);
|
||||
|
||||
#ifdef DRAW_PIC
|
||||
cv::imwrite("roiMat_front.jpg", roiMat_front);
|
||||
cv::imwrite("roiMat_back.jpg", roiMat_back);
|
||||
#endif
|
||||
|
||||
//正反面二值图像做或运算,真正镂空区域保留0,其他地方填充为255
|
||||
cv::Mat mask;
|
||||
cv::bitwise_or(roiMat_front, roiMat_back, mask); //或运算,正反面二值图像重叠
|
||||
//cv::imwrite("mask1.jpg", mask);
|
||||
|
||||
#ifdef DRAW_PIC
|
||||
cv::imwrite("mask1.jpg", mask);
|
||||
#endif
|
||||
|
||||
//二值图像重叠图像颜色取反,膨胀,提取轮廓
|
||||
cv::bitwise_not(mask, mask);
|
||||
//cv::imwrite("mask2.jpg", mask); //反色
|
||||
|
||||
#ifdef DRAW_PIC
|
||||
cv::imwrite("mask2.jpg", mask); //反色
|
||||
#endif
|
||||
|
||||
//为了避免孔洞彻底贯穿纸边,人为绘制纸张轮廓,确保所有孔洞为封闭图形,不会与背景粘连
|
||||
cv::polylines(mask, hg::getVertices(mask_rotatedRect), true, cv::Scalar(0), LINE_WIDTH * resize_scale); //绘制纸张矩形边缘
|
||||
//cv::imwrite("mask3.jpg", mask);
|
||||
|
||||
//膨胀算法,增大孔洞连通区域面积
|
||||
element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(DILATE_SIZE * resize_scale, DILATE_SIZE * resize_scale));
|
||||
cv::dilate(mask, mask, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar(255));
|
||||
//cv::imwrite("mask4.jpg", mask);
|
||||
#ifdef DRAW_PIC
|
||||
cv::imwrite("mask3.jpg", mask);
|
||||
#endif
|
||||
|
||||
#ifdef DRAW_PIC
|
||||
cv::imwrite("mask4.jpg", mask);
|
||||
#endif
|
||||
|
||||
//提取重叠图像轮廓
|
||||
std::vector<std::vector<cv::Point>> contours_mask;
|
||||
|
@ -165,7 +198,6 @@ void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
|||
for (size_t j = 0; j < hole_contours[i].size(); j++)
|
||||
hole_contours[i][j] /= resize_scale;
|
||||
|
||||
cv::Scalar color = getBackGroudColor(front(roi_front), rrect_front.size.area());
|
||||
roi_front.x /= resize_scale;
|
||||
roi_front.y /= resize_scale;
|
||||
roi_front.width /= resize_scale;
|
||||
|
@ -173,16 +205,17 @@ void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
|||
for (size_t i = 0; i < hole_contours.size(); i++)
|
||||
{
|
||||
std::vector<std::vector<cv::Point>> contourss_temp;
|
||||
dilateContour(hole_contours[i], cv::max(m_borderSize / 2, 5.0f));
|
||||
contourss_temp.push_back(hole_contours[i]);
|
||||
cv::Mat front_temp = mats[0](roi_front);
|
||||
hg::fillPolys(front_temp, contourss_temp, color);
|
||||
hg::fillPolys(front_temp, contourss_temp, color_front);
|
||||
}
|
||||
|
||||
if (isTwoSide)
|
||||
{
|
||||
int width_ = roi_back.width;
|
||||
roi_back.x = back.cols - roi_back.width - roi_back.x; //因为之前反面图像翻转,所以现在ROI也要进行相应翻转
|
||||
color = getBackGroudColor(back(roi_back), rrect_back.size.area());
|
||||
|
||||
roi_back.x /= resize_scale;
|
||||
roi_back.y /= resize_scale;
|
||||
roi_back.width /= resize_scale;
|
||||
|
@ -200,9 +233,10 @@ void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
|||
}
|
||||
|
||||
std::vector<std::vector<cv::Point>> contours_temp;
|
||||
dilateContour(hole_contour, cv::max(m_borderSize / 2, 5.0f));
|
||||
contours_temp.push_back(hole_contour);
|
||||
cv::Mat back_temp = mats[1](roi_back);
|
||||
hg::fillPolys(back_temp, contours_temp, color);
|
||||
hg::fillPolys(back_temp, contours_temp, color_back);
|
||||
}
|
||||
}
|
||||
#ifdef LOG
|
||||
|
@ -337,81 +371,4 @@ std::vector<std::vector<cv::Point>> CImageApplyOutHole::filterPoly(std::vector<s
|
|||
hole_contours.push_back(contours[i]);
|
||||
}
|
||||
return hole_contours;
|
||||
}
|
||||
|
||||
cv::Scalar CImageApplyOutHole::getBackGroudColor(const cv::Mat& image, const std::vector<cv::Point> pixelPoints)
|
||||
{
|
||||
if (pixelPoints.empty()) return cv::Scalar(255, 255, 255);
|
||||
|
||||
int channels = image.channels();
|
||||
|
||||
int temp[3] = { 0 };
|
||||
for (size_t i = 0, length = pixelPoints.size(); i < length; ++i)
|
||||
{
|
||||
int x = cv::min(cv::max(0, pixelPoints[i].x), image.cols - 1);
|
||||
int y = cv::min(cv::max(0, pixelPoints[i].y), image.rows - 1);
|
||||
|
||||
const unsigned char* ptr = image.ptr(y, x);
|
||||
for (int j = 0; j < channels; ++j)
|
||||
temp[j] += ptr[j];
|
||||
}
|
||||
|
||||
return cv::Scalar(temp[0] / static_cast<int>(pixelPoints.size()),
|
||||
temp[1] / static_cast<int>(pixelPoints.size()),
|
||||
temp[2] / static_cast<int>(pixelPoints.size()));
|
||||
}
|
||||
|
||||
cv::Scalar CImageApplyOutHole::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 CImageApplyOutHole::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<float>(i, 0);
|
||||
|
||||
int length = 1;
|
||||
const int length_max = 255;
|
||||
while (length < length_max)
|
||||
{
|
||||
for (size_t i = 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;
|
||||
}
|
|
@ -4,28 +4,33 @@
|
|||
* 功能:装订孔填充
|
||||
* 作者:刘丁维
|
||||
* 生成时间:2020/11/21
|
||||
* 最近修改时间:2020/05/12 v1.0
|
||||
* 2020/11/17 v1.1
|
||||
* 2021/09/06 v1.2 调整默认二值化阈值,从原来的50调整为100。将填充颜色从局部颜色提取改为全局颜色提取。
|
||||
* 2021/11/03 v1.3 增加逻辑,如果正反面图像尺寸差异超过10个像素,直接返回,不再进行除穿孔处理。
|
||||
* 2021/11/04 v1.4 增加背景抗噪机制,能够抗5像素的背景噪声。
|
||||
* 2021/11/17 v1.5 调整代码格式,避免一些由于opencv版本导致的BUG。
|
||||
* 2022/04/18 v1.6 修复由于图像超出边界导致的定位孔洞异常的BUG。
|
||||
* 2022/05/04 v1.6.1 增加逻辑判断,如果出现黑图,直接返回,不对原图进行任何处理。
|
||||
* 2022/07/16 v1.6.2 修复自动识别填充颜色的BUG
|
||||
* 2022/07/18 v1.6.3 修复mask的一些逻辑错误
|
||||
* 2022/07/18 v1.7 修复逻辑BUG,替换构造函数borderSize逻辑,由原来面积改为边长,定义穿孔范围为[borderSize, borderSize * 6]
|
||||
* 2022/07/22 v1.7.1 修复自动识别填充颜色的BUG
|
||||
* 2022/08/02 v1.7.2 调整部分默认参数以及参数命名
|
||||
* 2022/09/07 v1.8 去掉上下左右边缘范围的统一比例,取而代之是分别设置上下左右的边缘比例
|
||||
* 2022/09/09 v1.8.1 修复边缘定位的精确BUG。
|
||||
* 2022/09/15 v1.8.2 修复一些逻辑BUG。
|
||||
* 2022/09/15 v1.8.3 提高抗背景噪声能力。
|
||||
* 2022/09/15 v1.8.4 修复导致崩溃的BUG
|
||||
* 2022/09/16 v1.9 优化内存消耗
|
||||
* 2022/09/16 v1.9.1 修复缩放比例的逻辑错误。
|
||||
* 2022/11/17 v1.9.2 修复寻找孔洞轮廓BUG。
|
||||
* 版本号:v1.9.2
|
||||
* 最近修改时间:v1.0 2020/05/12
|
||||
* v1.1 2020/11/17
|
||||
* v1.2 2021/09/06 调整默认二值化阈值,从原来的50调整为100。将填充颜色从局部颜色提取改为全局颜色提取。
|
||||
* v1.3 2021/11/03 增加逻辑,如果正反面图像尺寸差异超过10个像素,直接返回,不再进行除穿孔处理。
|
||||
* v1.4 2021/11/04 增加背景抗噪机制,能够抗5像素的背景噪声。
|
||||
* v1.5 2021/11/17 调整代码格式,避免一些由于opencv版本导致的BUG。
|
||||
* v1.6 2022/04/18 修复由于图像超出边界导致的定位孔洞异常的BUG。
|
||||
* v1.6.1 2022/05/04 增加逻辑判断,如果出现黑图,直接返回,不对原图进行任何处理。
|
||||
* v1.6.2 2022/07/16 修复自动识别填充颜色的BUG
|
||||
* v1.6.3 2022/07/18 修复mask的一些逻辑错误
|
||||
* v1.7 2022/07/18 修复逻辑BUG,替换构造函数borderSize逻辑,由原来面积改为边长,定义穿孔范围为[borderSize, borderSize * 6]
|
||||
* v1.7.1 2022/07/22 修复自动识别填充颜色的BUG
|
||||
* v1.7.2 2022/08/02 调整部分默认参数以及参数命名
|
||||
* v1.8 2022/09/07 去掉上下左右边缘范围的统一比例,取而代之是分别设置上下左右的边缘比例
|
||||
* v1.8.1 2022/09/09 修复边缘定位的精确BUG。
|
||||
* v1.8.2 2022/09/15 修复一些逻辑BUG。
|
||||
* v1.8.3 2022/09/15 提高抗背景噪声能力。
|
||||
* v1.8.4 2022/09/15 修复导致崩溃的BUG
|
||||
* v1.9 2022/09/16 优化内存消耗
|
||||
* v1.9.1 2022/09/16 修复缩放比例的逻辑错误。
|
||||
* v1.9.2 2022/11/17 修复寻找孔洞轮廓BUG。
|
||||
* v1.9.3 2023/05/16 修复提取纸张最大轮廓的逻辑BUG。
|
||||
* v1.10 2023/11/18 替换形态学膨胀孔洞轮廓,改为特征矩阵膨胀轮廓说。
|
||||
* v1.10.1 2023/11/28 形态学kSize根据borderSize调整。
|
||||
* v1.11 2023/12/02 替换文稿底色提取方案;修复部分孔洞填充不完全的问题。
|
||||
* v1.11.1 2023/12/08 增加机制,当发现文稿底色<阈值时,直接返回。避免浪费无意义的算力;增大填涂面积
|
||||
* 版本号:v1.11.1
|
||||
|
||||
* ====================================================
|
||||
*/
|
||||
|
@ -74,11 +79,7 @@ private:
|
|||
std::vector<std::vector<cv::Point> > filterPoly(std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& m, cv::RotatedRect roi,
|
||||
cv::Vec4f edgeScale, float sideLengthLow);
|
||||
|
||||
cv::Scalar getBackGroudColor(const cv::Mat& image, const std::vector<cv::Point> pixelPoints);
|
||||
|
||||
cv::Scalar getBackGroudColor(const cv::Mat& image, int total);
|
||||
|
||||
uchar getBackGroudChannelMean(const cv::Mat& gray, int total);
|
||||
void dilateContour(std::vector<cv::Point>& contour, int distance);
|
||||
|
||||
private:
|
||||
float m_borderSize;
|
||||
|
|
|
@ -1,52 +1,65 @@
|
|||
#include "ImageApplyRefuseInflow.h"
|
||||
#include "ImageApplyAdjustColors.h"
|
||||
#include "ImageProcess_Public.h"
|
||||
|
||||
CImageApplyRefuseInflow::CImageApplyRefuseInflow(int constrast)
|
||||
: m_adjustColor(new CImageApplyAdjustColors(0, constrast, 1.0f))
|
||||
CImageApplyRefuseInflow::CImageApplyRefuseInflow(int threshold, int range)
|
||||
: m_threshold(threshold)
|
||||
, m_range(range)
|
||||
{
|
||||
}
|
||||
|
||||
CImageApplyRefuseInflow::~CImageApplyRefuseInflow()
|
||||
{
|
||||
delete m_adjustColor;
|
||||
}
|
||||
|
||||
void CImageApplyRefuseInflow::apply(cv::Mat& pDib, int side)
|
||||
{
|
||||
(void)side;
|
||||
#if 0
|
||||
static unsigned char table_contrast[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
|
||||
50, 51, 52, 53, 54, 55, 56, 57, 198, 199,
|
||||
200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
|
||||
210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
|
||||
220, 221, 222, 223, 224, 225, 226, 227, 228, 229,
|
||||
230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
|
||||
240, 241, 242, 243, 244, 245, 246, 247, 248, 249,
|
||||
250, 251, 252, 253, 254, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255 };
|
||||
static cv::Mat mat_table(1, 256, CV_8UC1, table_contrast);
|
||||
cv::LUT(pDib, mat_table, pDib);
|
||||
#else
|
||||
m_adjustColor->apply(pDib, side);
|
||||
#endif
|
||||
if (pDib.channels() == 3)
|
||||
{
|
||||
cv::Mat resizeMat;
|
||||
cv::resize(pDib, resizeMat, cv::Size(200, 200));
|
||||
cv::Mat mask;
|
||||
cv::cvtColor(resizeMat, mask, cv::COLOR_BGR2GRAY);
|
||||
cv::threshold(mask, mask, m_threshold, 255, cv::THRESH_BINARY);
|
||||
|
||||
cv::Scalar bgc = hg::getBackGroundColor(resizeMat, mask, m_threshold);
|
||||
|
||||
std::vector<int> low, up;
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
{
|
||||
low.push_back(cv::max((int)bgc[i] - m_range, 0));
|
||||
up.push_back(cv::min((int)bgc[i] + m_range, 255));
|
||||
}
|
||||
|
||||
cv::inRange(pDib, low, up, mask);
|
||||
pDib = pDib.setTo(bgc, mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
cv::Mat resizeMat;
|
||||
cv::resize(pDib, resizeMat, cv::Size(200, 200));
|
||||
cv::Mat mask;
|
||||
cv::threshold(resizeMat, mask, m_threshold, 255, cv::THRESH_BINARY);
|
||||
|
||||
cv::Mat hist;
|
||||
double min, max;
|
||||
cv::Point maxLoc;
|
||||
float range[] = { 0, 256 };
|
||||
const float* ranges = { range };
|
||||
int histSize = 256;
|
||||
cv::calcHist(&resizeMat, 1, 0, mask, hist, 1, &histSize, &ranges);
|
||||
|
||||
int index_max = 0;
|
||||
int max_value = 0;
|
||||
for (size_t j = m_threshold; j < 256; j++)
|
||||
if (hist.at<float>(j) > max_value)
|
||||
{
|
||||
index_max = j;
|
||||
max_value = hist.at<float>(j);
|
||||
}
|
||||
|
||||
cv::inRange(pDib, cv::max(index_max - m_range, 0), cv::min(index_max + m_range, 255), mask);
|
||||
pDib = pDib.setTo(cv::Scalar::all(index_max), mask);
|
||||
}
|
||||
}
|
||||
|
||||
void CImageApplyRefuseInflow::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
||||
|
|
|
@ -6,7 +6,11 @@
|
|||
* 生成时间:2020/4/21
|
||||
* 最近修改时间:v1.0 2020/04/21
|
||||
* v1.1 2022/05/04 重构算法,采用提高对比度实现防渗透。
|
||||
* 版本号:v1.1
|
||||
* v2.0 2023/08/12 筹够算法,采用双边滤波实现防渗透。
|
||||
* v2.1 2023/10/20 修复原图不能同时作为目标图的BUG。
|
||||
* v3.0 2023/12/02 更新方案,通过识别文稿底色,填充近似颜色实现防渗透。接口有所调整
|
||||
* v3.1 2023/12/04 支持灰度图防渗透
|
||||
* 版本号:v3.1
|
||||
|
||||
* ====================================================
|
||||
*/
|
||||
|
@ -16,11 +20,16 @@
|
|||
|
||||
#include "ImageApply.h"
|
||||
|
||||
class CImageApplyAdjustColors;
|
||||
class GIMGPROC_LIBRARY_API CImageApplyRefuseInflow : public CImageApply
|
||||
{
|
||||
public:
|
||||
CImageApplyRefuseInflow(int constrast = 15);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="threshod">背景阈值.取值范围[0, 255]</param>
|
||||
/// <param name="range">文稿底色相近范围。取值范围[0, 255]</param>
|
||||
CImageApplyRefuseInflow(int threshod = 20, int range = 40);
|
||||
|
||||
virtual ~CImageApplyRefuseInflow();
|
||||
|
||||
|
@ -29,6 +38,7 @@ public:
|
|||
virtual void apply(std::vector<cv::Mat>& mats, bool isTwoSide);
|
||||
|
||||
private:
|
||||
CImageApplyAdjustColors* m_adjustColor;
|
||||
int m_threshold;
|
||||
int m_range;
|
||||
};
|
||||
#endif // !IMAGE_APPLY_REFUSE_INFLOW_H
|
||||
|
|
|
@ -18,46 +18,15 @@ std::vector<cv::Mat> ImageMultiOutputRed::apply(cv::Mat& pDib)
|
|||
if (pDib.empty())
|
||||
return retMats;
|
||||
retMats.push_back(pDib);
|
||||
cv::Mat mat = FilterColor(pDib, m_channelIndex);
|
||||
if (!mat.empty())
|
||||
retMats.push_back(mat);
|
||||
filterColor(pDib, m_channelIndex);
|
||||
retMats.push_back(pDib);
|
||||
return retMats;
|
||||
}
|
||||
|
||||
cv::Mat ImageMultiOutputRed::FilterColor(cv::Mat image, short channel)
|
||||
void ImageMultiOutputRed::filterColor(cv::Mat& image, short channel)
|
||||
{
|
||||
cv::Mat dstImage(image.rows, image.cols, CV_8UC1);
|
||||
int channels = image.channels();
|
||||
if (channel > channels - 1)
|
||||
{
|
||||
return cv::Mat();
|
||||
}
|
||||
if ((channel == 3) && (channels != 4) && (channels != 8))
|
||||
{
|
||||
return cv::Mat();
|
||||
}
|
||||
if (channels <= 4)
|
||||
{
|
||||
int srcOffset = image.step - image.cols * channels;
|
||||
int dstOffset = dstImage.step - dstImage.cols;
|
||||
unsigned char *src = image.data;
|
||||
unsigned char *dst = dstImage.data;
|
||||
src += channel;
|
||||
if (image.channels() == 1)
|
||||
return;
|
||||
|
||||
for (int y = 0; y < image.rows; y++)
|
||||
{
|
||||
for (int x = 0; x < image.cols; x++, src += channels, dst++)
|
||||
{
|
||||
unsigned short pix = *src;
|
||||
if (pix >= 130)
|
||||
{
|
||||
pix = 255;
|
||||
}
|
||||
*dst = pix;
|
||||
}
|
||||
src += srcOffset;
|
||||
dst += dstOffset;
|
||||
}
|
||||
}
|
||||
return dstImage;
|
||||
cv::extractChannel(image, image, channel);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,15 @@
|
|||
/*
|
||||
* ====================================================
|
||||
|
||||
* 功能:多流除红
|
||||
* 作者:刘丁维
|
||||
* 生成时间:2023/12/02
|
||||
* 最近修改时间:v1.0 2023/12/02
|
||||
* 版本号:v1.0
|
||||
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#ifndef IMAGE_MULTI_OUTPUT_RED_H
|
||||
#define IMAGE_MULTI_OUTPUT_RED_H
|
||||
#include "IMulti.h"
|
||||
|
@ -9,9 +21,9 @@ public:
|
|||
ImageMultiOutputRed(short channelIndex);
|
||||
virtual ~ImageMultiOutputRed(void);
|
||||
virtual std::vector<cv::Mat> apply(cv::Mat& pDib) override;
|
||||
|
||||
private:
|
||||
void filterColor(cv::Mat& image, short channel);
|
||||
private:
|
||||
short m_channelIndex;
|
||||
cv::Mat FilterColor(cv::Mat image, short channel);
|
||||
};
|
||||
#endif //!IMAGE_MULTI_OUTPUT_RED_H
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#include "ImageProcess_Public.h"
|
||||
#include <opencv2/core/core_c.h>
|
||||
#include <opencv2/core/types_c.h>
|
||||
#include <opencv2/imgproc/imgproc_c.h>
|
||||
|
||||
namespace hg
|
||||
{
|
||||
|
@ -150,14 +153,11 @@ namespace hg
|
|||
|
||||
void findContours(const cv::Mat& src, std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& hierarchy, int retr, int method, cv::Point offset)
|
||||
{
|
||||
#if CV_VERSION_REVISION <= 6
|
||||
CvMat c_image = src;
|
||||
#else
|
||||
CvMat c_image;
|
||||
c_image = cvMat(src.rows, src.cols, src.type(), src.data);
|
||||
c_image.step = src.step[0];
|
||||
c_image.type = (c_image.type & ~cv::Mat::CONTINUOUS_FLAG) | (src.flags & cv::Mat::CONTINUOUS_FLAG);
|
||||
#endif
|
||||
|
||||
cv::MemStorage storage(cvCreateMemStorage());
|
||||
CvSeq* _ccontours = nullptr;
|
||||
|
||||
|
@ -205,6 +205,52 @@ namespace hg
|
|||
storage.release();
|
||||
}
|
||||
|
||||
cv::Scalar getBackGroundColor(const cv::Mat& image, const cv::Mat& mask, int threshold)
|
||||
{
|
||||
float range[] = { 0, 256 };
|
||||
const float* ranges = { range };
|
||||
int histSize = 256;
|
||||
cv::Scalar bgc;
|
||||
if (image.channels() == 3)
|
||||
{
|
||||
cv::Mat mv[3];
|
||||
cv::split(image, mv);
|
||||
|
||||
cv::Mat hist[3];
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
cv::calcHist(&mv[i], 1, 0, mask, hist[i], 1, &histSize, &ranges);
|
||||
|
||||
int index_max = 0;
|
||||
int max_value = 0;
|
||||
for (size_t j = threshold; j < 256; j++)
|
||||
if (hist[i].at<float>(j) > max_value)
|
||||
{
|
||||
index_max = j;
|
||||
max_value = hist[i].at<float>(j);
|
||||
}
|
||||
|
||||
bgc[i] = index_max;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cv::Mat hist;
|
||||
cv::calcHist(&image, 1, 0, mask, hist, 1, &histSize, &ranges);
|
||||
int index_max = 0;
|
||||
int max_value = 0;
|
||||
for (size_t j = threshold; j < 256; j++)
|
||||
if (hist.at<float>(j) > max_value)
|
||||
{
|
||||
index_max = j;
|
||||
max_value = hist.at<float>(j);
|
||||
}
|
||||
bgc = cv::Scalar::all(index_max);
|
||||
}
|
||||
|
||||
return bgc;
|
||||
}
|
||||
|
||||
cv::RotatedRect getBoundingRect(const std::vector<cv::Point>& contour)
|
||||
{
|
||||
if (contour.empty()) return {};
|
||||
|
@ -302,8 +348,11 @@ namespace hg
|
|||
return dst;
|
||||
}
|
||||
|
||||
#define DEFAULT_THRESHOLD 30
|
||||
#define THRESHOLD_OFFSET 10
|
||||
void threshold_Mat(const cv::Mat& src, cv::Mat& dst, double thre)
|
||||
{
|
||||
cv::Mat temp;
|
||||
if (src.channels() == 3)
|
||||
{
|
||||
#ifdef USE_ONENCL
|
||||
|
@ -312,13 +361,39 @@ namespace hg
|
|||
else
|
||||
#endif
|
||||
{
|
||||
cv::Mat gray = transforColor(src);
|
||||
cv::threshold(gray, dst, thre, 255, cv::THRESH_BINARY);
|
||||
gray.release();
|
||||
//temp = transforColor(src);
|
||||
cv::cvtColor(src, temp, cv::COLOR_BGR2GRAY);
|
||||
}
|
||||
}
|
||||
else
|
||||
cv::threshold(src, dst, thre, 255, cv::THRESH_BINARY);
|
||||
temp = src;
|
||||
|
||||
if (thre > 0)
|
||||
cv::threshold(temp, dst, thre, 255, cv::THRESH_BINARY);
|
||||
else
|
||||
{
|
||||
std::vector<int> unusual_cols;
|
||||
std::vector<uchar> unusual_gray;
|
||||
|
||||
uchar* firstLine = temp.ptr<uchar>(0);
|
||||
uchar* lastLine = temp.ptr<uchar>(temp.rows - 1);
|
||||
|
||||
uchar temp_gray;
|
||||
for (size_t i = 0, length = temp.step; i < length; i++)
|
||||
{
|
||||
temp_gray = cv::min(firstLine[i], lastLine[i]);
|
||||
if (temp_gray > DEFAULT_THRESHOLD)
|
||||
{
|
||||
unusual_cols.push_back(i);
|
||||
unusual_gray.push_back(temp_gray);
|
||||
}
|
||||
}
|
||||
|
||||
cv::threshold(temp, dst, DEFAULT_THRESHOLD + THRESHOLD_OFFSET, 255, cv::THRESH_BINARY);
|
||||
|
||||
for (size_t i = 0; i < unusual_cols.size(); i++)
|
||||
dst(cv::Rect(unusual_cols[i], 0, 1, temp.rows)) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
cv::Point warpPoint(const cv::Point& p, const cv::Mat& warp_mat)
|
||||
|
|
|
@ -5,9 +5,14 @@
|
|||
* 作者:刘丁维
|
||||
* 生成时间:2020/4/21
|
||||
* 最近修改时间:2020/4/21
|
||||
* 2021/07/12 v1.1 getBoundingRect中,增加考虑纠正初始 angle > 90 的情况。
|
||||
* 2021/07/22 v1.2 convexHull中,修复点集为空可能导致崩溃的BUG。
|
||||
* 版本号:v1.2
|
||||
* 2021/07/12 v1.1 getBoundingRect中,增加考虑纠正初始 angle > 90 的情况。
|
||||
* 2021/07/22 v1.2 convexHull中,修复点集为空可能导致崩溃的BUG。
|
||||
* 2023/11/02 v1.3 threshold_Mat,当thre<0时,采用自适应背景二值化。
|
||||
* 2023/12/01 v1.4 增加getBackGroundColor算法。
|
||||
* 2023/12/02 v1.4.1 getBackGroundColor增加threshold阈值。
|
||||
* 2023/12/04 v1.4.2 兼容opencv版本接口。
|
||||
* 2023/12/05 v1.4.3 getBackGroundColor支持单通道图像背景色识别。
|
||||
* 版本号:v1.4.3
|
||||
|
||||
* ====================================================
|
||||
*/
|
||||
|
@ -55,6 +60,15 @@ namespace hg
|
|||
void findContours(const cv::Mat& src, std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& hierarchy,
|
||||
int retr = cv::RETR_LIST, int method = cv::CHAIN_APPROX_SIMPLE, cv::Point offset = cv::Point(0, 0));
|
||||
|
||||
/// <summary>
|
||||
/// 获取图片文稿底色
|
||||
/// </summary>
|
||||
/// <param name="image">图像,三通道</param>
|
||||
/// <param name="mask">掩膜</param>
|
||||
/// <param name="threshold">阈值,用于排除黑色背景</param>
|
||||
/// <returns>文稿底色</returns>
|
||||
cv::Scalar getBackGroundColor(const cv::Mat& image, const cv::Mat& mask = cv::Mat(), int threshold = 20);
|
||||
|
||||
/*
|
||||
* 功能:获取覆盖点集的最小外接矩形
|
||||
* contour: 点集
|
||||
|
@ -90,7 +104,7 @@ namespace hg
|
|||
* 功能: 二值化,能够处理彩色和灰度图像。src为彩色图像时,灰度图取三个通道的最大值
|
||||
* src: 源图
|
||||
* dst: 目标图
|
||||
* thre: 阈值
|
||||
* thre: 阈值。当thre < 0时,采用背景色作为每列自适应阈值。
|
||||
*/
|
||||
void threshold_Mat(const cv::Mat& src, cv::Mat& dst, double thre);
|
||||
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
#include "LineContinuityDetection.h"
|
||||
|
||||
LineContinuityDetection::LineContinuityDetection()
|
||||
{
|
||||
}
|
||||
|
||||
bool LineContinuityDetection::isContinuous(const cv::Mat& image, double area_threshold)
|
||||
{
|
||||
cv::Mat thre;
|
||||
if (image.channels() != 1)
|
||||
{
|
||||
cv::cvtColor(image, thre, cv::COLOR_BGR2GRAY);
|
||||
cv::threshold(thre, thre, 127, 255, cv::THRESH_OTSU);
|
||||
}
|
||||
else
|
||||
cv::threshold(image, thre, 127, 255, cv::THRESH_OTSU);
|
||||
|
||||
std::vector<std::vector<cv::Point>> contours;
|
||||
std::vector<cv::Vec4i> hierarchy;
|
||||
myFindContours(thre, contours, hierarchy, cv::RETR_TREE);
|
||||
|
||||
return findBlock(contours, hierarchy, area_threshold);
|
||||
}
|
||||
|
||||
void LineContinuityDetection::myFindContours(const cv::Mat& src, std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& hierarchy, int retr, int method, cv::Point offset)
|
||||
{
|
||||
#if CV_VERSION_REVISION <= 6
|
||||
CvMat c_image = src;
|
||||
#else
|
||||
CvMat c_image;
|
||||
c_image = cvMat(src.rows, src.cols, src.type(), src.data);
|
||||
c_image.step = src.step[0];
|
||||
c_image.type = (c_image.type & ~cv::Mat::CONTINUOUS_FLAG) | (src.flags & cv::Mat::CONTINUOUS_FLAG);
|
||||
#endif
|
||||
cv::MemStorage storage(cvCreateMemStorage());
|
||||
CvSeq* _ccontours = nullptr;
|
||||
|
||||
#if CV_VERSION_REVISION <= 6
|
||||
cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, CvPoint(offset));
|
||||
#else
|
||||
cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, CvPoint{ offset.x, offset.y });
|
||||
#endif
|
||||
if (!_ccontours)
|
||||
{
|
||||
contours.clear();
|
||||
return;
|
||||
}
|
||||
cv::Seq<CvSeq*> all_contours(cvTreeToNodeSeq(_ccontours, sizeof(CvSeq), storage));
|
||||
size_t total = all_contours.size();
|
||||
contours.resize(total);
|
||||
|
||||
cv::SeqIterator<CvSeq*> it = all_contours.begin();
|
||||
for (size_t i = 0; i < total; i++, ++it)
|
||||
{
|
||||
CvSeq* c = *it;
|
||||
reinterpret_cast<CvContour*>(c)->color = static_cast<int>(i);
|
||||
int count = c->total;
|
||||
int* data = new int[static_cast<size_t>(count * 2)];
|
||||
cvCvtSeqToArray(c, data);
|
||||
for (int j = 0; j < count; j++)
|
||||
{
|
||||
contours[i].push_back(cv::Point(data[j * 2], data[j * 2 + 1]));
|
||||
}
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
hierarchy.resize(total);
|
||||
it = all_contours.begin();
|
||||
for (size_t i = 0; i < total; i++, ++it)
|
||||
{
|
||||
CvSeq* c = *it;
|
||||
int h_next = c->h_next ? reinterpret_cast<CvContour*>(c->h_next)->color : -1;
|
||||
int h_prev = c->h_prev ? reinterpret_cast<CvContour*>(c->h_prev)->color : -1;
|
||||
int v_next = c->v_next ? reinterpret_cast<CvContour*>(c->v_next)->color : -1;
|
||||
int v_prev = c->v_prev ? reinterpret_cast<CvContour*>(c->v_prev)->color : -1;
|
||||
hierarchy[i] = cv::Vec4i(h_next, h_prev, v_next, v_prev);
|
||||
}
|
||||
|
||||
storage.release();
|
||||
}
|
||||
|
||||
bool LineContinuityDetection::findBlock(const std::vector<std::vector<cv::Point>>& contours, const std::vector<cv::Vec4i>& hierarchy, double area_threshold)
|
||||
{
|
||||
if (contours.empty())
|
||||
return false;
|
||||
|
||||
std::vector<cv::RotatedRect> rects;
|
||||
|
||||
for (size_t i = 0; i < contours.size(); i++)
|
||||
{
|
||||
cv::RotatedRect rect = minAreaRect(contours[i]);
|
||||
rects.push_back(rect);
|
||||
}
|
||||
|
||||
std::vector<int> max_index;
|
||||
std::vector<float> max_area;
|
||||
for (size_t i = 0; i < 5; i++)
|
||||
{
|
||||
max_index.push_back(0);
|
||||
max_area.push_back(0);
|
||||
}
|
||||
for (size_t i = 0; i < rects.size(); i++)
|
||||
{
|
||||
float area = rects[i].size.area();
|
||||
for (size_t j = 0; j < 5; j++)
|
||||
{
|
||||
if (area > max_area[j])
|
||||
{
|
||||
max_index.insert(max_index.begin() + j, i);
|
||||
max_area.insert(max_area.begin() + j, area);
|
||||
|
||||
max_index.erase(max_index.begin() + 5);
|
||||
max_area.erase(max_area.begin() + 5);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 1; i < 5; i++)
|
||||
{
|
||||
int child_count = 0;
|
||||
int index_temp = hierarchy[max_index[i]][2];
|
||||
if (index_temp < 0)
|
||||
return false;
|
||||
|
||||
child_count++;
|
||||
while (hierarchy[index_temp][0] != -1)
|
||||
{
|
||||
if (rects[index_temp].size.area() > area_threshold)
|
||||
child_count++;
|
||||
|
||||
index_temp = hierarchy[index_temp][0];
|
||||
}
|
||||
|
||||
if (child_count != 4)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef LINE_CONTINUITY_DETECTION_H
|
||||
#define LINE_CONTINUITY_DETECTION_H
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
class LineContinuityDetection
|
||||
{
|
||||
public:
|
||||
LineContinuityDetection();
|
||||
|
||||
static bool isContinuous(const cv::Mat& image, double area_threshold = 100);
|
||||
|
||||
private:
|
||||
/// <summary>
|
||||
/// 获取连通区域轮廓
|
||||
/// </summary>
|
||||
/// <param name="src">源图像</param>
|
||||
/// <param name="contours">结果轮廓集</param>
|
||||
/// <param name="hierarchy">轮廓集的排序关系。与contours的数量对应,受retr选项不同,排序会有变化</param>
|
||||
/// <param name="retr">轮廓集排序方式,默认为链式排序</param>
|
||||
/// <param name="method">查找算法选择,默认为普通查找</param>
|
||||
/// <param name="offset">查找起始点,默认为(0,0)点</param>
|
||||
static void myFindContours(const cv::Mat& src, std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& hierarchy,
|
||||
int retr = cv::RETR_LIST, int method = cv::CHAIN_APPROX_SIMPLE, cv::Point offset = cv::Point(0, 0));
|
||||
|
||||
static bool findBlock(const std::vector<std::vector<cv::Point>>& contours, const std::vector<cv::Vec4i>& hierarchy, double area_threshold);
|
||||
};
|
||||
|
||||
#endif //LINE_CONTINUITY_DETECTION_H
|
|
@ -318,6 +318,7 @@
|
|||
#define SCANNER_NAME_LSC_G42S "LANXUMSCAN G42S"
|
||||
#define SCANNER_NAME_LSC_G52S "LANXUMSCAN G52S"
|
||||
#define SCANNER_NAME_LSC_G62S "LANXUMSCAN G62S"
|
||||
#define SCANNER_NAME_LSC_G63S "LANXUMSCAN G63S"
|
||||
#define SCANNER_NAME_LSC_G73S "LANXUMSCAN G73S"
|
||||
|
||||
|
||||
|
@ -334,7 +335,9 @@
|
|||
#define SCANNER_NAME_CT_138 "CUMTENN CT-138"
|
||||
#define SCANNER_NAME_CT_238 "CUMTENN CT-238"
|
||||
|
||||
#define SCANNER_NAME_ZJ_6500 "Microtek A3HG Scanner"
|
||||
#define SCANNER_NAME_ZJ_6570 "Microtek A3HG Scanner"
|
||||
#define SCANNER_NAME_ZJ_8790 "Microtek A3ES Scanner"
|
||||
#define SCANNER_NAME_ZJ_500DC "Microtek A3FZ Scanner"
|
||||
|
||||
#define SANNNER_NAME_ZG_Q7110 "Uniscan Q7 Series"
|
||||
#define SANNNER_NAME_ZG_Q1070 "Uniscan Q1 Series"
|
||||
|
@ -342,4 +345,4 @@
|
|||
#define SANNER_NAME_DL_S3000 "DELI SCAN S3000-S3110"
|
||||
#define SANNER_NAME_DL_S3400 "DELI SCAN S3000-S3400"
|
||||
#define SANNER_NAME_DL_S2000 "DELI SCAN S2000-S2090"
|
||||
#define SANNER_NAME_DL_DL9000 "DELI SCAN DL9000-DL9080"
|
||||
#define SANNER_NAME_DL_DL9000 "DELI SCAN DL9000-DL9080"
|
|
@ -1,4 +1,4 @@
|
|||
#include "common_setting.h"
|
||||
#include "common_setting.h"
|
||||
#include "sane/sane_option_definitions.h"
|
||||
#include "hg_log.h"
|
||||
|
||||
|
@ -69,6 +69,7 @@ g_page[] =
|
|||
{MAKE_ID_AND_STR(ID_OPTION_VALUE_SMYM_SM), PAGE_DOUBLE},
|
||||
{MAKE_ID_AND_STR(ID_OPTION_VALUE_SMYM_TGKBYTY), PAGE_OMIT_EMPTY},
|
||||
{MAKE_ID_AND_STR(ID_OPTION_VALUE_SMYM_TGKBYFPZ), PAGE_OMIT_EMPTY_RECEIPT},
|
||||
{MAKE_ID_AND_STR(ID_OPTION_VALUE_SMYM_TGKBYJYWJDX), PAGE_OMIT_EMPTY_FILE_SIZE},
|
||||
{MAKE_ID_AND_STR(ID_OPTION_VALUE_SMYM_DZ), PAGE_FOLIO}
|
||||
},
|
||||
|
||||
|
@ -104,11 +105,11 @@ g_text_direction[] =
|
|||
|
||||
g_permeate_lv[] =
|
||||
{
|
||||
{MAKE_ID_AND_STR(ID_OPTION_VALUE_FZSTDJ_JR), PERMAEATE_WEAKER},
|
||||
{MAKE_ID_AND_STR(ID_OPTION_VALUE_FZSTDJ_R), PERMAEATE_WEAK},
|
||||
{MAKE_ID_AND_STR(ID_OPTION_VALUE_FZSTDJ_JR), PERMAEATE_WEAK},
|
||||
{MAKE_ID_AND_STR(ID_OPTION_VALUE_FZSTDJ_R), PERMAEATE_WEAKER},
|
||||
{MAKE_ID_AND_STR(ID_OPTION_VALUE_FZSTDJ_YB), PERMAEATE_ORDINARY},
|
||||
{MAKE_ID_AND_STR(ID_OPTION_VALUE_FZSTDJ_Q), PERMAEATE_STRONG},
|
||||
{MAKE_ID_AND_STR(ID_OPTION_VALUE_FZSTDJ_JQ), PERMAEATE_STRONGER}
|
||||
{MAKE_ID_AND_STR(ID_OPTION_VALUE_FZSTDJ_Q), PERMAEATE_STRONGER},
|
||||
{MAKE_ID_AND_STR(ID_OPTION_VALUE_FZSTDJ_JQ), PERMAEATE_STRONG}
|
||||
},
|
||||
g_img_quality[] =
|
||||
{
|
||||
|
@ -504,12 +505,12 @@ int double_paper_flag_from_option_value(std::string& opt_val, bool* exact)
|
|||
if (exact)
|
||||
*exact = true;
|
||||
|
||||
if (opt_val == hg_log::lang_load(ID_OPTION_VALUE_SZTPCL_SCTXBJXSM))
|
||||
return DOUBLE_PAPER_CONTINUE | DOUBLE_PAPER_SAVE_IMG;
|
||||
else if (opt_val == hg_log::lang_load(ID_OPTION_VALUE_SZTPCL_SCTXBTZSM))
|
||||
if (opt_val == hg_log::lang_load(ID_OPTION_VALUE_SZTPCL_SCTXBTZSM))//上传图像并停止
|
||||
return DOUBLE_PAPER_SAVE_IMG;
|
||||
else if (opt_val == hg_log::lang_load(ID_OPTION_VALUE_SZTPCL_DQTXBTZSM))//丢弃图像并停止
|
||||
return DOUBLE_PAPEAR_STOP;
|
||||
else if (opt_val == from_default_language(OPTION_VALUE_SZTPCL_SCTXBJY))//上传图像并校验
|
||||
return DOUBLE_PAPER_SAVE_IMG;
|
||||
else if (opt_val == hg_log::lang_load(ID_OPTION_VALUE_SZTPCL_DQTXBJXSM))
|
||||
return DOUBLE_PAPER_CONTINUE;
|
||||
else
|
||||
{
|
||||
if (exact)
|
||||
|
|
|
@ -173,12 +173,14 @@ bool is_lateral(int paper);
|
|||
//#define HUAGAO_SETTING_STR_PAGE_DOUBLE "双面"
|
||||
//#define HUAGAO_SETTING_STR_PAGE_OMIT_EMPTY "跳过空白页(通用)"
|
||||
//#define HUAGAO_SETTING_STR_PAGE_OMIT_EMPTY_RECEIPT "跳过空白页(发票纸)"
|
||||
//#define HUAGAO_SETTING_STR_PAGE_OMIT_EMPTY_FILE_SIZE "跳过空白页(基于文件大小)"
|
||||
//#define HUAGAO_SETTING_STR_PAGE_FOLIO "对折"
|
||||
enum {
|
||||
PAGE_SINGLE = 0,
|
||||
PAGE_DOUBLE,
|
||||
PAGE_OMIT_EMPTY,
|
||||
PAGE_OMIT_EMPTY_RECEIPT,
|
||||
PAGE_OMIT_EMPTY_FILE_SIZE,
|
||||
PAGE_FOLIO,
|
||||
};
|
||||
int match_best_page(std::string& val, bool* exact);
|
||||
|
@ -273,6 +275,7 @@ enum
|
|||
{
|
||||
DOUBLE_PAPER_CONTINUE = 0x01, // 继续扫描
|
||||
DOUBLE_PAPER_SAVE_IMG = 0x02, // 保存图片
|
||||
DOUBLE_PAPEAR_STOP = 0x03 //丢弃并停止
|
||||
};
|
||||
int double_paper_flag_from_option_value(std::string& opt_val, bool* exact);
|
||||
std::string double_paper_flag_to_option_value(int flag);
|
||||
|
@ -614,6 +617,12 @@ typedef struct _scan_conf
|
|||
uint8_t fold_concatmode; /**< 对折拼接模式 0左右,1上下,2自动对折>*/
|
||||
int HsvFilterType; /**< 答题卡留红出杂色功能类型 暂定为0*/
|
||||
bool is_colorcast; /**< 色偏校正*/
|
||||
int discare_edge; /**< 跳过空白页边缘缩进>*/
|
||||
int discare_dilate; /**< 调过空白页纸张杂点阈值>*/
|
||||
double discare_meanth; /**< 调过空白页文稿底色阈值>*/
|
||||
bool en_contaminationdetection; /**< 脏污检测使能>*/
|
||||
bool detect_size_diascard_blank; /**< 基于压缩图像大小跳过空白页使能*/
|
||||
int refuseInflow_level; /**< 防止渗透等级*/
|
||||
uint32_t reserve[1024]; /**< 预留4096字节做协议扩展*/
|
||||
}SCANCONF ,*LPSCANCONF;
|
||||
//图像参数设置 -OVER
|
||||
|
@ -632,7 +641,7 @@ namespace setting_hardware
|
|||
unsigned int ultrasonic_enable : 1; // 是否进行超声波检测(双/多张进纸检测)
|
||||
unsigned int staple_enbale : 1; // 是否进行钉书钉检测
|
||||
unsigned int screw_detect_enable : 1; // 是否歪斜检测
|
||||
unsigned int screw_detect_level : 3; // 歪斜检测水平
|
||||
unsigned int screw_detect_level : 3; // 歪斜检测水平 bit14
|
||||
unsigned int iscorrect_mod : 1; // 是否自动校正
|
||||
unsigned int is_autopaper : 1; // 是否自动进纸
|
||||
// unsigned int reserved1 : 4; // 保留
|
||||
|
@ -641,7 +650,8 @@ namespace setting_hardware
|
|||
unsigned int en_anlogic_key : 1; //
|
||||
unsigned int en_autosize : 1; //
|
||||
unsigned int pc_correct : 1; // 是否在PC端校正 1:不校正 cis原图,0:校正
|
||||
unsigned int enable_sizecheck : 1; // 是否进行尺寸检测
|
||||
//unsigned int enable_sizecheck : 1; // 是否进行尺寸检测 2023-10-11 屏蔽 此bit位变更为double_out_en
|
||||
unsigned int double_out_en : 1; //true 双张纸搓出出纸口, false 卡在出纸口
|
||||
unsigned int enabledsp_cache : 1; // 是否在片上缓存
|
||||
unsigned int sizeerror_errorratio : 9; // 幅面检测
|
||||
}params_3399;
|
||||
|
@ -668,37 +678,47 @@ namespace setting_hardware
|
|||
typedef union hg_scanner_config_3288
|
||||
{
|
||||
unsigned int value;
|
||||
//struct
|
||||
//{
|
||||
// unsigned int pageSize : 5;
|
||||
// unsigned int isColor : 1;
|
||||
// unsigned int dpi : 2;
|
||||
// unsigned int doubleFeeded : 1;
|
||||
// unsigned int enableUV : 1;
|
||||
// unsigned int enableLed : 1;
|
||||
// unsigned int sizedetece : 1;
|
||||
// unsigned int reversed1 : 5;
|
||||
// unsigned int isCorrect : 1;
|
||||
// unsigned int dstHeight : 8;
|
||||
// unsigned int reversed2 : 6;
|
||||
//}params;
|
||||
|
||||
struct // changed on 2022-07-25
|
||||
{
|
||||
unsigned int pageSize : 5;
|
||||
unsigned int isColor : 1;
|
||||
unsigned int dpi : 2;
|
||||
unsigned int doubleFeeded : 1;
|
||||
unsigned int enableStable : 1;
|
||||
unsigned int en_doublefeed_check : 1;
|
||||
unsigned int enableLed : 1;
|
||||
unsigned int enableSizeDetect : 1;
|
||||
unsigned int lutmode : 1; // 设置文本和照片模式, 0 - 文本;1 - 照片。默认值为“0”
|
||||
unsigned int moire : 1;
|
||||
unsigned int reversed1 : 3;
|
||||
unsigned int dirty_detect : 1;
|
||||
unsigned int reversed1 : 2;
|
||||
unsigned int isCorrect : 1; //设置0 为原图,1为校正后的图
|
||||
unsigned int dstHeight : 8;
|
||||
unsigned int reversed2 : 6;
|
||||
}params_3288;
|
||||
}HGSCANCONF_3288;
|
||||
|
||||
typedef union hg_scanner_config_7010
|
||||
{
|
||||
unsigned int value;
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned int pageSize : 5;
|
||||
unsigned int isColor : 1;
|
||||
unsigned int dpi : 2;
|
||||
unsigned int doubleFeeded : 1;
|
||||
unsigned int en_doublefeed_check : 1;
|
||||
unsigned int enableLed : 1;
|
||||
unsigned int enableSizeDetect : 1;
|
||||
unsigned int lutmode : 1; // 设置文本和照片模式, 0 - 文本;1 - 照片。默认值为“0”
|
||||
unsigned int moire : 1;
|
||||
unsigned int reversed1 : 2;
|
||||
unsigned int isCorrect : 1; //设置0 为原图,1为校正后的图
|
||||
unsigned int dc : 7; //设置PWM占空比
|
||||
unsigned int reversed2 : 8;
|
||||
}params_7010;
|
||||
}HGSCANCONF_7010;
|
||||
}
|
||||
//硬件协议定义 -OVER
|
||||
namespace setting3288dsp
|
||||
|
@ -721,11 +741,13 @@ namespace setting3288dsp
|
|||
{
|
||||
FLAT_INFO info;
|
||||
cv::Mat flat_lut;
|
||||
float vratio;
|
||||
float hratio;
|
||||
};
|
||||
|
||||
struct HG_JpegCompressInfo
|
||||
{
|
||||
unsigned int data_type;
|
||||
unsigned int error_code;
|
||||
unsigned int first_frame;
|
||||
unsigned int last_frame;
|
||||
unsigned int index_frame;
|
||||
|
@ -771,9 +793,11 @@ namespace setting3288dsp
|
|||
USB_DISCONNECTED = 200, //USB 未连接
|
||||
USER_STOP = 201, //用户点击停止
|
||||
AUTO_FLAT_FINISHED = 202, //自动校正完成
|
||||
USB_CONNECTED, //USB已连接
|
||||
HAVE_PAPER,
|
||||
DEVICE_OFF_LINE, //USB链接断开
|
||||
SCANNER_ACTIVED=0x10, //设备未休眠 休眠返回0x100 未休眠返回0x10
|
||||
DOUBLE_FEED_IMAGE=203,//双张校验图像
|
||||
IMAGE_DIRTY_BAND=204,//图像脏污
|
||||
IMAGE_DIRTY_CIS = 205
|
||||
|
||||
} UsbSupported, * PUsbSupported;
|
||||
//
|
||||
//设备状态 - OVER
|
||||
|
@ -936,6 +960,12 @@ namespace setting3288dsp
|
|||
GETMOTORPARMLEN = 0x203,
|
||||
SETMOTORPARAM = 0x204,
|
||||
SETMOTORPARAMLEN = 0x205,
|
||||
SET_BACKUP_CONFIG = 0x304,
|
||||
SET_RECOVERY = 0x305,
|
||||
GET_BACKUP_STATUS = 0x306,
|
||||
GET_RECOVERY_STATUS = 0x307,
|
||||
GET_DATETIME,
|
||||
SET_DATETIME,
|
||||
DEVICES_7010 = 0x7010
|
||||
};
|
||||
typedef enum tagUsbKeyWords UsbKeyWords, * PUsbKeyWords;
|
||||
|
@ -1057,6 +1087,7 @@ namespace setting3399
|
|||
SR_GET_TOKEN_LENGHT,
|
||||
SR_DECODE_TOKEN,
|
||||
SR_CLEAN_PAPER_ROAD, //清理纸道
|
||||
SR_BACKUP_RESTORES_HUAGODIR=67,
|
||||
SR_GET_CUO_ERROR = 0x50,
|
||||
SR_GET_DOU_ERROR,
|
||||
SR_GET_JAM_ERROR,
|
||||
|
@ -1076,6 +1107,11 @@ namespace setting3399
|
|||
SR_SET_H_600_RATIO,
|
||||
SR_GET_V_600_RATIO,
|
||||
SR_SET_V_600_RATIO,
|
||||
SR_GET_ARM_DATETIME=101,
|
||||
SR_GET_ARM_DATETIME_LENGHT=102,
|
||||
SR_SET_ARM_DATETIME=103,
|
||||
SR_SET_LCD_LANGUAGE = 106,
|
||||
SR_GET_LCD_LANGUAGE = 107,
|
||||
SR_UPDATA_START = 0x100,
|
||||
SR_UPDATA_STAUTUS = 0x101,
|
||||
SR_UPDATA_MD5_RELUST = 0x102,
|
||||
|
@ -1113,11 +1149,24 @@ namespace setting3399
|
|||
AutoCorrect,
|
||||
STOPSCAN,
|
||||
};
|
||||
enum Image_Status
|
||||
{
|
||||
Image_Status_OK = 0, // normal
|
||||
Image_Status_Double = 1 << 0, // double-feeded paper
|
||||
Image_Status_Jammed = 1 << 1, // jammed paper
|
||||
Image_Status_Staple = 1 << 2, // staples on the paper
|
||||
Image_Status_Size_Error = 1 << 3, // size check failed
|
||||
Image_Status_Dogear = 1 << 4, // paper has dogear - common
|
||||
Image_Status_Partial = 1 << 5, // dogear - scanned partial
|
||||
Image_Status_Blank = 1 << 6 // blank image
|
||||
};
|
||||
|
||||
struct HGEIntInfo
|
||||
{
|
||||
HGType From;
|
||||
unsigned int Code;
|
||||
unsigned int Img_Index;
|
||||
Image_Status Img_Status;
|
||||
};
|
||||
enum PaperSize_ //239 302 402
|
||||
{
|
||||
|
@ -1333,10 +1382,10 @@ namespace setting3399
|
|||
|
||||
#ifdef UOS
|
||||
#define HELP_PATH "../../entries/help/NeuScan_scanSettings_Help_manual.pdf";
|
||||
#define HELP_PATH_EN ""
|
||||
#define HELP_PATH_EN "../../entries/help/NeuScan_scanSettings_Help_manual_EN.pdf"
|
||||
#elif KYLIN
|
||||
#define HELP_PATH "../doc/NeuScan_scanSettings_Help_manual.pdf";
|
||||
#define HELP_PATH_EN ""
|
||||
#define HELP_PATH_EN "../doc/NeuScan_scanSettings_Help_manual_EN.pdf"
|
||||
#endif
|
||||
|
||||
#elif defined(OEM_DELI)
|
||||
|
@ -1409,7 +1458,7 @@ namespace setting3399
|
|||
#define IMGPRC_LIBNANE "NEUImgProc.dll"
|
||||
#define HGBASE_LIBNAME "NEUBase.dll"
|
||||
#define HELP_PATH "NeuScan_scanSettings_Help_manual.pdf"
|
||||
#define HELP_PATH_EN ""
|
||||
#define HELP_PATH_EN "NeuScan_scanSettings_Help_manual_EN.pdf"
|
||||
|
||||
#elif defined(OEM_DELI)
|
||||
#define HGVERSION_LIBNANE "DLVersion.dll"
|
||||
|
|
|
@ -639,7 +639,7 @@ tiny_buffer::tiny_buffer(unsigned int size
|
|||
, const char* name_leading
|
||||
, const char* ext
|
||||
, unsigned int uniq_id)
|
||||
: size_(size), buf_(nullptr), img_statu_(SANE_Image_Statu_OK)
|
||||
: size_(size), buf_(nullptr), img_statu_(IMG_STATUS_OK)
|
||||
{
|
||||
init(tmp_path, name_leading, ext, uniq_id);
|
||||
}
|
||||
|
@ -785,7 +785,7 @@ void final_img_queue::clear(void)
|
|||
mem_usage_ = 0;
|
||||
queue_.clear();
|
||||
}
|
||||
bool final_img_queue::put(int w, int h, int bpp, int channels, int line_bytes, void* data, unsigned bytes
|
||||
bool final_img_queue::put(int w, int h, int bpp, int channels, int line_bytes, void* data, unsigned bytes, int statu
|
||||
, const char* tmp_path, const char* name_leading, const char* ext, int ind, uint32_t id)
|
||||
{
|
||||
IMGDT imgd;
|
||||
|
@ -799,6 +799,7 @@ bool final_img_queue::put(int w, int h, int bpp, int channels, int line_bytes, v
|
|||
imgd.header.line_bytes = line_bytes;
|
||||
imgd.header.width = w;
|
||||
imgd.header.src_id = id;
|
||||
imgd.header.statu = statu;
|
||||
imgd.offset = 0;
|
||||
imgd.data.reset(new tiny_buffer(bytes, tmp_path, name_leading, ext, ind));
|
||||
|
||||
|
|
|
@ -213,6 +213,7 @@ typedef struct _img_header
|
|||
int bits;
|
||||
int channels;
|
||||
int line_bytes;
|
||||
int statu; // SANE_Image_Statu
|
||||
unsigned bytes;
|
||||
uint32_t src_id;
|
||||
}IMH;
|
||||
|
@ -236,7 +237,7 @@ public:
|
|||
unsigned long long mem_usage(void);
|
||||
size_t size(void);
|
||||
void clear(void);
|
||||
bool put(int w, int h, int bpp, int channels, int line_bytes, void* data, unsigned bytes
|
||||
bool put(int w, int h, int bpp, int channels, int line_bytes, void* data, unsigned bytes, int statu
|
||||
, const char* tmp_path, const char* name_leading, const char* ext, int ind, uint32_t id);
|
||||
bool front(IMH* header);
|
||||
void fetch_front(void* buf, int* len, bool* over);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
|
@ -129,7 +130,8 @@ class hg_scanner
|
|||
void working_begin(void*);
|
||||
void working_done(void*);
|
||||
|
||||
void image_process(std::shared_ptr<tiny_buffer>& buffer, uint32_t id);
|
||||
void save_exception_image(std::shared_ptr<tiny_buffer>& buffer, int sn, const char* desc);
|
||||
bool image_process(std::shared_ptr<tiny_buffer>& buffer, uint32_t id); // 返回true - continue; false - exit and invoked do_stop
|
||||
void reset_custom_area_range(int paper);
|
||||
float reset_custom_area_jsn_value(const char* name, double& var, float range_l, float range_u, float value_l, float value_u); // return cur value
|
||||
int set_color_change(void);
|
||||
|
@ -241,6 +243,8 @@ protected:
|
|||
int setting_get_motor_ver(void* data, long* len);
|
||||
int setting_get_initial_boot_time(void* data, long* len);
|
||||
int setting_set_discardblank(void* data, long* len);
|
||||
int setting_detect_lens_dirty(void* data, long* len);
|
||||
int setting_set_period(void* data, long* len);
|
||||
|
||||
virtual void on_device_reconnected(void);
|
||||
virtual int on_scanner_closing(bool force);
|
||||
|
@ -260,6 +264,9 @@ protected:
|
|||
virtual int on_pick_paper_threshold(double threshold) = 0; //设置搓纸阈值
|
||||
virtual int on_is_auto_paper(bool isautopaper) = 0; //待纸扫描
|
||||
virtual int on_cis_get_image(bool type) = 0;
|
||||
virtual int on_process_double_paper(bool type) = 0; //双张图像校验
|
||||
virtual int on_detect_lens_dirty(bool &type); //检测镜头脏污
|
||||
virtual int on_set_period(int val); //PWM占空比
|
||||
protected:
|
||||
|
||||
virtual int set_setting_value(const char* name, void* data, long* len);
|
||||
|
@ -273,6 +280,7 @@ protected:
|
|||
void adjust_color(hg_imgproc::HIMGPRC handle);
|
||||
hg_imgproc::IMGPRCPARAM get_image_process_object(int model);
|
||||
SANE_Image_Statu last_usb_image_statu(int err);
|
||||
bool is_auto_scan(void); // BUG-732
|
||||
hg_imgproc::HIMGPRC ImagePrc_pHandle_;
|
||||
protected:
|
||||
ScannerSerial serial_;
|
||||
|
@ -296,8 +304,9 @@ protected:
|
|||
std::vector<std::string> jsn_children_;
|
||||
std::vector<string> erase_depend_; //需要删除父依赖项
|
||||
json setting_jsn_;
|
||||
|
||||
IMGPRCFIXPARAM image_prc_param_;
|
||||
|
||||
|
||||
int erase_bkg_range_; // 背景移除像素范围
|
||||
int noise_range_; // 噪点优化尺寸
|
||||
TwSS paper_size_;
|
||||
|
@ -316,16 +325,13 @@ protected:
|
|||
int is_quality_; // 画质设置 0 - 速度优先;1 - 画质优先
|
||||
bool is_color_fill; // 色彩填充
|
||||
bool is_multiout; // 多流输出
|
||||
|
||||
int bw_threshold_; // 黑白图像阈值 (added on 2022-06-28)
|
||||
int feedmode_; // 分纸强度
|
||||
int sleeptime_; // 睡眠时间
|
||||
bool is_auto_paper_scan; // 待纸扫描
|
||||
bool size_check; // 尺寸检测
|
||||
|
||||
bool save_feedmode_type_; //保存分支强度狀態
|
||||
bool save_sleeptime_type_; //保存休眠時間
|
||||
|
||||
bool isremove_left_hole; //设置左边除穿孔
|
||||
bool isremove_right_hole; //设置右边除穿孔
|
||||
bool isremove_top_hole; //设置上边除穿孔
|
||||
|
@ -343,37 +349,19 @@ protected:
|
|||
int is_auto_paper_scan_exit_time; //待纸扫描退出时间
|
||||
bool is_auto_feedmode_; //是否启用自动分纸强度
|
||||
bool is_discardblank; //是否启动跳过空白页
|
||||
bool is_lens_dirty; //是否检测镜头脏污
|
||||
int split3399_; //3399设备正面和反面图像是相对的,所以对折时反面需要进行特殊处理
|
||||
int pid_;
|
||||
|
||||
|
||||
SANE_DISTORTION_VAL distortion_val; //畸变修正结构体保存
|
||||
|
||||
|
||||
|
||||
int split3399_; //3399设备正面和反面图像是相对的,所以对折时反面需要进行特殊处理
|
||||
int pid_;
|
||||
|
||||
/////////不同的固件号版本支持
|
||||
//bool is_kernelsnap_239_220830_; //此版本支持,手动睡眠唤醒,分纸强度
|
||||
//bool is_kernelsnap_239_211209_; //获取固件版本号是否是新旧版本
|
||||
//bool is_kernelsnap_239_221027_; //此版本一下不支持拆分模式 pc实现
|
||||
|
||||
//bool is_kernelsnap3288_221106_; //G300 3288 在221106版本支持真实300dpi
|
||||
//bool is_kernelsnap3288_230210_; //G300 3288 在230210版本支持真实600dpi
|
||||
|
||||
//bool is_kernelsnap3288_230303_; //G300 3288 支持清除历史扫描张数
|
||||
|
||||
//bool is_kernelsnap_devsislock; //支持设备锁的版本
|
||||
//bool is_kernelsnap_239_3C_; //支持偏色校正的版本,自适应配置
|
||||
//bool is_kernelsnap_439_3C0606; //支持偏色校正的版本
|
||||
//bool is_kernelsnap_239_220500_; //支持双张保留的版本
|
||||
|
||||
//bool is_kernelsnap_239_220429_; //第一个安陆版本,支持设备日志导出
|
||||
//bool is_kernelsnap_239_220430_; //待纸扫描
|
||||
// bool is_kernelsnap_211227_; //此版本以下,不支持真实dpi ,只设置1下去
|
||||
|
||||
|
||||
bool firmware_sup_wait_paper_; //固件支持 待纸扫描 139 239-3B0431, 439-3B0629
|
||||
bool firmware_sup_pick_strength_; //固件支持 分纸强度 139 239-3B0830
|
||||
bool firmware_sup_log_export_; //固件支持 日志导出 139 239-3B0429
|
||||
bool firmware_sup_log_export_G300_; //固件支持 不用协议,直接读片上文件,设备日志导出 300 - 0430
|
||||
bool firmware_sup_color_corr_; //固件支持 偏色校正 139 239 439-3C
|
||||
bool firmware_sup_wake_device_; //固件支持 唤醒设备 139 239-3B0830
|
||||
bool firmware_sup_double_img; //固件支持 双张保留 139 239-3C
|
||||
|
@ -384,7 +372,14 @@ protected:
|
|||
bool firmware_sup_morr_; //固件支持 摩尔纹 139 239-3C0518
|
||||
bool firmware_sup_color_fill_; //固件支持 色彩填充 139 239 439 -3C
|
||||
bool firmware_sup_history_cnt; //固件支持 清除历史张数 3288 G300 220303
|
||||
bool firmware_sup_double_check; //固件支持 双张校验 231027
|
||||
bool firmware_sup_dirty_check; //固件支持 脏污检测 231027
|
||||
bool firmware_sup_backup_restore; //固件支持 备份还原 231021
|
||||
bool firmware_sup_boardTime; //固件支持 板级时间校验 231021
|
||||
bool firmware_sup_permeation_level; //固件支持 防渗透等级 3399-3C1206
|
||||
bool firmware_sup_device_7010; //G300 设备但是7010 2023/9/21
|
||||
bool firmware_sup_firmware_language_;//固件支持 设置或获取固件语言模式 仅139 239有固件语言功能,3C1229及之后支持
|
||||
bool firmware_sup_300device_D8_; //G300 固件211124及以前是3288设备,之后是D8设备
|
||||
int mat_width;
|
||||
int mat_height;
|
||||
|
||||
|
@ -399,6 +394,7 @@ protected:
|
|||
unsigned long memory_size_; // MB
|
||||
unsigned long wait_mem_seconds_; // wait up to wait_mem_seconds_ if memory usage is great than memory_size_
|
||||
bool isx86_Advan_;
|
||||
bool no_paper_check_ = false; // 扫描前是否检测无纸状态;可以通过配置[func]no-paper-chk=1开启
|
||||
int stop_fatal_;
|
||||
BlockingQueue<std::shared_ptr<tiny_buffer>> imgs_;
|
||||
|
||||
|
@ -408,6 +404,7 @@ protected:
|
|||
|
||||
void change_setting_language(bool init);
|
||||
void erase_option(const char* name);
|
||||
void erase_range(const char* name, const char* opt_name);
|
||||
void init_settings(const char* json_setting_text);
|
||||
int init_settings(int pid);
|
||||
void change_string_2_lang_id(const char* name, const char* key);
|
||||
|
@ -426,14 +423,7 @@ protected:
|
|||
int save_final_image(hg_imgproc::LPIMGHEAD head, void* buf, uint32_t id = -1);
|
||||
|
||||
void adjust_filling_hole(LPSCANCONF conf);
|
||||
|
||||
enum thread_running
|
||||
{
|
||||
THREAD_RUNNING_IDLE = 0,
|
||||
THREAD_RUNNING_USB = 1 << 0,
|
||||
THREAD_RUNNING_IMAGE = 1 << 1,
|
||||
};
|
||||
int is_running(void); // return thread_running
|
||||
int wait_one_image_from_start(bool& handled);
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// 新增自定义伽玛曲线及扫描区域属性 - 2022-05-05
|
||||
|
@ -456,6 +446,9 @@ protected:
|
|||
bool is_white_0_; // 是否‘0’代表白色
|
||||
|
||||
public:
|
||||
int start(void);
|
||||
int stop(void);
|
||||
|
||||
void set_ui_callback(sane_callback cb, bool enable_async_io);
|
||||
void set_dev_family(const char* family);
|
||||
void set_read_over_with_no_data(bool no_data);
|
||||
|
@ -473,11 +466,19 @@ public:
|
|||
bool is_online(void);
|
||||
void on_language_changed(void);
|
||||
|
||||
enum thread_running
|
||||
{
|
||||
THREAD_RUNNING_IDLE = 0,
|
||||
THREAD_RUNNING_USB = 1 << 0,
|
||||
THREAD_RUNNING_IMAGE = 1 << 1,
|
||||
};
|
||||
int is_running(void); // return thread_running
|
||||
|
||||
public:
|
||||
virtual int start(void);
|
||||
virtual int get_image_info(SANE_Parameters* ii);
|
||||
virtual int do_start(void) = 0;
|
||||
virtual int do_stop(void) = 0;
|
||||
virtual int get_image_info(SANE_Parameters* ii, int len);
|
||||
virtual int read_image_data(unsigned char* buf, int* len);
|
||||
virtual int stop(void);
|
||||
virtual int reset(void);
|
||||
virtual int device_io_control(unsigned long code, void* data, unsigned* len);
|
||||
virtual int discard_all_images(void) = 0;
|
||||
|
@ -505,22 +506,18 @@ public:
|
|||
/////////////成功返回:SCANNER_ERR_OK /////////////
|
||||
/////////////失败返回:IO错误码 /////////////
|
||||
virtual int set_leaflet_scan(void) = 0; //单张扫描
|
||||
virtual int get_abuot_info(void); //获取软件关于信息 (基类实现)
|
||||
virtual int get_abuot_info(void); //获取软件关于信息 (基类实现)
|
||||
virtual int restore_default_setting(void); //恢复默认设置 (基类实现)
|
||||
virtual int set_final_image_format(SANE_FinalImgFormat* fmt);//设置图像处理最终输出(final())的图像数据格式 (基类实现) ***
|
||||
|
||||
|
||||
virtual int get_compression_format(void); //获取支持的压缩格式 不支持
|
||||
virtual int set_compression_format(void); //设置图像数据最终输出的压缩格式 不支持
|
||||
|
||||
virtual int set_auto_color_type(void); //设置自动匹配颜色模式 (基类实现)
|
||||
virtual int set_clear_roller_num(void) = 0; //清除滚轴计数
|
||||
virtual int set_clear_history_num(void) = 0; //清除历史张数
|
||||
|
||||
virtual int get_device_code(void); //获取设备编码 不支持
|
||||
|
||||
virtual int get_scanner_paperon(SANE_Bool& type)=0; //获取设备有无纸张 /*/ type : false无纸(不正常状态false) true有纸 */
|
||||
|
||||
virtual int get_scan_is_sleep(SANE_Bool& type) = 0; //获取设备是否休眠当中 /*/ type : false休眠(不正常状态false) true未休眠*/
|
||||
virtual int get_sleep_time(int& data) = 0; //获取功耗模式(休眠) /*/ data > 0*/
|
||||
virtual int set_sleep_time(int data) = 0; //设置功耗模式(休眠) /*/ data > 0*/
|
||||
|
@ -540,23 +537,22 @@ public:
|
|||
virtual int get_scan_mode(bool& type) ; //获取设备是否计数模式 /*/ type:false计数模式 true非计数模式
|
||||
virtual int set_speed_mode(int data) = 0; //设置速度模式 /*/ 设备不同值不同,详情见子类注释
|
||||
virtual int get_speed_mode(int &data) = 0; //获取速度模式 /*/ 设备不同值不同,详情见子类注释
|
||||
|
||||
virtual int set_distortion_image(bool type); //设置畸变校正图 /*/ 基类处理
|
||||
virtual int get_distortion_check_val(int &val); //获取自动计算畸变校正值 /*/ 基类处理
|
||||
|
||||
virtual int set_devs_distortion_check_val(float data) = 0; //设置畸变矫正值 float;
|
||||
virtual int get_devs_distortion_check_val(float& data) = 0; //获取设备畸变值 float;
|
||||
|
||||
virtual int set_auto_flat(int data) = 0; //设置自动平场校正
|
||||
// data:0(ALL) 1(200dpi、gray) 2(200dpi、color) 3(300dpi、gray) 4(300dpi、color) 5(600dpi、gray) 6(600dpi、color)
|
||||
virtual int set_updata0303(void) ;
|
||||
virtual int get_motor_board_ver(string &ver); //获取G239电机板的固件号 //3399设备支持
|
||||
|
||||
virtual int set_devs_time(string times); //设置设备时间 //3399设备支持
|
||||
virtual int get_devs_time(string ×); //获取设备时间 //3399设备支持
|
||||
|
||||
virtual int get_devs_cpu(string& cpu); //获取设备内存大小
|
||||
virtual int get_devs_disk(string& disk); //获取设备硬盘容量大小
|
||||
virtual int get_devs_cpu(int& cpu); //获取设备内存大小(kb)
|
||||
virtual int get_devs_disk(int& disk); //获取设备硬盘容量大小(kb)
|
||||
virtual int set_restore(); //还原文件
|
||||
virtual int set_backup(); //备份文件
|
||||
virtual int set_firmware_language(int language_mode); // 设置固件语言模式 仅139、239设备支持; //0->简体中文; 1->繁体中文; 2->English
|
||||
virtual int get_firmware_language(int& language_mode); // 获取固件语言模式 仅139、239设备支持; //0->简体中文; 1->繁体中文; 2->English
|
||||
};
|
||||
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,4 @@
|
|||
#pragma once
|
||||
#pragma once
|
||||
|
||||
// hg_scanner is the base class of kinds of scanners
|
||||
//
|
||||
|
@ -44,13 +44,14 @@ protected:
|
|||
virtual int on_pick_paper_threshold(double threshold) override; //设置搓纸阈值
|
||||
virtual int on_is_auto_paper(bool isautopaper) override; //待纸扫描
|
||||
virtual int on_cis_get_image(bool isautopaper) override; //获取cis原图
|
||||
virtual int on_process_double_paper(bool type) override; //双张图像校验
|
||||
public:
|
||||
hg_scanner_200(const char* dev_name,int vid, usb_io* io);
|
||||
~hg_scanner_200();
|
||||
|
||||
public:
|
||||
virtual int start(void)override;
|
||||
virtual int stop(void)override;
|
||||
virtual int do_start(void) override;
|
||||
virtual int do_stop(void) override;
|
||||
|
||||
private:
|
||||
int initdevice();
|
||||
|
@ -58,7 +59,7 @@ private:
|
|||
int readusb(USBCB &usb);
|
||||
int pop_image();
|
||||
int get_scanner_status(USBCB &usb);
|
||||
int get_img_data(unsigned int bytes, SANE_Image_Statu statu = SANE_Image_Statu_OK);
|
||||
int get_img_data(unsigned int bytes, SANE_Image_Statu statu = IMG_STATUS_OK);
|
||||
int writedown_device_configuration(bool type =false,setting_hardware::HGSCANCONF_DSP *d = NULL);
|
||||
void writedown_image_configuration(void);
|
||||
void printf_devconfig(setting_hardware::HGSCANCONF_DSP *d = NULL);
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -41,7 +41,7 @@ class hg_scanner_239 : public hg_scanner
|
|||
int writedown_device_configuration(bool type = false, setting_hardware::HGSCANCONF_3399* dev_conf = NULL);//false 在start再把type置为true,其他做设置时不发
|
||||
int writedown_image_configuration(void);
|
||||
int pop_first_image(void);
|
||||
int read_one_image_from_usb(SANE_Image_Statu statu = SANE_Image_Statu_OK);
|
||||
int read_one_image_from_usb(SANE_Image_Statu statu = IMG_STATUS_OK);
|
||||
bool is_dev_image_process_done(void);
|
||||
bool is_dev_image_keep_last_paper(void);
|
||||
|
||||
|
@ -51,6 +51,8 @@ class hg_scanner_239 : public hg_scanner
|
|||
|
||||
int write_control_device_files(std::string file_path,std::string file_str);
|
||||
int read_control_device_files(std::string file_path, std::string &file_str);
|
||||
|
||||
int update_boarddatetime();
|
||||
protected:
|
||||
virtual void on_device_reconnected(void) override;
|
||||
virtual int on_scanner_closing(bool force) override;
|
||||
|
@ -73,6 +75,8 @@ protected:
|
|||
virtual int on_pick_paper_threshold(double threshold)override;
|
||||
virtual int on_is_auto_paper(bool isautopaper)override; //待纸扫描
|
||||
virtual int on_cis_get_image(bool isautopaper) override; //cis 原图获取
|
||||
virtual int on_process_double_paper(bool type) override; //双张图像校验
|
||||
virtual int on_detect_lens_dirty(bool &type) override; //检测镜头脏污
|
||||
|
||||
|
||||
public:
|
||||
|
@ -82,8 +86,8 @@ public:
|
|||
public:
|
||||
//virtual int get_image_info(IMG_PARAM* ii) override;
|
||||
//virtual int read_image_data(unsigned char* buf, int* len) override;
|
||||
virtual int start(void) override;
|
||||
virtual int stop(void) override;
|
||||
virtual int do_start(void) override;
|
||||
virtual int do_stop(void) override;
|
||||
virtual int reset(void) override;
|
||||
virtual int device_io_control(unsigned long code, void* data, unsigned* len) override;
|
||||
virtual int get_roller_life(void) override;
|
||||
|
@ -142,7 +146,11 @@ public:
|
|||
|
||||
virtual int set_devs_time(string times); //设置设备时间 //3399设备支持
|
||||
virtual int get_devs_time(string& times); //获取设备时间 //3399设备支持
|
||||
virtual int get_devs_cpu(string& cpu); //获取设备内存大小
|
||||
virtual int get_devs_disk(string& disk); //获取设备硬盘容量大小
|
||||
virtual int get_devs_cpu(int& cpu); //获取设备内存大小(kb)
|
||||
virtual int get_devs_disk(int& disk); //获取设备硬盘容量大小(kb)
|
||||
virtual int set_restore(); //还原文件
|
||||
virtual int set_backup(); //备份文件
|
||||
virtual int set_firmware_language(int language_mode); // 设置固件语言模式 仅139、239设备支持; //0->简体中文; 1->繁体中文; 2->English
|
||||
virtual int get_firmware_language(int& language_mode); // 获取固件语言模式 仅139、239设备支持; //0->简体中文; 1->繁体中文; 2->English
|
||||
};
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -44,13 +44,16 @@ protected:
|
|||
virtual int on_pick_paper_threshold(double threshold)override;
|
||||
virtual int on_is_auto_paper(bool isautopaper)override; //待纸扫描
|
||||
virtual int on_cis_get_image(bool isautopaper) override; //cis 原图获取
|
||||
virtual int on_process_double_paper(bool type) override; //双张图像校验
|
||||
virtual int on_detect_lens_dirty(bool &type) override; //检测镜头脏污
|
||||
|
||||
public:
|
||||
hg_scanner_300(const char* dev_name,int pid, usb_io* io);
|
||||
~hg_scanner_300();
|
||||
public:
|
||||
virtual int start(void)override;
|
||||
virtual int stop(void)override;
|
||||
virtual int do_start(void) override;
|
||||
virtual int do_stop(void) override;
|
||||
|
||||
private:
|
||||
int set_kernelsnap_ver();
|
||||
int agreement(TwSS tw,int align);
|
||||
|
@ -60,13 +63,12 @@ private:
|
|||
int pop_image(void);
|
||||
int get_scanner_status(USBCB &usb);
|
||||
int get_img_data(std::shared_ptr<tiny_buffer> &imagedata);
|
||||
int get_img_data_7010();
|
||||
int writedown_device_configuration(bool type =false,setting_hardware::HGSCANCONF_3288 *d = NULL);
|
||||
void writedown_image_configuration(void);
|
||||
void printf_devconfig(setting_hardware::HGSCANCONF_3288 *d = NULL);
|
||||
int get_device_type(bool &type);
|
||||
int get_devs_distortion_check_val(float& data, int dpi, int dir);//获取设备畸变值 DPI=1、2、3; dir = 0,1;
|
||||
int update_boarddatetime();
|
||||
|
||||
setting3288dsp::HG_JpegCompressInfo frame_info_;
|
||||
///////////////////////7010专有协议,获取校正数据//////////////////////
|
||||
//inx:序号//
|
||||
//dpi:1--->200 2--->300 3--->600//
|
||||
|
@ -77,14 +79,7 @@ private:
|
|||
setting_hardware::HGSCANCONF_3288 dsp_config;
|
||||
Device::PaperSize papersize;
|
||||
bool is_devs_sleep_;
|
||||
|
||||
|
||||
int first_frame_total; //设置的帧数
|
||||
int last_frame_total; //实际采集的帧数
|
||||
|
||||
|
||||
std::vector<unsigned char> jpgdata_;
|
||||
int index_;
|
||||
;
|
||||
|
||||
public:
|
||||
//////////////固定的硬件信息设置或获取//////////////
|
||||
|
@ -131,6 +126,8 @@ public:
|
|||
virtual int set_auto_flat(int data)override; //设置自动平场校正
|
||||
// data:0(ALL) 1(200dpi、gray) 2(200dpi、color) 3(300dpi、gray) 4(300dpi、color) 5(600dpi、gray) 6(600dpi、color)
|
||||
virtual int set_updata0303(void)override;
|
||||
virtual int get_devs_cpu(string& cpu); //获取设备内存大小
|
||||
virtual int get_devs_disk(string& disk); //获取设备硬盘容量大小
|
||||
virtual int get_devs_cpu(int& cpu); //获取设备内存大小(kb)
|
||||
virtual int get_devs_disk(int& disk); //获取设备硬盘容量大小(kb)
|
||||
virtual int set_restore(); //还原文件
|
||||
virtual int set_backup(); //备份文件
|
||||
};
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,4 @@
|
|||
#pragma once
|
||||
#pragma once
|
||||
|
||||
// hg_scanner is the base class of kinds of scanners
|
||||
//
|
||||
|
@ -51,7 +51,7 @@ class hg_scanner_302 : public hg_scanner
|
|||
int writedown_image_configuration(void);
|
||||
int pop_first_image(void);
|
||||
|
||||
int read_one_image_from_usb(SANE_Image_Statu statu = SANE_Image_Statu_OK);
|
||||
int read_one_image_from_usb(SANE_Image_Statu statu = IMG_STATUS_OK);
|
||||
virtual int discard_all_images();
|
||||
virtual int get_roller_life(void) override;
|
||||
|
||||
|
@ -75,6 +75,7 @@ protected:
|
|||
virtual int on_pick_paper_threshold(double threshold)override;
|
||||
virtual int on_is_auto_paper(bool isautopaper)override; //待纸扫描
|
||||
virtual int on_cis_get_image(bool isautopaper) override; //cis 原图获取
|
||||
virtual int on_process_double_paper(bool type) override; //双张图像校验
|
||||
|
||||
|
||||
public:
|
||||
|
@ -82,10 +83,9 @@ public:
|
|||
~hg_scanner_302();
|
||||
|
||||
public:
|
||||
virtual int start(void) override;
|
||||
//virtual int get_image_info(IMG_PARAM* ii) override;
|
||||
//virtual int read_image_data(unsigned char* buf, int* len) override;
|
||||
virtual int stop(void) override;
|
||||
virtual int do_start(void) override;
|
||||
virtual int do_stop(void) override;
|
||||
|
||||
virtual int reset(void) override;
|
||||
virtual int device_io_control(unsigned long code, void* data, unsigned* len) override;
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,157 @@
|
|||
#pragma once
|
||||
|
||||
// hg_scanner is the base class of kinds of scanners
|
||||
//
|
||||
// created on 2022-01-30
|
||||
//
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "hg_scanner.h"
|
||||
#include "../wrapper/hg_log.h"
|
||||
#include "PaperSize.h"
|
||||
|
||||
//#ifdef OEM_HANWANG
|
||||
//#define hg_scanner_306 hw_scanner_300
|
||||
//#elif defined(OEM_LISICHENG)
|
||||
//#define hg_scanner_306 lsc_scanner_300
|
||||
//#endif
|
||||
|
||||
|
||||
class hg_scanner_306 : public hg_scanner
|
||||
{
|
||||
protected:
|
||||
virtual int on_scanner_closing(bool force) override;
|
||||
virtual void thread_handle_usb_read(void) override;
|
||||
virtual int discard_all_images(void) override;
|
||||
virtual int get_roller_life(void) override;
|
||||
|
||||
protected:
|
||||
virtual int on_color_mode_changed(int& color_mode) override; //颜色切换
|
||||
virtual int on_paper_changed(int& paper) override; //纸张大小设置
|
||||
virtual int on_paper_check_changed(bool& check) override; //尺寸检测
|
||||
virtual int on_resolution_changed(int& dpi) override; //分辨率设置
|
||||
virtual int on_ultrasonic_check_changed(bool& check) override; //设置超声波检测
|
||||
virtual int on_staple_check_changed(bool& check) override; //设置订书针检测
|
||||
virtual int on_skew_check_changed(bool& check) override; //设置歪斜检测
|
||||
virtual int on_skew_check_level_changed(int& check) override; //设置歪斜检测强度
|
||||
virtual int on_get_feedmode(int& feedmode) override; //获取分纸强度
|
||||
virtual int on_set_feedmode(int feedmode) override; //设置分纸强度
|
||||
virtual int on_pic_type(bool& pic)override; //照片模式或者文本模式
|
||||
virtual int on_pick_paper(bool autostrength)override; //自动分纸强度
|
||||
virtual int on_pick_paper_threshold(double threshold)override;
|
||||
virtual int on_is_auto_paper(bool isautopaper)override; //待纸扫描
|
||||
virtual int on_cis_get_image(bool isautopaper) override; //cis 原图获取
|
||||
virtual int on_process_double_paper(bool type) override; //双张图像校验
|
||||
virtual int on_set_period(int val) override; //PWM占空比
|
||||
protected:
|
||||
|
||||
public:
|
||||
hg_scanner_306(const char* dev_name,int pid, usb_io* io);
|
||||
~hg_scanner_306();
|
||||
public:
|
||||
virtual int do_start(void) override;
|
||||
virtual int do_stop(void) override;
|
||||
|
||||
private:
|
||||
int set_kernelsnap_ver();
|
||||
int agreement(TwSS tw,int align);
|
||||
int initdevice();
|
||||
int writeusb(USBCB &usb);
|
||||
int readusb(USBCB &usb);
|
||||
int pop_image(void);
|
||||
int get_scanner_status(USBCB &usb);
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* 注意事项1:7010按帧传输数据 */
|
||||
/* 注意事项2:7010最后一帧为空包,需把最后一帧数据剔除 */
|
||||
/* 注意事项3:7010最后一帧主要作用是反馈当前纸张问题状态码 error_code */
|
||||
/************************************************************************/
|
||||
int get_img_data_7010();
|
||||
int get_img_data_7010_test();
|
||||
|
||||
/*********************获取校正数据***************/
|
||||
/* inx:序号 */
|
||||
/* dpi:1--->200dpi 2--->300dpi 3--->600dpi */
|
||||
/* mode:0 灰度 1彩色 */
|
||||
/************************************************/
|
||||
int get_correction_image(int inx, int dpi, int mode);
|
||||
|
||||
|
||||
|
||||
int writedown_device_configuration(bool type =false,setting_hardware::HGSCANCONF_7010 *d = NULL);
|
||||
void writedown_image_configuration(void);
|
||||
void printf_devconfig(setting_hardware::HGSCANCONF_7010 *d = NULL);
|
||||
int get_device_type(bool &type);
|
||||
int get_devs_distortion_check_val(float& data, int dpi, int dir);//获取设备畸变值 DPI=1、2、3; dir = 0,1;
|
||||
|
||||
setting3288dsp::HG_JpegCompressInfo frame_info_;
|
||||
|
||||
|
||||
private:
|
||||
std::vector<int> savestatus_;
|
||||
setting_hardware::HGSCANCONF_7010 dsp_config;
|
||||
Device::PaperSize papersize;
|
||||
bool is_devs_sleep_;
|
||||
|
||||
|
||||
int first_frame_total_; //设置的帧数
|
||||
int last_frame_total_; //实际采集的帧数
|
||||
int frame_length_ ;
|
||||
int frame_width_ ;
|
||||
int frame_hegiht_ ;
|
||||
|
||||
std::vector<unsigned char> jpgdata_;
|
||||
int index_;
|
||||
|
||||
public:
|
||||
//////////////固定的硬件信息设置或获取//////////////
|
||||
virtual std::string get_firmware_version(void)override;
|
||||
virtual std::string get_serial_num(void)override;
|
||||
virtual std::string get_ip(void)override;
|
||||
|
||||
virtual int set_serial_num(string str) override; //设置序列号
|
||||
virtual int set_vid_pid(int data) override; //设置vidpid
|
||||
virtual int get_vid_pid(int& data)override; //获取vidpid
|
||||
|
||||
/////////////////成功返回:SCANNER_ERR_OK /////////////
|
||||
/////////////////失败返回:IO错误码 /////////////
|
||||
virtual int set_leaflet_scan(void) override; //单张扫描
|
||||
|
||||
|
||||
virtual int set_clear_roller_num(void) override; //清除滚轴计数
|
||||
virtual int set_clear_history_num(void) override; //清除历史张数 0303固件版本才支持
|
||||
|
||||
virtual int get_device_code(void); //获取设备编码 不支持
|
||||
|
||||
virtual int get_scanner_paperon(SANE_Bool& type) override; //获取设备有无纸张 /*/ type : 0无纸 1有纸 */
|
||||
|
||||
virtual int get_scan_is_sleep(SANE_Bool& type) override; //获取设备是否休眠当中 /*/ type : 0休眠 1唤醒状态*/
|
||||
virtual int get_sleep_time(int& data) override; //获取功耗模式(休眠) /*/ data > 0*/
|
||||
virtual int set_sleep_time(int data) override; //设置功耗模式(休眠) /*/ data > 0*/
|
||||
virtual int get_history_scan_count(int& data) override; //获取历史扫描张数 /*/ data > 0*/
|
||||
virtual int get_roller_num(int& data) override; //获取滚轮张数 /*/ data > 0*/
|
||||
virtual int set_notify_sleep(void) override; //唤醒设备
|
||||
virtual int get_device_log(string& log) override; //获取设备日志 /*/ log :储存路径*/
|
||||
virtual int set_devreboot(int data) override; //设置设备重启
|
||||
virtual int set_devshtudown() override; //设置设备关机
|
||||
virtual int set_scan_islock(SANE_Bool type) override; //设置设备是否锁定 /*/ type:0解锁,1锁定*/
|
||||
virtual int get_scan_islock(SANE_Bool& type) override; //获取设备是否锁定 /*/ type:0解锁,1锁定*/
|
||||
virtual int set_scan_lock_check_val(string str) override; //获取设备是否锁定 /*/ str:校验码*/
|
||||
virtual int set_firmware_upgrade(std::string str) override; //固件升级 /*/ str:文件名路径*/
|
||||
virtual int set_clean_paper_road() override; //清理纸道
|
||||
virtual int get_dev_islock_file(int& data) override; //获取设备文件 /*/ data:0 未上锁,1 上锁。-1 未发现黑名单列表 -2列表没有信息*/
|
||||
virtual int set_dev_islock_file(int data) override; //设置设备文件 /*/ data:0 未上锁,1 上锁*
|
||||
virtual int set_speed_mode(int data) override; //设置速度模式 /*/ data:40,50,60,70
|
||||
virtual int get_speed_mode(int& data)override; //获取速度模式 /*/ data:40,50,60,70
|
||||
virtual int set_devs_distortion_check_val(float data) override; //设置畸变矫正
|
||||
virtual int get_devs_distortion_check_val(float& data)override;//获取设备畸变值 float to int;
|
||||
virtual int set_auto_flat(int data)override; //设置自动平场校正
|
||||
// data:0(ALL) 1(200dpi、gray) 2(200dpi、color) 3(300dpi、gray) 4(300dpi、color) 5(600dpi、gray) 6(600dpi、color)
|
||||
virtual int set_updata0303(void)override;
|
||||
virtual int get_devs_cpu(int& cpu); //获取设备内存大小(kb)
|
||||
virtual int get_devs_disk(int& disk); //获取设备硬盘容量大小(kb)
|
||||
};
|
|
@ -98,7 +98,7 @@ static int strToWchar(string str, wchar_t* s)
|
|||
return -1;
|
||||
}
|
||||
size_t size = str.length();
|
||||
//鑾峰彇缂撳啿鍖哄ぇ灏忥紝骞剁敵璇风┖闂达紝缂撳啿鍖哄ぇ灏忔寜瀛楃璁$畻
|
||||
//閼惧嘲褰囩紓鎾冲暱閸栧搫銇囩亸蹇ョ礉楠炲墎鏁电拠椋庘敄闂傝揪绱濈紓鎾冲暱閸栧搫銇囩亸蹇斿瘻鐎涙顑佺拋锛勭暬
|
||||
int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), size, NULL, 0);
|
||||
wchar_t* buffer = new wchar_t[size + 1];
|
||||
MultiByteToWideChar(CP_ACP, 0, str.c_str(), size, buffer, len);
|
||||
|
@ -217,7 +217,7 @@ namespace hg_imgproc
|
|||
// construction
|
||||
public:
|
||||
imgproc(int pid, bool isx86_Advan) : pid_(pid),papersize_(pid_)
|
||||
, img_statu_(SANE_Image_Statu_OK)
|
||||
, img_statu_(IMG_STATUS_OK)
|
||||
, my_path_(hg_log::pe_path())
|
||||
,ocrinit_(NULL),ocrgetdirectimage_(NULL)
|
||||
,ocrexit_(NULL),HGBase_CreatImg(NULL)
|
||||
|
@ -334,7 +334,7 @@ namespace hg_imgproc
|
|||
{
|
||||
return SCANNER_ERR_OUT_OF_RANGE;
|
||||
}
|
||||
printf("HGBaselib_path锛?s HGImagePrclib_path:%s\r\n",HGBaselib_path.c_str(),HGImagePrclib_path.c_str());
|
||||
printf("HGBaselib_path閿?s HGImagePrclib_path:%s\r\n",HGBaselib_path.c_str(),HGImagePrclib_path.c_str());
|
||||
|
||||
Dynamicopen_HGImageprc_pHandle_ = dlopen(HGImagePrclib_path.c_str(), RTLD_LAZY);
|
||||
Dynamicopen_HGBase_pHandle_ = dlopen(HGBaselib_path.c_str(), RTLD_LAZY);
|
||||
|
@ -353,8 +353,8 @@ namespace hg_imgproc
|
|||
HGBase_FreeImg = (SDKHGBase_FreeImage_)dlsym(Dynamicopen_HGBase_pHandle_,"HGBase_DestroyImage");
|
||||
|
||||
#else
|
||||
string scanner_path = hg_log::get_module_full_path("scanner.dll");
|
||||
scanner_path = scanner_path.substr(0, scanner_path.size() - strlen("scanner.dll"));
|
||||
string scanner_path = hg_log::get_module_full_path(MODULE_NAME_SCANNER);
|
||||
scanner_path = scanner_path.substr(0, scanner_path.size() - strlen(MODULE_NAME_SCANNER));
|
||||
|
||||
string HGImagePrclib_path = scanner_path + IMGPRC_LIBNANE;
|
||||
string HGBaselib_path = scanner_path + HGBASE_LIBNAME;
|
||||
|
@ -369,8 +369,8 @@ namespace hg_imgproc
|
|||
if (ret == -1)
|
||||
return SCANNER_ERR_INSUFFICIENT_MEMORY;
|
||||
|
||||
load_dll(Baselibbuffer, &Dynamicopen_HGBase_pHandle_); //鍏堝姞杞藉悗閲婃斁
|
||||
load_dll(Prclibbuffer, &Dynamicopen_HGImageprc_pHandle_); //windows涓嬪彲鑳戒細鎵句笉鍒颁粬鎵€鍦ㄧ殑渚濊禆搴撳鑷寸洿鎺ユ墦寮€鍔ㄦ€佸簱鐨勬椂鍊欐壘涓嶅埌妯″潡
|
||||
load_dll(Baselibbuffer, &Dynamicopen_HGBase_pHandle_); //閸忓牆濮炴潪钘夋倵闁插﹥鏂?
|
||||
load_dll(Prclibbuffer, &Dynamicopen_HGImageprc_pHandle_); //windows娑撳褰查懗鎴掔窗閹靛彞绗夐崚棰佺铂閹碘偓閸︺劎娈戞笟婵婄鎼存挸顕遍懛瀵告纯閹恒儲澧﹀鈧崝銊︹偓浣哥氨閻ㄥ嫭妞傞崐娆愬娑撳秴鍩屽Ο鈥虫健
|
||||
|
||||
SAFE_DELETE(Prclibbuffer);
|
||||
SAFE_DELETE(Baselibbuffer);
|
||||
|
@ -418,7 +418,7 @@ namespace hg_imgproc
|
|||
#if (!defined WIN32)
|
||||
ret = dlclose(Dynamicopen_HGBase_pHandle_);
|
||||
#else
|
||||
ret = FreeLibrary(Dynamicopen_HGBase_pHandle_); //璨屼技鍔犺浇椤哄簭涓嶅锛屼細瀵艰嚧杩欎釜鍦版柟鐨勬閿侊紵锛燂紵
|
||||
ret = FreeLibrary(Dynamicopen_HGBase_pHandle_); //鐠ㄥ奔鎶€閸旂姾娴囨い鍝勭碍娑撳秴顕敍灞肩窗鐎佃壈鍤ф潻娆庨嚋閸︾増鏌熼惃鍕劥闁夸緤绱甸敍鐕傜吹
|
||||
#endif
|
||||
Dynamicopen_HGBase_pHandle_ = NULL;
|
||||
}
|
||||
|
@ -431,13 +431,25 @@ namespace hg_imgproc
|
|||
int ret = SCANNER_ERR_OK;
|
||||
|
||||
float scale = img_conf_.fillhole.fillholeratio / 100.0;
|
||||
float val = img_conf_.resolution_dst / 10;
|
||||
int dpi = img_conf_.resolution_dst;
|
||||
|
||||
if (!param_.is_sup_real_300dpi_ && !param_.is_sup_real_600dpi_)
|
||||
{
|
||||
dpi = 200;
|
||||
}
|
||||
else if (param_.is_sup_real_300dpi_ && !param_.is_sup_real_600dpi_)
|
||||
{
|
||||
if (dpi >= 300)
|
||||
dpi = 300;
|
||||
}
|
||||
|
||||
float val = dpi / 10;
|
||||
cv::Vec4f edgeScale;
|
||||
edgeScale[0] = top;
|
||||
edgeScale[1] = low;
|
||||
edgeScale[2] = l;
|
||||
edgeScale[3] = r;
|
||||
CImageApplyOutHole outh(val, edgeScale, 50);
|
||||
CImageApplyOutHole outh(val, edgeScale, 20);
|
||||
outh.apply(v, true);
|
||||
if (v.empty())
|
||||
{
|
||||
|
@ -521,40 +533,55 @@ namespace hg_imgproc
|
|||
else
|
||||
mat = m_dst.clone();
|
||||
|
||||
cv::imwrite("C:\\image\\imdecode" + std::to_string(img_idx++) + ".jpg", mat);
|
||||
float vratio = 0.0;
|
||||
float hratio = 0.0;
|
||||
//cv::imwrite("C:\\image\\imdecode" + std::to_string(img_idx++) + ".jpg", mat);
|
||||
int dpi = param_.dpi == 600 ? 3 : (param_.dpi < 599 && param_.dpi >= 300) ? 2 : 1;
|
||||
int mode = param_.color_mode == COLOR_MODE_24_BITS ? 1 : 0;
|
||||
for (auto it : correction_image_map_)
|
||||
{
|
||||
if (img_conf_.removeMorr && param_.dpi != 600) //除摩尔纹 使用300dpi校正数据
|
||||
{
|
||||
if (it.second.info.params.dpi == 2 && it.second.info.params.colormode == mode)
|
||||
{
|
||||
if (it.second.info.params.status != 100)
|
||||
break;
|
||||
vratio = it.second.vratio;
|
||||
hratio = it.second.hratio;
|
||||
correctColor(mat, it.second.flat_lut);
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (it.second.info.params.colormode == mode && it.second.info.params.dpi == dpi)
|
||||
{
|
||||
if (it.second.info.params.status != 100)
|
||||
{
|
||||
break;
|
||||
}
|
||||
vratio = it.second.vratio;
|
||||
hratio = it.second.hratio;
|
||||
correctColor(mat, it.second.flat_lut);//校正
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
//for (size_t i = 0; i < correction_image_map_.size(); i++)
|
||||
//{
|
||||
// if (correction_image_map_[i].info.params.colormode == mode && correction_image_map_[i].info.params.dpi == dpi)
|
||||
// {
|
||||
// if (correction_image_map_[i].info.params.status != 100)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
// correctColor(mat, correction_image_map_[i].flat_lut);//校正
|
||||
// }
|
||||
//}
|
||||
//cv::imwrite("C:\\image\\imdecode" + std::to_string(img_idx++) + ".jpg", mat);
|
||||
|
||||
//if (param_.dpi < 299)/////7010不支持 200dpi 所以需要手动拉伸宽度
|
||||
//{
|
||||
// float xy = param_.dpi / 300.0;
|
||||
// cv::resize(mat, mat, cv::Size(), xy, 1);
|
||||
if (!(vratio >= 0.8f && vratio <= 1.20f && hratio > 0.8f && hratio < 1.2f))
|
||||
vratio = hratio = 1.0f;
|
||||
|
||||
//}
|
||||
if (dpi == 1 && img_conf_.removeMorr)
|
||||
hratio = (200.0 / 300.0) * hratio;
|
||||
|
||||
if (img_conf_.removeMorr && dpi != 3)
|
||||
vratio = dpi == 1 ? vratio * 0.5 : vratio * 0.75; //0.5 = 200/400 0.75= 300/400
|
||||
|
||||
if (img_conf_.removeMorr)
|
||||
resize(mat, mat, cv::Size(0, 0), hratio, vratio, cv::InterpolationFlags::INTER_AREA);
|
||||
else
|
||||
resize(mat, mat, cv::Size(0, 0), hratio, vratio);
|
||||
}
|
||||
|
||||
//cv::imwrite("C:\\image\\imdecode4.png", mat);
|
||||
|
@ -712,7 +739,7 @@ namespace hg_imgproc
|
|||
|
||||
mats_.clear();
|
||||
|
||||
CImageApplyFadeBackGroudColor fade(40, 0, img_conf_.fadebackrange);
|
||||
CImageApplyFadeBackGroudColor fade(20, 255, img_conf_.fadebackrange);
|
||||
for(size_t i = 0; i < mats.size();i++)
|
||||
{
|
||||
fade.apply(mats[i],img_conf_.is_duplex);
|
||||
|
@ -731,13 +758,13 @@ namespace hg_imgproc
|
|||
}
|
||||
return SCANNER_ERR_OK;
|
||||
}
|
||||
int multi_out(int out_type)
|
||||
int multi_out(int out_type, int bw_threshold)
|
||||
{
|
||||
std::vector<cv::Mat> mats(mats_);
|
||||
std::vector<cv::Mat> mat;
|
||||
mats_.clear();
|
||||
|
||||
IMageMulti output(out_type);
|
||||
IMageMulti output(out_type, bw_threshold);
|
||||
|
||||
for(size_t i = 0;i < mats.size();i++)
|
||||
{
|
||||
|
@ -815,7 +842,7 @@ namespace hg_imgproc
|
|||
|
||||
SIZE temp_Size = papersize_.GetPaperSize(img_conf_.papertype, dpi,img_conf_.paperAlign);
|
||||
cv::Size cvSize(temp_Size.cx, temp_Size.cy);
|
||||
CImageApplyAutoCrop crop(img_conf_.is_autocrop,img_conf_.autodescrew,img_conf_.fillbackground,cvSize,img_conf_.is_convex,img_conf_.isfillcolor);
|
||||
CImageApplyAutoCrop crop(img_conf_.is_autocrop,img_conf_.autodescrew,img_conf_.fillbackground,cvSize,img_conf_.is_convex,img_conf_.isfillcolor, 30,img_conf_.noise,img_conf_.indent);
|
||||
|
||||
crop.apply(mats,img_conf_.is_duplex);
|
||||
mats_ = mats;
|
||||
|
@ -827,6 +854,26 @@ namespace hg_imgproc
|
|||
}
|
||||
return SCANNER_ERR_OK;
|
||||
}
|
||||
int dispersion()
|
||||
{
|
||||
int ret = SCANNER_ERR_OK;
|
||||
std::vector<cv::Mat> mats(mats_);
|
||||
mats_.clear();
|
||||
|
||||
CImageApplyDispersion disp;
|
||||
|
||||
for (int i = 0; i < mats.size(); ++i)
|
||||
{
|
||||
disp.apply(mats[i], 0);
|
||||
mats_.push_back(mats[i]);
|
||||
}
|
||||
|
||||
if (mats_.empty())
|
||||
{
|
||||
return SCANNER_ERR_NO_DATA;
|
||||
}
|
||||
return SCANNER_ERR_OK;
|
||||
}
|
||||
int fillhole(float top,float low,float l,float r)
|
||||
{
|
||||
int ret = SCANNER_ERR_OK;
|
||||
|
@ -840,7 +887,7 @@ namespace hg_imgproc
|
|||
edgeScale[1] = low;
|
||||
edgeScale[2] = l;
|
||||
edgeScale[3] = r;
|
||||
CImageApplyOutHole outh(val, edgeScale,50);
|
||||
CImageApplyOutHole outh(val, edgeScale, 20);
|
||||
|
||||
outh.apply(mats,img_conf_.is_duplex);
|
||||
mats_ = mats;
|
||||
|
@ -962,7 +1009,7 @@ namespace hg_imgproc
|
|||
std::vector<cv::Mat> mats(mats_);
|
||||
mats_.clear();
|
||||
|
||||
CImageApplyRefuseInflow Inflow(permeate_lv);
|
||||
CImageApplyRefuseInflow Inflow(20, permeate_lv);
|
||||
for (size_t i = 0; i < mats.size(); ++i)
|
||||
{
|
||||
Inflow.apply(mats[i],img_conf_.is_duplex);
|
||||
|
@ -1109,7 +1156,7 @@ namespace hg_imgproc
|
|||
return SCANNER_ERR_OK;
|
||||
|
||||
}
|
||||
int errorextention()
|
||||
int errorextention(int bw_threshold)
|
||||
{
|
||||
int ret = SCANNER_ERR_OK;
|
||||
std::vector<cv::Mat> mats(mats_);
|
||||
|
@ -1121,7 +1168,7 @@ namespace hg_imgproc
|
|||
else
|
||||
thrtype = CImageApplyBWBinaray::ThresholdType::THRESH_BINARY;
|
||||
|
||||
CImageApplyBWBinaray BWBinaray(thrtype);
|
||||
CImageApplyBWBinaray BWBinaray(thrtype, bw_threshold);
|
||||
for (size_t i = 0; i < mats.size(); ++i)
|
||||
{
|
||||
BWBinaray.apply(mats[i],img_conf_.is_duplex);
|
||||
|
@ -1140,7 +1187,7 @@ namespace hg_imgproc
|
|||
mats_.clear();
|
||||
|
||||
double threshold = 40;
|
||||
int edge = 30;
|
||||
int edge = 100;
|
||||
int dis = img_conf_.discardblank_percent;
|
||||
if (img_conf_.is_autodiscradblank_vince)
|
||||
dis *= 1.5;
|
||||
|
@ -1183,7 +1230,7 @@ namespace hg_imgproc
|
|||
std::vector<cv::Mat> mats(mats_);
|
||||
mats_.clear();
|
||||
|
||||
CImageApplyConcatenation fold((CImageApplyConcatenation::ConcatMode)img_conf_.fold_concatmode);
|
||||
CImageApplyConcatenation fold((CImageApplyConcatenation::ConcatMode)img_conf_.fold_concatmode, cv::Scalar(255, 255, 255));
|
||||
fold.apply(mats,img_conf_.is_duplex);
|
||||
mats_= mats;
|
||||
|
||||
|
@ -1396,11 +1443,35 @@ namespace hg_imgproc
|
|||
int ret = SCANNER_ERR_OK;
|
||||
std::vector<cv::Mat> mats(mats_);
|
||||
mats_.clear();
|
||||
CImageApplyColorCastCorrect ColorCastCorrect(1);
|
||||
|
||||
int tmp = -1;
|
||||
CImageApplyColorCastCorrect::PreScheme deviceType = (CImageApplyColorCastCorrect::PreScheme)tmp;
|
||||
if (param_.device_7010)
|
||||
deviceType = CImageApplyColorCastCorrect::G300_7010;
|
||||
if (0x300 == pid_)
|
||||
{
|
||||
deviceType = CImageApplyColorCastCorrect::G300_D8;
|
||||
}
|
||||
else if (0x400 == pid_)
|
||||
{
|
||||
deviceType = CImageApplyColorCastCorrect::G400_3288;
|
||||
}
|
||||
else if (0x402 == pid_)
|
||||
{
|
||||
deviceType = CImageApplyColorCastCorrect::G400_402;
|
||||
}
|
||||
else if (0x302 == pid_)
|
||||
{
|
||||
deviceType = CImageApplyColorCastCorrect::Android302;
|
||||
}
|
||||
|
||||
|
||||
CImageApplyColorCastCorrect ColorCastCorrect(deviceType);
|
||||
ColorCastCorrect.apply(mats, true);
|
||||
|
||||
//cv::imwrite(to_string(i) + "cis_test_image.jpg", mats[i]);
|
||||
|
||||
ColorCastCorrect.apply(mats,true);
|
||||
|
||||
mats_ = mats;
|
||||
|
||||
if (mats_.empty())
|
||||
|
@ -1410,7 +1481,14 @@ namespace hg_imgproc
|
|||
return ret;
|
||||
//cv::imwrite("CISTestImageProcess.jpg",mats[i]);
|
||||
}
|
||||
|
||||
int lost_frame_test()
|
||||
{
|
||||
if (mats_.empty())
|
||||
{
|
||||
return SCANNER_ERR_NO_DATA;
|
||||
}
|
||||
return LineContinuityDetection::isContinuous(mats_[0], 100); //妫€娴嬩竴闈㈠氨琛?
|
||||
}
|
||||
int correction_image(cv::Mat &flat_lut, cv::Mat black_mat, cv::Mat white_mat)
|
||||
{
|
||||
flat_lut = creatLUTData(black_mat, white_mat);//计算LUT 查值表
|
||||
|
@ -1425,7 +1503,7 @@ namespace hg_imgproc
|
|||
info.width = mats.cols;
|
||||
info.origin = HGBASE_IMGORIGIN_TOP;
|
||||
int bits = mats.channels() == 1 ? 8 : 24;
|
||||
info.widthStep = mats.step; //opencv鍘熷鍊?
|
||||
info.widthStep = mats.step; //opencv閸樼喎顫愰崐?
|
||||
info.type = mats.channels() == 1 ? HGBASE_IMGTYPE_GRAY : HGBASE_IMGTYPE_BGR;
|
||||
|
||||
int ret = HGBase_CreatImg(const_cast<uchar*>(mats.data), &info, &image);
|
||||
|
@ -1437,13 +1515,13 @@ namespace hg_imgproc
|
|||
|
||||
|
||||
/// <summary>
|
||||
/// 8浣嶅浘杞?浣嶅浘
|
||||
/// 8娴e秴娴樻潪?娴e秴娴?
|
||||
/// </summary>
|
||||
/// <param name="image">8bit鍥?/param>
|
||||
/// <param name="threshold">闃堝€硷紝寤鸿榛樿127</param>
|
||||
/// <param name="reverse">true涓哄弽鑹诧紝鍗抽粦0鐧?锛涘弽涔嬩害鐒?/param>
|
||||
/// <param name="align">true涓哄洓瀛楄妭瀵归綈</param>
|
||||
/// <returns>1浣嶅浘</returns>
|
||||
/// <param name="image">8bit閸?/param>
|
||||
/// <param name="threshold">闂冨牆鈧》绱濆楦款唴姒涙顓?27</param>
|
||||
/// <param name="reverse">true娑撳搫寮介懝璇х礉閸楁娊绮?閻?閿涙稑寮芥稊瀣╁閻?/param>
|
||||
/// <param name="align">true娑撳搫娲撶€涙濡€靛綊缍?/param>
|
||||
/// <returns>1娴e秴娴?/returns>
|
||||
///
|
||||
static cv::Mat convert_8bit_2_1bit(const cv::Mat& image, uchar threshold, bool reverse, bool align)
|
||||
{
|
||||
|
@ -1737,7 +1815,7 @@ namespace hg_imgproc
|
|||
|
||||
|
||||
#define GAMMA_EX 1.7f
|
||||
#define BLACK_OFFSET 0
|
||||
#define BLACK_OFFSET 8
|
||||
|
||||
void fittingLUT(const std::vector<unsigned char>& points, unsigned char min_value, unsigned char max_value, unsigned char* data)
|
||||
{
|
||||
|
@ -1753,7 +1831,7 @@ namespace hg_imgproc
|
|||
float temp;
|
||||
for (int j = 0, length = (255 - b + 1); j < length; j++)
|
||||
{
|
||||
temp = tb + step * j;// gamma(tb + step * j, GAMMA_EX) - BLACK_OFFSET;
|
||||
temp = gamma(tb + step * j, GAMMA_EX) - BLACK_OFFSET;//tb + step * j;//
|
||||
data[j + b] = (cv::min)(255, (cv::max)(0, static_cast<int>(temp)));
|
||||
}
|
||||
}
|
||||
|
@ -1813,7 +1891,7 @@ namespace hg_imgproc
|
|||
memcpy(lutROI.data, tran.data, tran.total());
|
||||
}
|
||||
|
||||
cv::imwrite("C:\\image\\" + std::to_string(lut_idx++) + ".bmp", lut);
|
||||
//cv::imwrite("C:\\image\\" + std::to_string(lut_idx++) + ".bmp", lut);
|
||||
return lut;
|
||||
}
|
||||
|
||||
|
@ -1915,9 +1993,9 @@ namespace hg_imgproc
|
|||
{
|
||||
return ((imgproc*)himg)->fadeback();
|
||||
}
|
||||
int multi_out(HIMGPRC himg,int out_type)
|
||||
int multi_out(HIMGPRC himg, int out_type, int bw_threshold)
|
||||
{
|
||||
return ((imgproc*)himg)->multi_out(out_type);
|
||||
return ((imgproc*)himg)->multi_out(out_type, bw_threshold);
|
||||
}
|
||||
int multi_out_red(HIMGPRC himg)
|
||||
{
|
||||
|
@ -1931,6 +2009,10 @@ namespace hg_imgproc
|
|||
{
|
||||
return ((imgproc*)himg)->auto_crop(dpi);
|
||||
}
|
||||
int dispersion(HIMGPRC himg)
|
||||
{
|
||||
return ((imgproc*)himg)->dispersion();
|
||||
}
|
||||
int fillhole(HIMGPRC himg, float top, float low, float l, float r)
|
||||
{
|
||||
return ((imgproc*)himg)->fillhole(top, low, l,r);
|
||||
|
@ -1979,9 +2061,9 @@ namespace hg_imgproc
|
|||
{
|
||||
return ((imgproc*)himg)->nosieDetach();
|
||||
}
|
||||
int errorextention(HIMGPRC himg)
|
||||
int errorextention(HIMGPRC himg, int bw_threshold)
|
||||
{
|
||||
return ((imgproc*)himg)->errorextention();
|
||||
return ((imgproc*)himg)->errorextention(bw_threshold);
|
||||
}
|
||||
int discardBlank(HIMGPRC himg)
|
||||
{
|
||||
|
@ -2024,6 +2106,11 @@ namespace hg_imgproc
|
|||
{
|
||||
return ((imgproc*)himg)->color_cast_correction();
|
||||
}
|
||||
int lost_frame_test(HIMGPRC himg)
|
||||
{
|
||||
return ((imgproc*)himg)->lost_frame_test();
|
||||
return 0;
|
||||
}
|
||||
int final(HIMGPRC himg)
|
||||
{
|
||||
return ((imgproc*)himg)->final();
|
||||
|
|
|
@ -153,6 +153,8 @@ namespace hg_imgproc
|
|||
int width; // in pixel
|
||||
int height; // in pixel
|
||||
unsigned total_bytes;// total bytes
|
||||
bool is_sup_real_300dpi_;
|
||||
bool is_sup_real_600dpi_;
|
||||
bool device_7010;
|
||||
}IMGPRCPARAM, *LPIMGPRCPARAM;
|
||||
typedef struct _img_header
|
||||
|
@ -180,10 +182,11 @@ namespace hg_imgproc
|
|||
//拆分
|
||||
int split(HIMGPRC himg,int split3399);
|
||||
int fadeback(HIMGPRC himg);
|
||||
int multi_out(HIMGPRC himg,int out_type);
|
||||
int multi_out(HIMGPRC himg,int out_type, int bw_threshold);
|
||||
int multi_out_red(HIMGPRC himg);
|
||||
int auto_matic_color(HIMGPRC himg,int color_type);
|
||||
int auto_crop(HIMGPRC himg, float dpi);
|
||||
int dispersion(HIMGPRC himg);
|
||||
int fillhole(HIMGPRC himg, float top, float low, float r, float l);
|
||||
int resolution_change(HIMGPRC himg,float dpi3288);
|
||||
int croprect(HIMGPRC himg);
|
||||
|
@ -196,7 +199,7 @@ namespace hg_imgproc
|
|||
int remove_morr(HIMGPRC himg);
|
||||
int sharpenType(HIMGPRC himg);
|
||||
int nosieDetach(HIMGPRC himg);
|
||||
int errorextention(HIMGPRC himg);
|
||||
int errorextention(HIMGPRC himg, int bw_threshold);
|
||||
int discardBlank(HIMGPRC himg);
|
||||
int answerSheetFilterRed(HIMGPRC himg);
|
||||
int imgtypechange(HIMGPRC himg,std::string img_type_,void *buf,std::vector<unsigned char> &bmpdata);
|
||||
|
@ -207,6 +210,7 @@ namespace hg_imgproc
|
|||
int size_detection(HIMGPRC himg);
|
||||
int cis_test_image(HIMGPRC himg, CISTestImageProcess::CISTestResult& res);
|
||||
int color_cast_correction(HIMGPRC himg);
|
||||
int lost_frame_test(HIMGPRC himg);
|
||||
int final(HIMGPRC himg);
|
||||
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "hg_scanner_239.h"
|
||||
#include "hg_scanner_300.h"
|
||||
#include "hg_scanner_302.h"
|
||||
#include "hg_scanner_306.h"
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
@ -46,6 +47,7 @@ g_supporting_devices[] = {
|
|||
, {0x31c9, PID_AND_NAME(8529, SCANNER_NAME_LSC_G52S), "G52S", "", &hg_scanner_mgr::create_scanner_g439}
|
||||
, {0x31c9, PID_AND_NAME(8620, SCANNER_NAME_LSC_G62S), "G62S", "", &hg_scanner_mgr::create_scanner_g100}
|
||||
, {0x31c9, PID_AND_NAME(8629, SCANNER_NAME_LSC_G62S), "G62S", "", &hg_scanner_mgr::create_scanner_g239}
|
||||
, {0x31c9, PID_AND_NAME(8630, SCANNER_NAME_LSC_G63S), "G63S", "", &hg_scanner_mgr::create_scanner_g239}
|
||||
, {0x31c9, PID_AND_NAME(8730, SCANNER_NAME_LSC_G73S), "G73S", "", &hg_scanner_mgr::create_scanner_g100}
|
||||
, {0x31c9, PID_AND_NAME(8739, SCANNER_NAME_LSC_G73S), "G73S", "", &hg_scanner_mgr::create_scanner_g239}
|
||||
#endif
|
||||
|
@ -72,22 +74,35 @@ g_supporting_devices[] = {
|
|||
|
||||
|
||||
#elif defined(OEM_ZHONGJING)
|
||||
{0X05DA, 0x9220, SCANNER_NAME_ZJ_6500, "S6570", "",& hg_scanner_mgr::create_scanner_g439}
|
||||
{0X05DA, 0x9220, SCANNER_NAME_ZJ_6570, "S6570", "",& hg_scanner_mgr::create_scanner_g439}
|
||||
, {0X05DA, 0x9222, SCANNER_NAME_ZJ_8790, "S8790", "",& hg_scanner_mgr::create_scanner_g239}
|
||||
, {0X05DA, 0x9223, SCANNER_NAME_ZJ_500DC, "S500DC", "",& hg_scanner_mgr::create_scanner_g239}
|
||||
#elif defined(OEM_ZIGUANG)
|
||||
{0x32ec, 0x0200, SANNNER_NAME_ZG_Q7110,"Q7110", "", & hg_scanner_mgr::create_scanner_g239}
|
||||
, {0x32ec, 0x0210, SANNNER_NAME_ZG_Q1070, "Q1070", "", &hg_scanner_mgr::create_scanner_g402}
|
||||
#elif defined(OEM_NEUTRAL)
|
||||
{0x3072, PID_AND_NAME(100, SCANNER_NAME_HGNEU_G100), "G100", "",& hg_scanner_mgr::create_scanner_g100}
|
||||
, {0x3072, PID_AND_NAME(139, SCANNER_NAME_HGNEU_G100), "G100", "", &hg_scanner_mgr::create_scanner_g239}
|
||||
, {0x3072, PID_AND_NAME(200, SCANNER_NAME_HGNEU_G200), "G200", "", &hg_scanner_mgr::create_scanner_g100}
|
||||
, {0x3072, PID_AND_NAME(239, SCANNER_NAME_HGNEU_G200), "G200", "", &hg_scanner_mgr::create_scanner_g239}
|
||||
, {0x3072, PID_AND_NAME(300, SCANNER_NAME_HGNEU_G300), "G300", "", &hg_scanner_mgr::create_scanner_g300}
|
||||
, {0x3072, PID_AND_NAME(302, SCANNER_NAME_HGNEU_G300), "G300", "", &hg_scanner_mgr::create_scanner_g302}
|
||||
, {0x3072, PID_AND_NAME(339, SCANNER_NAME_HGNEU_G300), "G300", "", &hg_scanner_mgr::create_scanner_empty}
|
||||
, {0x3072, PID_AND_NAME(400, SCANNER_NAME_HGNEU_G400), "G400", "", &hg_scanner_mgr::create_scanner_g400}
|
||||
, {0x3072, PID_AND_NAME(402, SCANNER_NAME_HGNEU_G400), "G400", "", &hg_scanner_mgr::create_scanner_g402}
|
||||
, {0x3072, PID_AND_NAME(439, SCANNER_NAME_HGNEU_G400), "G400", "", &hg_scanner_mgr::create_scanner_g439}
|
||||
, {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HGNEU_G200), "G200", "", &hg_scanner_mgr::create_scanner_g100}
|
||||
|
||||
|
||||
{0x3072, PID_AND_NAME(100, SCANNER_NAME_HG_G100), "G100", "",& hg_scanner_mgr::create_scanner_g100}
|
||||
, {0x3072, PID_AND_NAME(139, SCANNER_NAME_HG_G100), "G100", "", &hg_scanner_mgr::create_scanner_g239}
|
||||
, {0x3072, PID_AND_NAME(200, SCANNER_NAME_HG_G200), "G200", "", &hg_scanner_mgr::create_scanner_g100}
|
||||
, {0x3072, PID_AND_NAME(239, SCANNER_NAME_HG_G200), "G200", "", &hg_scanner_mgr::create_scanner_g239}
|
||||
, {0x3072, PID_AND_NAME(300, SCANNER_NAME_HG_G300), "G300", "", &hg_scanner_mgr::create_scanner_g300}
|
||||
, {0x3072, PID_AND_NAME(302, SCANNER_NAME_HG_G300), "G300", "", &hg_scanner_mgr::create_scanner_g302}
|
||||
, {0x3072, PID_AND_NAME(339, SCANNER_NAME_HG_G300), "G300", "", &hg_scanner_mgr::create_scanner_empty}
|
||||
, {0x3072, PID_AND_NAME(400, SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g400}
|
||||
, {0x3072, PID_AND_NAME(402, SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g402}
|
||||
, {0x3072, PID_AND_NAME(439, SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g439}
|
||||
, {0x3072, PID_AND_NAME(306, SCANNER_NAME_HG_G300), "G300", "", &hg_scanner_mgr::create_scanner_g306}
|
||||
|
||||
, {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HG_G300), "G300", "", &hg_scanner_mgr::create_scanner_g300}
|
||||
, {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HG_G200), "G200", "", &hg_scanner_mgr::create_scanner_g100}
|
||||
, {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HG_G300), "G400", "", &hg_scanner_mgr::create_scanner_g400}
|
||||
|
||||
|
||||
|
||||
, {0x31c9, PID_AND_NAME(8426, SCANNER_NAME_LSC_G42S), "G4245F", "",& hg_scanner_mgr::create_scanner_g300}
|
||||
, {0x31c9, PID_AND_NAME(8626, SCANNER_NAME_LSC_G62S), "G6290U", "", &hg_scanner_mgr::create_scanner_g239}
|
||||
, {0x31c9, PID_AND_NAME(8200, SCANNER_NAME_LSC_G42S), "G42S", "",& hg_scanner_mgr::create_scanner_g300}
|
||||
, {0x31c9, PID_AND_NAME(8420, SCANNER_NAME_LSC_G42S), "G42S", "", &hg_scanner_mgr::create_scanner_g300}
|
||||
, {0x31c9, PID_AND_NAME(8429, SCANNER_NAME_LSC_G42S), "G42S", "", &hg_scanner_mgr::create_scanner_empty}
|
||||
|
@ -95,16 +110,44 @@ g_supporting_devices[] = {
|
|||
, {0x31c9, PID_AND_NAME(8529, SCANNER_NAME_LSC_G52S), "G52S", "", &hg_scanner_mgr::create_scanner_g439}
|
||||
, {0x31c9, PID_AND_NAME(8620, SCANNER_NAME_LSC_G62S), "G62S", "", &hg_scanner_mgr::create_scanner_g100}
|
||||
, {0x31c9, PID_AND_NAME(8629, SCANNER_NAME_LSC_G62S), "G62S", "", &hg_scanner_mgr::create_scanner_g239}
|
||||
, {0x31c9, PID_AND_NAME(8630, SCANNER_NAME_LSC_G63S), "G63S", "", &hg_scanner_mgr::create_scanner_g239}
|
||||
, {0x31c9, PID_AND_NAME(8730, SCANNER_NAME_LSC_G73S), "G73S", "", &hg_scanner_mgr::create_scanner_g100}
|
||||
, {0x31c9, PID_AND_NAME(8739, SCANNER_NAME_LSC_G73S), "G73S", "", &hg_scanner_mgr::create_scanner_g239}
|
||||
, {0x32ec, 0x0200, SANNNER_NAME_ZG_Q7110,"", "",& hg_scanner_mgr::create_scanner_g239}
|
||||
, {0x32ec, 0x0210, SANNNER_NAME_ZG_Q1070, "", "", &hg_scanner_mgr::create_scanner_g402}
|
||||
, {0X05DA, 0x9220, SCANNER_NAME_ZJ_6500, "S6500", "",&hg_scanner_mgr::create_scanner_g439}
|
||||
, {0x3308, 0x6006, SCANNER_NAME_CT_9020, SCANNER_NAME_CT_9020, "",& hg_scanner_mgr::create_scanner_g239}
|
||||
|
||||
|
||||
, {0x2903, 0x1000, SCANNER_NAME_HW_1000, SCANNER_NAME_HW_1000, "",& hg_scanner_mgr::create_scanner_g300} // "HW-1060A"
|
||||
, {0x2903, 0x1002, SCANNER_NAME_HW_1002, SCANNER_NAME_HW_1002, "", &hg_scanner_mgr::create_scanner_g302} // "HW-1060A"
|
||||
, {0x2903, 0x7000, SCANNER_NAME_HW_7000, SCANNER_NAME_HW_7000, "", &hg_scanner_mgr::create_scanner_g400} // "HW-74x0WA"
|
||||
, {0x2903, 0x7002, SCANNER_NAME_HW_7002, SCANNER_NAME_HW_7002, "", &hg_scanner_mgr::create_scanner_g402} // "HW-7002"
|
||||
, {0x2903, 0x7039, SCANNER_NAME_HW_7039, SCANNER_NAME_HW_7039, "", &hg_scanner_mgr::create_scanner_g439} // "HW-7039F"
|
||||
, {0x2903, 0x8000, SCANNER_NAME_HW_8000, SCANNER_NAME_HW_8000, "", &hg_scanner_mgr::create_scanner_g239} // "HW-8090F"
|
||||
, {0x2903, 0x9000, SCANNER_NAME_HW_9000, SCANNER_NAME_HW_9000, "", &hg_scanner_mgr::create_scanner_g239} // "HW-9110E"
|
||||
|
||||
, {0x3072, 0x0303, SCANNER_NAME_CT_4520, SCANNER_NAME_CT_4520, "",& hg_scanner_mgr::create_scanner_g300}
|
||||
, {0x3072, 0x0403, SCANNER_NAME_CT_138, SCANNER_NAME_CT_138, "", &hg_scanner_mgr::create_scanner_g439}
|
||||
, {0x3072, 0x0138, SCANNER_NAME_CT_138, SCANNER_NAME_CT_138, "", &hg_scanner_mgr::create_scanner_g239}
|
||||
, {0x3072, 0x0238, SCANNER_NAME_CT_138, SCANNER_NAME_CT_138, "", &hg_scanner_mgr::create_scanner_g239}
|
||||
|
||||
, {0x3308, 0x0138, SCANNER_NAME_CT_138, SCANNER_NAME_CT_138, "", &hg_scanner_mgr::create_scanner_g239}
|
||||
, {0x3308, 0x0238, SCANNER_NAME_CT_238, SCANNER_NAME_CT_238, "", &hg_scanner_mgr::create_scanner_g239}
|
||||
, {0x3308, 0x6006, SCANNER_NAME_CT_9020, SCANNER_NAME_CT_9020, "", &hg_scanner_mgr::create_scanner_g239}
|
||||
, {0x3308, 0x6005, SCANNER_NAME_CT_4520, SCANNER_NAME_CT_4520, "", &hg_scanner_mgr::create_scanner_g300}
|
||||
, {0x3308, 0x0238, SCANNER_NAME_CT_138, SCANNER_NAME_CT_138, "", &hg_scanner_mgr::create_scanner_g239}
|
||||
, {0x3308, 0x0138, SCANNER_NAME_CT_238, SCANNER_NAME_CT_238, "", &hg_scanner_mgr::create_scanner_g239}
|
||||
, {0x3072, 0x0303, SCANNER_NAME_CT_4520, SCANNER_NAME_CT_4520, "", &hg_scanner_mgr::create_scanner_g300}
|
||||
|
||||
, {0X05DA, 0x9220, SCANNER_NAME_ZJ_6570, "S6570", "",& hg_scanner_mgr::create_scanner_g439}
|
||||
, {0X05DA, 0x9222, SCANNER_NAME_ZJ_8790, "S8790", "",&hg_scanner_mgr::create_scanner_g239}
|
||||
, {0X05DA, 0x9223, SCANNER_NAME_ZJ_500DC, "S500DC", "",&hg_scanner_mgr::create_scanner_g239}
|
||||
|
||||
|
||||
, {0x32ec, 0x0200, SANNNER_NAME_ZG_Q7110,"Q7110", "",& hg_scanner_mgr::create_scanner_g239}
|
||||
, {0x32ec, 0x0210, SANNNER_NAME_ZG_Q1070, "Q1070", "", &hg_scanner_mgr::create_scanner_g402}
|
||||
|
||||
, { 0x300E, PID_AND_NAME(401C, SANNER_NAME_DL_S3000), "S3000", "", &hg_scanner_mgr::create_scanner_g239 }
|
||||
, { 0x300E, PID_AND_NAME(4020, SANNER_NAME_DL_S3400), "S3000", "", &hg_scanner_mgr::create_scanner_g239 }
|
||||
, { 0x300E, PID_AND_NAME(4015, SANNER_NAME_DL_S2000), "S2000", "", &hg_scanner_mgr::create_scanner_g300 }
|
||||
, { 0x300E, PID_AND_NAME(4019, SANNER_NAME_DL_DL9000), "DL9000", "", &hg_scanner_mgr::create_scanner_g439 }
|
||||
|
||||
|
||||
|
||||
#elif defined(OEM_DELI)
|
||||
{0x300E, PID_AND_NAME(401C, SANNER_NAME_DL_S3000), "S3000", "", &hg_scanner_mgr::create_scanner_g239}
|
||||
, {0x300E, PID_AND_NAME(4020, SANNER_NAME_DL_S3400), "S3000", "", &hg_scanner_mgr::create_scanner_g239}
|
||||
|
@ -121,9 +164,11 @@ g_supporting_devices[] = {
|
|||
, {0x3072, PID_AND_NAME(400, SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g400}
|
||||
, {0x3072, PID_AND_NAME(402, SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g402}
|
||||
, {0x3072, PID_AND_NAME(439, SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g439}
|
||||
, {0x3072, PID_AND_NAME(306, SCANNER_NAME_HG_G300), "G300", "", &hg_scanner_mgr::create_scanner_g306}
|
||||
|
||||
, {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HG_G300), "G300", "", &hg_scanner_mgr::create_scanner_g300}
|
||||
, {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HG_G200), "G200", "", &hg_scanner_mgr::create_scanner_g100}
|
||||
, {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HG_G100), "G100", "", &hg_scanner_mgr::create_scanner_g100}
|
||||
, {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g400}
|
||||
#endif
|
||||
};
|
||||
|
@ -348,6 +393,15 @@ hg_scanner* hg_scanner_mgr::create_scanner_g439(const char* name, usb_io* io, sc
|
|||
|
||||
return dynamic_cast<hg_scanner*>(s);
|
||||
}
|
||||
hg_scanner* hg_scanner_mgr::create_scanner_g306(const char* name, usb_io* io, scanner_handle* h)
|
||||
{
|
||||
hg_scanner_306* s = new hg_scanner_306(name, 0x300, io);
|
||||
|
||||
if (h)
|
||||
*h = s;
|
||||
|
||||
return dynamic_cast<hg_scanner*>(s);
|
||||
}
|
||||
void hg_scanner_mgr::usb_event_handle(usb_event ev, libusb_device* device, int vid, int pid, int usb_ver_h, int usb_ver_l, bool* retry, void* user) // usb_ver_h.usb_ver_l
|
||||
{
|
||||
hg_scanner_mgr* obj = (hg_scanner_mgr*)user;
|
||||
|
@ -407,14 +461,14 @@ void hg_scanner_mgr::on_hgscanner_pnp(usb_event ev, libusb_device* device, int v
|
|||
size_t i = 0;
|
||||
for (; i < online_devices_.size(); ++i)
|
||||
{
|
||||
if (online_devices_[i].dev == device) // 濮濄倕顦╅崑鍥х暰閸氬奔绔撮崣鎷岊啎婢跺洭鍣搁弬鎷岀箾閹恒儱鎮楅敍宀冾啎婢跺洤顕挒鈾€鈧竸evice閳ユ繀绻氶幐浣风瑝閸欐﹫绱辨俊鍌涚亯閸嬪洩顔曟稉宥嗗灇缁斿绱濇导姘嚤閼风顔曟径鍥櫢鏉╃偞绉烽幁顖欑瑝閼宠姤顒滅敮鍛婂复閺€璁圭礉缂佹垵鐣鹃崚鎷岊嚉鐠佹儳顦惃鍓哻anner鐎电钖勫妞剧瑝閸掍即鍣撮弨?
|
||||
if (online_devices_[i].dev == device) // 濮濄倕顦╅崑é<EFBFBD>¥Ñ…暰閸氬奔绔撮崣鎷岊啎婢跺æ´é<EFBFBD>£æ<EFBFBD><EFBFBD>弬鎷岀箾閹æ<EFBFBD>’儱鎮楅æ•<EFBFBD>宀冾啎婢跺洤顕挒鈾€鈧î„<EFBFBD>竸evice閳ユ繀绻氶å¹<EFBFBD>浣风ç‘<EFBFBD>é–¸æ¬<EFBFBD>﹫绱辨俊é<EFBFBD>Œæ¶šäº¯é–¸å¬ªæ´©é¡”曟稉宥嗗ç<EFBFBD>‡ç¼<EFBFBD>斿绱濇导姘嚤閼风î—<EFBFBD>顔曟径é<EFBFBD>¥î„€æ«¢é<EFBFBD>‰â•ƒå<EFBFBD>žç»‰çƒ½å¹<EFBFBD>顖欑ç‘<EFBFBD>é–¼å® å§¤é¡’æ»…æ•®é<EFBFBD>›å©‚å¤<EFBFBD>閺€ç’<EFBFBD>åœç¤‰ç¼‚佹垵é<EFBFBD>£é¹ƒå´šéŽ·å²Šåš‰é<EFBFBD> 佹儳顦惃é<EFBFBD>“å“»anneré<EFBFBD>Žç”µî”Šé’–勫妞剧ç‘<EFBFBD>é–¸æŽ<EFBFBD>å<EFBFBD>³é<EFBFBD>£æ’®å¼?
|
||||
{
|
||||
online_devices_[i].ind = index;
|
||||
add = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (add) // 婢跺嫮鎮婄€电钖勯垾娓別vice閳ユ繃鏁奸崣妯兼畱閹懏娅?
|
||||
if (add) // 婢跺嫮鎮婄€电钖勯垾娓別vice閳ユ繃é<EFBFBD><EFBFBD>奸崣妯兼畱閹æ‡<EFBFBD>å¨?
|
||||
{
|
||||
i = 0;
|
||||
for (auto& v : online_devices_)
|
||||
|
@ -732,6 +786,11 @@ scanner_err hg_scanner_mgr::hg_scanner_open(scanner_handle* h, const char* name,
|
|||
ret = (scanner_err)usb_manager::instance()->open(it->dev, &io, &hg_scanner_mgr::last_open_msg_);
|
||||
if (ret == SCANNER_ERR_OK)
|
||||
{
|
||||
if (io->get_ver() > 1)
|
||||
{
|
||||
// new version ...
|
||||
}
|
||||
|
||||
hg_scanner* scanner = g_supporting_devices[it->ind].create_scanner(it->display_name.c_str(), io, h);
|
||||
if (!scanner)
|
||||
{
|
||||
|
@ -751,6 +810,7 @@ scanner_err hg_scanner_mgr::hg_scanner_open(scanner_handle* h, const char* name,
|
|||
g_supporting_devices[it->ind].pid == 0x9000 ||
|
||||
g_supporting_devices[it->ind].pid == 0x8739 ||
|
||||
g_supporting_devices[it->ind].pid == 0x8629 ||
|
||||
g_supporting_devices[it->ind].pid == 0x8630 ||
|
||||
g_supporting_devices[it->ind].pid == 0x0439 ||
|
||||
g_supporting_devices[it->ind].pid == 0x7039 ||
|
||||
g_supporting_devices[it->ind].pid == 0x8529)
|
||||
|
@ -780,6 +840,16 @@ scanner_err hg_scanner_mgr::hg_scanner_open(scanner_handle* h, const char* name,
|
|||
|
||||
if (scanner)
|
||||
{
|
||||
int devStatus = scanner->status();
|
||||
if (SCANNER_ERR_OK != devStatus)
|
||||
{
|
||||
io->release();
|
||||
*h = NULL;
|
||||
delete scanner;
|
||||
scanner = nullptr;
|
||||
|
||||
return (scanner_err)devStatus;
|
||||
}
|
||||
scanner->set_ui_callback(&hg_scanner_mgr::ui_default_callback, hg_scanner_mgr::async_io_enabled_);
|
||||
scanner->set_dev_family(g_supporting_devices[it->ind].type.c_str());
|
||||
scanner->set_read_over_with_no_data(hg_scanner_mgr::read_over_with_eof_);
|
||||
|
@ -790,8 +860,8 @@ scanner_err hg_scanner_mgr::hg_scanner_open(scanner_handle* h, const char* name,
|
|||
if (ptr != online_devices_.end())
|
||||
ptr->scanner = (hg_scanner*)*h;
|
||||
}
|
||||
else if(hg_scanner_mgr::last_open_msg_.length())
|
||||
hg_scanner_mgr::ui_default_callback(nullptr, SANE_EVENT_ERROR, (void*)hg_scanner_mgr::last_open_msg_.c_str(), (unsigned int*)&ret, nullptr);
|
||||
//else if(hg_scanner_mgr::last_open_msg_.length())
|
||||
// hg_scanner_mgr::ui_default_callback(nullptr, SANE_EVENT_ERROR, (void*)hg_scanner_mgr::last_open_msg_.c_str(), (unsigned int*)&ret, nullptr);
|
||||
|
||||
if(io)
|
||||
io->release();
|
||||
|
@ -813,6 +883,7 @@ scanner_err hg_scanner_mgr::hg_scanner_close(scanner_handle h, bool force)
|
|||
}
|
||||
}
|
||||
|
||||
//SCAN_PTR(h)->stop(); //shield on 2023.12.13,BUG-853
|
||||
SCAN_PTR(h)->close(force);
|
||||
delete SCAN_PTR(h);
|
||||
|
||||
|
@ -1056,11 +1127,17 @@ scanner_err hg_scanner_mgr::hg_scanner_start(scanner_handle h, void* async_event
|
|||
}
|
||||
scanner_err hg_scanner_mgr::hg_scanner_stop(scanner_handle h)
|
||||
{
|
||||
return (scanner_err)SCAN_PTR(h)->stop();
|
||||
scanner_err err = (scanner_err)SCAN_PTR(h)->stop();
|
||||
|
||||
// call from APP, block when all working-threads stopped - added on 2023-10-18 when handled double-feeding in SANE
|
||||
while (SCAN_PTR(h)->is_running() != hg_scanner::THREAD_RUNNING_IDLE)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(3));
|
||||
|
||||
return err;
|
||||
}
|
||||
scanner_err hg_scanner_mgr::hg_scanner_get_img_info(scanner_handle h, SANE_Parameters* bmi, long len)
|
||||
{
|
||||
return (scanner_err)SCAN_PTR(h)->get_image_info(bmi);
|
||||
return (scanner_err)SCAN_PTR(h)->get_image_info(bmi, (int)len);
|
||||
}
|
||||
scanner_err hg_scanner_mgr::hg_scanner_read_img_data(scanner_handle h, unsigned char* data, long* len)
|
||||
{
|
||||
|
|
|
@ -120,6 +120,7 @@ public:
|
|||
static hg_scanner* create_scanner_g400(const char* name, usb_io* io, scanner_handle* h);
|
||||
static hg_scanner* create_scanner_g402(const char* name, usb_io* io, scanner_handle* h);
|
||||
static hg_scanner* create_scanner_g439(const char* name, usb_io* io, scanner_handle* h);
|
||||
static hg_scanner* create_scanner_g306(const char* name, usb_io* io, scanner_handle* h);
|
||||
|
||||
public:
|
||||
scanner_err hg_scanner_enum(ScannerInfo* scanner_list, long* count, bool local_only);
|
||||
|
|
|
@ -70,7 +70,7 @@ int LIBUSB_CALL usb_manager::usb_pnp_callback(libusb_context* ctx, libusb_device
|
|||
usb_manager* obj = (usb_manager*)monitor;
|
||||
|
||||
// if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED)
|
||||
libusb_ref_device(device); // keep the object until handle it
|
||||
//libusb_ref_device(device); // keep the object until handle it
|
||||
//else if(event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT)
|
||||
// libusb_unref_device(device);
|
||||
|
||||
|
@ -187,17 +187,22 @@ void usb_manager::thread_notify_usb_event()
|
|||
}
|
||||
}
|
||||
|
||||
libusb_ref_device(pd.dev); // for re-enter the queue pnp_events_
|
||||
notify_usb_event(pd, &retry);
|
||||
if (retry)
|
||||
{
|
||||
if(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - pd.happen_time).count()
|
||||
if (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - pd.happen_time).count()
|
||||
<= 5000)
|
||||
pnp_events_.Put(pd, sizeof(pd));
|
||||
else
|
||||
retry = false;
|
||||
if(pnp_events_.Size() == 1)
|
||||
this_thread::sleep_for(chrono::milliseconds(1000));
|
||||
else
|
||||
this_thread::sleep_for(chrono::milliseconds(delay));
|
||||
}
|
||||
if (!retry)
|
||||
libusb_unref_device(pd.dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -283,6 +288,7 @@ int usb_manager::on_usb_pnp_event(libusb_context *ctx, libusb_device *device, li
|
|||
PNPDEV pd;
|
||||
unsigned ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - born_).count();
|
||||
|
||||
libusb_ref_device(device);
|
||||
pd.ctx = ctx;
|
||||
pd.dev = device;
|
||||
pd.event = event;
|
||||
|
@ -295,9 +301,12 @@ int usb_manager::on_usb_pnp_event(libusb_context *ctx, libusb_device *device, li
|
|||
else
|
||||
{
|
||||
bool retry = false;
|
||||
libusb_ref_device(device);
|
||||
notify_usb_event(pd, &retry);
|
||||
if(retry)
|
||||
pnp_events_.Put(pd, sizeof(pd));
|
||||
else
|
||||
libusb_unref_device(device);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -760,6 +769,24 @@ void usb_io::init_after_open(void)
|
|||
close();
|
||||
last_err_ = err;
|
||||
}
|
||||
else
|
||||
{
|
||||
char str[128] = { 0 }, *ver = nullptr;
|
||||
libusb_device_descriptor dd = { 0 };
|
||||
|
||||
libusb_get_device_descriptor(dev_info_.device, &dd);
|
||||
libusb_get_string_descriptor_ascii(handle_, dd.iProduct, (unsigned char*)str, _countof(str) - 1);
|
||||
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "Device Product: '%s'\n", str);
|
||||
ver = strstr(str, "(V");
|
||||
if (ver)
|
||||
{
|
||||
ver_ = (int)atof(ver + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
ver_ = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
void usb_io::open(void)
|
||||
{
|
||||
|
@ -1098,6 +1125,10 @@ int usb_io::get_pid(void)
|
|||
{
|
||||
return dev_info_.pid;
|
||||
}
|
||||
int usb_io::get_ver(void)
|
||||
{
|
||||
return ver_;
|
||||
}
|
||||
|
||||
void usb_io::on_disconnected(void)
|
||||
{
|
||||
|
|
|
@ -152,6 +152,7 @@ class usb_io
|
|||
int last_err_;
|
||||
std::string init_err_msg_;
|
||||
libusb_device *ref_device_;
|
||||
unsigned int ver_ = 1;
|
||||
|
||||
// endpoint ports
|
||||
usb_manager::USBTRANSENDP endpoints_;
|
||||
|
@ -191,6 +192,7 @@ public:
|
|||
libusb_device* get_usb_device(void); // 获取该USB对象
|
||||
int get_vid(void); // 获取连接到该USB端口上的设备VID
|
||||
int get_pid(void); // 获取连接到该USB端口上的设备PID
|
||||
int get_ver(void);
|
||||
|
||||
void on_disconnected(void);
|
||||
std::string init_error_msg(void);
|
||||
|
|
|
@ -36,7 +36,7 @@ endif()
|
|||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
${PROJECT_SOURCE_DIR}/../../../build/libgdev.a
|
||||
${PROJECT_SOURCE_DIR}/../../../build/libgimgproc.a
|
||||
${PROJECT_SOURCE_DIR}/../../../release/uos/${CMAKE_SYSTEM_PROCESSOR}/liblang.so
|
||||
${PROJECT_SOURCE_DIR}/../../../release/uos/${CMAKE_SYSTEM_PROCESSOR}/libyuyanbao.so
|
||||
${PROJECT_SOURCE_DIR}/../3rdparty/opencv/lib/uos/${CMAKE_SYSTEM_PROCESSOR}/libopencv_imgproc.a
|
||||
${PROJECT_SOURCE_DIR}/../3rdparty/opencv/lib/uos/${CMAKE_SYSTEM_PROCESSOR}/libopencv_imgcodecs.a
|
||||
${PROJECT_SOURCE_DIR}/../3rdparty/opencv/lib/uos/${CMAKE_SYSTEM_PROCESSOR}/libopencv_highgui.a
|
||||
|
|
|
@ -66,7 +66,7 @@ class log_cls
|
|||
}
|
||||
|
||||
std::string now(g_time_tag + hg_log::current_time() + g_time_tag);
|
||||
now += truncate ? " trcated.\n" : " started.\n";
|
||||
now += truncate ? " truncated.\n" : " started.\n";
|
||||
now.insert(0, log_divider);
|
||||
fwrite(now.c_str(), 1, now.length(), file_);
|
||||
}
|
||||
|
@ -264,6 +264,13 @@ extern "C"
|
|||
|
||||
return true;
|
||||
}
|
||||
static bool save_dir_files(const char* path_file, void* param)
|
||||
{
|
||||
((std::vector<std::string>*)param)->push_back(path_file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(WIN32) || defined(_WIN64)
|
||||
static std::string u2a(const wchar_t* u, UINT cp = CP_ACP)
|
||||
{
|
||||
|
@ -287,25 +294,56 @@ extern "C"
|
|||
static int enum_files(const char* dir, bool recursive, bool(*found_file)(const char* path_file, void* param), void* param)
|
||||
{
|
||||
int ret = 0;
|
||||
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
|
||||
MODULEENTRY32W pei = { 0 };
|
||||
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
ret = GetLastError();
|
||||
if (!dir || *dir == 0)
|
||||
{
|
||||
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
|
||||
MODULEENTRY32W pei = { 0 };
|
||||
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
ret = GetLastError();
|
||||
else
|
||||
{
|
||||
pei.dwSize = sizeof(pei);
|
||||
if (Module32FirstW(h, &pei))
|
||||
{
|
||||
do
|
||||
{
|
||||
std::string ansi(u2a(pei.szExePath));
|
||||
if (!found_file(ansi.c_str(), param))
|
||||
break;
|
||||
pei.dwSize = sizeof(pei);
|
||||
} while (Module32NextW(h, &pei));
|
||||
}
|
||||
CloseHandle(h);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pei.dwSize = sizeof(pei);
|
||||
if (Module32FirstW(h, &pei))
|
||||
WIN32_FIND_DATAA wfd = { 0 };
|
||||
HANDLE h = FindFirstFileA((std::string(dir) + "\\*").c_str(), &wfd);
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
ret = GetLastError();
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
std::string ansi(u2a(pei.szExePath));
|
||||
if (!found_file(ansi.c_str(), param))
|
||||
if (strcmp(wfd.cFileName, ".") == 0 || strcmp(wfd.cFileName, "..") == 0)
|
||||
continue;
|
||||
if (!found_file((std::string(dir) + "\\" + wfd.cFileName).c_str(), param))
|
||||
{
|
||||
ret = ECANCELED;
|
||||
break;
|
||||
pei.dwSize = sizeof(pei);
|
||||
} while (Module32NextW(h, &pei));
|
||||
}
|
||||
if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && recursive)
|
||||
{
|
||||
ret = enum_files((std::string(dir) + "\\" + wfd.cFileName).c_str(), recursive, found_file, param);
|
||||
if (ret == ECANCELED)
|
||||
break;
|
||||
}
|
||||
} while (FindNextFileA(h, &wfd));
|
||||
FindClose(h);
|
||||
}
|
||||
CloseHandle(h);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -539,6 +577,10 @@ extern "C"
|
|||
{
|
||||
return MKDIR(fodler, S_IREAD | S_IWRITE | S_IEXEC) == 0 || errno == EEXIST;
|
||||
}
|
||||
void get_foler_files(const char* folder, std::vector<std::string>& files, bool recursive)
|
||||
{
|
||||
enum_files(folder, recursive, save_dir_files, &files);
|
||||
}
|
||||
std::string ini_get(const char* app, const char* key)
|
||||
{
|
||||
return ini_.get(app, key);
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "../../sdk/hginclude/huagaoxxx_warraper_ex.h"
|
||||
#include "lang/app_language.h"
|
||||
#if defined(WIN32) || defined(_WIN64)
|
||||
|
@ -64,6 +66,7 @@ extern "C"
|
|||
unsigned long long available_memory(void);
|
||||
void str_tolower(std::string& str);
|
||||
bool create_folder(const char* fodler);
|
||||
void get_foler_files(const char* folder, std::vector<std::string>& files, bool recursive = false);
|
||||
|
||||
std::string ini_get(const char* app, const char* key);
|
||||
void ini_set(const char* app, const char* key, const char* val);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <string.h>
|
||||
#endif
|
||||
#include <math.h>
|
||||
#include <exception>
|
||||
|
||||
|
||||
#define MAKE_VERSION(a, b, c, d) \
|
||||
|
@ -138,7 +139,26 @@ extern "C"
|
|||
|
||||
scanner_err hg_scanner_open(scanner_handle* h, const char* name, bool shared, const char* user, const char* pwd, const char* check, char* rsc)
|
||||
{
|
||||
return hg_scanner_mgr::instance()->hg_scanner_open(h, name, shared, user, pwd, check, rsc);
|
||||
try
|
||||
{
|
||||
return hg_scanner_mgr::instance()->hg_scanner_open(h, name, shared, user, pwd, check, rsc);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
if (h)
|
||||
*h = nullptr;
|
||||
VLOG_MINI_2(LOG_LEVEL_FATAL, "Exception occurs when open '%s': %s.\n", name, e.what());
|
||||
|
||||
return SCANNER_ERR_DATA_DAMAGED;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (h)
|
||||
*h = nullptr;
|
||||
VLOG_MINI_1(LOG_LEVEL_FATAL, "Exception occurs when open '%s'!\n", name);
|
||||
|
||||
return SCANNER_ERR_DATA_DAMAGED;
|
||||
}
|
||||
}
|
||||
|
||||
scanner_err hg_scanner_close(scanner_handle h, bool force)
|
||||
|
@ -220,6 +240,8 @@ extern "C"
|
|||
RETURN_IF(err, SCANNER_ERR_CONFIGURATION_CHANGED);
|
||||
RETURN_IF(err, SCANNER_ERR_RELOAD_IMAGE_PARAM);
|
||||
RETURN_IF(err, SCANNER_ERR_RELOAD_OPT_PARAM);
|
||||
RETURN_IF(err, SCANNER_ERR_IMAGE_PROC_FATAL);
|
||||
|
||||
RETURN_IF(err, SCANNER_ERR_NOT_OPEN);
|
||||
RETURN_IF(err, SCANNER_ERR_NOT_START);
|
||||
RETURN_IF(err, SCANNER_ERR_NOT_ANY_MORE);
|
||||
|
@ -258,6 +280,8 @@ extern "C"
|
|||
RETURN_IF(err, SCANNER_ERR_DEVICE_MAYBE_IS_HOLE);
|
||||
RETURN_IF(err, SCANNER_ERR_DEVICE_DEVS_BOOTING);
|
||||
RETURN_IF(err, SCANNER_ERR_DEVICE_UNKNOWN_STATUS);
|
||||
RETURN_IF(err, SCANNER_ERR_DEVICE_LENS_DIRTY);
|
||||
RETURN_IF(err, SCANNER_ERR_DEVICE_AUTO_FAIL_OVER);
|
||||
|
||||
if (err == SCANNER_ERR_LANG_PAK_LOST)
|
||||
return "SCANNER_ERR_LANG_PAK_LOST";
|
||||
|
@ -296,6 +320,8 @@ extern "C"
|
|||
RETURN_DESC_IF(err, SCANNER_ERR_CONFIGURATION_CHANGED);
|
||||
RETURN_DESC_IF(err, SCANNER_ERR_RELOAD_IMAGE_PARAM);
|
||||
RETURN_DESC_IF(err, SCANNER_ERR_RELOAD_OPT_PARAM);
|
||||
RETURN_DESC_IF(err, SCANNER_ERR_IMAGE_PROC_FATAL);
|
||||
|
||||
RETURN_DESC_IF(err, SCANNER_ERR_NOT_OPEN);
|
||||
RETURN_DESC_IF(err, SCANNER_ERR_NOT_START);
|
||||
RETURN_DESC_IF(err, SCANNER_ERR_NOT_ANY_MORE);
|
||||
|
@ -334,6 +360,8 @@ extern "C"
|
|||
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_MAYBE_IS_HOLE);
|
||||
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_DEVS_BOOTING);
|
||||
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_UNKNOWN_STATUS);
|
||||
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_LENS_DIRTY);
|
||||
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_AUTO_FAIL_OVER);
|
||||
if (err == SCANNER_ERR_LANG_PAK_LOST)
|
||||
return "SCANNER_ERR_LANG_PAK_LOST";
|
||||
|
||||
|
@ -415,10 +443,10 @@ extern "C"
|
|||
|
||||
const char* hg_scanner_image_statu_name(int img_statu)
|
||||
{
|
||||
RETURN_IF(img_statu, SANE_Image_Statu_OK);
|
||||
RETURN_IF(img_statu, SANE_Image_Statu_Blank);
|
||||
RETURN_IF(img_statu, SANE_Image_Statu_Double);
|
||||
RETURN_IF(img_statu, SANE_Image_Statu_Jammed);
|
||||
RETURN_IF(img_statu, IMG_STATUS_OK);
|
||||
RETURN_IF(img_statu, IMG_STATUS_BLANK);
|
||||
RETURN_IF(img_statu, IMG_STATUS_DOUBLE);
|
||||
RETURN_IF(img_statu, IMG_STATUS_JAM);
|
||||
|
||||
// NOTE: multi-thread unsafe here
|
||||
static char g_unk_statu[80] = { 0 };
|
||||
|
|
|
@ -18,7 +18,7 @@ link_directories(${PROJECT_NAME} PRIVATE
|
|||
${PROJECT_SOURCE_DIR}/../../release/uos/${CMAKE_SYSTEM_PROCESSOR}
|
||||
)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE hgdriver
|
||||
${PROJECT_SOURCE_DIR}/../../release/uos/${CMAKE_SYSTEM_PROCESSOR}/liblang.so
|
||||
${PROJECT_SOURCE_DIR}/../../release/uos/${CMAKE_SYSTEM_PROCESSOR}/libyuyanbao.so
|
||||
${PROJECT_SOURCE_DIR}/../../release/uos/${CMAKE_SYSTEM_PROCESSOR}/libhgdriver.so
|
||||
)
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ extern SANE_Status inner_sane_io_control(SANE_Handle h, unsigned long code, void
|
|||
extern const char* inner_sane_err_desc(SANE_Status err);
|
||||
extern SANE_Status inner_sane_read_ext(SANE_Img_Ext_Info* ext_info, SANE_Int* len);
|
||||
extern SANE_Status inner_sane_ex_get_driver_version(SANE_Int* hh, SANE_Int* hl, SANE_Int* lh, SANE_Int* ll);
|
||||
extern SANE_Status inner_sane_get_parameters_ex(SANE_Handle h, SANE_Image* info);
|
||||
|
||||
/// <summary>
|
||||
/// 导出接口
|
||||
|
@ -115,6 +116,10 @@ SANE_Status sane_read_ext_info(SANE_Img_Ext_Info* ext_info, SANE_Int* len)
|
|||
{
|
||||
return inner_sane_read_ext(ext_info, len);
|
||||
}
|
||||
SANE_Status sane_get_parameters_ex(SANE_Handle h, SANE_Image* info)
|
||||
{
|
||||
return inner_sane_get_parameters_ex(h, info);
|
||||
}
|
||||
int sane_ex_get_driver_version(int* hh, int* hl, int* lh, int* ll)
|
||||
{
|
||||
return inner_sane_ex_get_driver_version(hh, hl, lh, ll);
|
||||
|
|
|
@ -342,6 +342,7 @@ namespace local_utility
|
|||
TRY_MATCH(LANGUAGE);
|
||||
TRY_MATCH(INITIAL_BOOT_TIME);
|
||||
TRY_MATCH(DISCARDBLANK);
|
||||
TRY_MATCH(LENS_DIRTY);
|
||||
|
||||
//TRY_MATCH(HISTORY_COUNT);
|
||||
//TRY_MATCH(DRIVER_VERSION);
|
||||
|
@ -1669,12 +1670,26 @@ SANE_Status hg_sane_middleware::get_image_parameters(SANE_Handle handle, SANE_Pa
|
|||
|
||||
return local_utility::scanner_err_2_sane_statu(err);
|
||||
}
|
||||
SANE_Status hg_sane_middleware::get_image_parameters_ex(SANE_Handle handle, SANE_Image* params)
|
||||
{
|
||||
scanner_handle h = find_openning_device(handle);
|
||||
scanner_err err = SCANNER_ERR_NOT_START;
|
||||
|
||||
if (!params)
|
||||
return SANE_STATUS_INVAL;
|
||||
|
||||
err = hg_scanner_get_img_info(h, (SANE_Parameters*)params, sizeof(*params));
|
||||
|
||||
return local_utility::scanner_err_2_sane_statu(err);
|
||||
}
|
||||
SANE_Status hg_sane_middleware::start(SANE_Handle h, void* async_event)
|
||||
{
|
||||
LPDEVINST dev;
|
||||
scanner_handle hs = find_openning_device(h);
|
||||
scanner_err err = SCANNER_ERR_INVALID_PARAMETER;
|
||||
|
||||
LOG_INFO(LOG_LEVEL_ALL, "sane_start ...\n");
|
||||
|
||||
if(hs)
|
||||
err = hg_scanner_start(hs, async_event, -1);
|
||||
|
||||
|
@ -1696,6 +1711,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)
|
||||
|
@ -2575,8 +2591,6 @@ extern "C" { // avoid compiler exporting name in C++ style !!!
|
|||
}
|
||||
SANE_Status inner_sane_start(SANE_Handle handle)
|
||||
{
|
||||
LOG_INFO(LOG_LEVEL_ALL, "sane_start\n");
|
||||
|
||||
return hg_sane_middleware::instance()->start(handle, NULL);
|
||||
}
|
||||
SANE_Status inner_sane_read(SANE_Handle handle, SANE_Byte* data, SANE_Int max_length, SANE_Int* length)
|
||||
|
@ -2590,8 +2604,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)
|
||||
|
@ -2643,6 +2655,10 @@ extern "C" { // avoid compiler exporting name in C++ style !!!
|
|||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
SANE_Status inner_sane_get_parameters_ex(SANE_Handle h, SANE_Image* info)
|
||||
{
|
||||
return hg_sane_middleware::instance()->get_image_parameters_ex(h, info);
|
||||
}
|
||||
|
||||
void sanei_debug_msg(int level, int max_level, const char* be, const char* fmt, va_list ap)
|
||||
{
|
||||
|
|
|
@ -223,6 +223,7 @@ public:
|
|||
SANE_Status open_device(SANE_String_Const devicename, SANE_Handle* handle);
|
||||
SANE_Status close_device(SANE_Handle h);
|
||||
SANE_Status get_image_parameters(SANE_Handle handle, SANE_Parameters* params);
|
||||
SANE_Status get_image_parameters_ex(SANE_Handle handle, SANE_Image* params);
|
||||
SANE_Status start(SANE_Handle h, void* async_event);
|
||||
SANE_Status read(SANE_Handle h, void* buf, int* bytes);
|
||||
SANE_Status stop(SANE_Handle h);
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#if defined(WIN32) || defined(_WIN64)
|
||||
#include "../../../sdk/include/huagao/brand.h"
|
||||
#ifndef HGSCANNER_EXPORT
|
||||
#pragma comment(lib, "scanner.lib")
|
||||
#pragma comment(lib, "scannerqd.lib")
|
||||
#endif
|
||||
#define VERSION_MAJOR VERSION_MAIN
|
||||
#define VERSION_MINOR VERSION_SUB
|
||||
|
|
Loading…
Reference in New Issue