tx-gxx-linux/device/gxx-linux/scanner/iimagehandler.h

332 lines
13 KiB
C++

#pragma once
#include "commondef.h"
#include "ImageApplyHeaders.h"
#include "CSizedetect.h"
#include <vector>
#include <map>
#include <memory>
using namespace std;
static std::map<TwSS, Size> papersize{
{A3, Size{297, 420}},
{A4, Size{210, 297}},
{A5, Size{148, 210}},
{A6, Size{105, 148}},
{B4, Size{250, 353}},
{B5, Size{176, 250}},
{B6, Size{125, 176}},
{MaxSize, Size{297, 420 * 2}},
{USStatement, Size{297, (long)(420 * 1.5)}},
{USLetter, Size{216, 279}},
{USLegal, Size{216, 356}},
{USLedger, Size{279, 432}},
{None, Size{297, 420}},
{K8, Size{270, 390}},
{K16, Size{190, 270}},
{Trigeminy, Size{270, 560}},
};
class IImageHandler
{
public:
virtual ~IImageHandler() {}
virtual void add_image(void *data, int width, int height, int type,int scannnum) = 0;
virtual void config_procparams(HGImgProcParms params) = 0;
virtual void add_scanevent(HGIntInfo status) = 0;
virtual void clear() = 0;
virtual bool done() = 0;
virtual void Set_ratio(u32 h_ratio,u32 v_ratio) = 0;
ImgStatus getimgstatus() { return m_imgstatus;}
void resetimgstatus() { m_imgstatus={.status=NO_error,.sannum=0};}
Size GetPaperSize(std::uint32_t paperType, float dpi, int orentation)
{
if (papersize.find((TwSS)paperType) != papersize.end() && (dpi > 99 && dpi < 601))
{
Size resize{2338, 3307};
if (orentation == 0)
{
resize.x = papersize[(TwSS)paperType].x * dpi / 25.4;
resize.y = papersize[(TwSS)paperType].y * dpi / 25.4;
return resize;
}
else
{
resize.y = papersize[(TwSS)paperType].x * dpi / 25.4;
resize.x = papersize[(TwSS)paperType].y * dpi / 25.4;
return resize;
}
}
return Size{2338, 3307};
}
void set_scanconfig(HGScanConfig config)
{
m_scanconfig = config;
}
bool set_config(GScanCap config) {
m_hgimgconfig = config;
m_ials.clear();
if(m_dog.get())
{
if(m_hgimgconfig.dogeardistabce>=10 && m_hgimgconfig.dogeardistabce <=300)
m_dog->setDistance(m_hgimgconfig.dogeardistabce);
else
m_dog->setDistance(50);
}
if(config.fillhole.is_fillhole)
{
float ratio=config.fillhole.fillholeratio/100.0;
m_ials.push_back(std::shared_ptr<CImageApply>(new CImageApplyOutHole(200.0f,ratio,50.0)));
}
bool islongcustomcrop = config.papertype == 52;
//bool isautocrop = config.papertype == TwSS::None;
Size fixedSize;
printf(" \nconfig.papertype=%d", config.papertype);
printf(" \nconfig.AutoCrop_threshold=%d", config.AutoCrop_threshold);
printf(" \nconfig.autodescrew=%d", config.autodescrew);
printf(" \nconfig.automaticcolor=%d", config.automaticcolor);
printf(" \nconfig.brightness=%f", config.brightness);
printf(" \nconfig.contrast=%f", config.contrast);
printf(" \nconfig.detachnoise=%d", config.detachnoise);
printf(" \nconfig.en_fold=%d", config.en_fold);
printf(" \nconfig.en_sizecheck=%d", config.en_sizecheck);
printf(" \nconfig.enhance_color=%d", config.enhance_color);
printf(" \nconfig.fillbackground=%d", config.fillbackground);
printf(" \nconfig.filter=%d", config.filter);
printf(" \nconfig.fillhole.is_fillhole=%d", config.fillhole.is_fillhole);
printf(" \nconfig.gamma=%f", config.gamma);
printf(" \nconfig.hardwarecaps.capturepixtype=%d", config.hardwarecaps.capturepixtype);
printf(" \nconfig.hardwarecaps.en_doublefeed=%d", config.hardwarecaps.en_doublefeed);
printf(" \nconfig.hsvcorrect=%d", config.hsvcorrect);
printf(" \nconfig.imageRotateDegree=%d", config.imageRotateDegree);
printf(" \nconfig.indent=%d", config.indent);
printf(" \nconfig.is_autocontrast=%d", config.is_autocontrast);
printf(" \nconfig.is_autocrop=%d", config.is_autocrop);
printf(" \nconfig.is_autodiscradblank_normal=%d", config.is_autodiscradblank_normal);
printf(" \nconfig.is_autodiscradblank_vince=%d", config.is_autodiscradblank_vince);
printf(" \nconfig.is_autotext=%d", config.is_autotext);
printf(" \nconfig.is_backrotate180=%d", config.is_backrotate180);
printf(" \nconfig.is_convex=%d", config.is_convex);
printf(" \nconfig.is_duplex=%d", config.is_duplex);
printf(" \nconfig.is_switchfrontback=%d", config.is_switchfrontback);
printf(" \nconfig.is_dogeardetection=%d", config.is_dogeardetection);
printf(" \nconfig.fillhole.multi_output_red=%d", config.multi_output_red);
printf(" \nconfig.noise=%d", config.noise);
printf(" \nconfig.hardwarecaps.paperAlign=%d", config.paperAlign);
printf(" \nconfig.hardwarecaps.pixtype=%d", config.pixtype);
printf(" \nconfig.resolution_dst=%d", config.resolution_dst);
printf(" \nconfig.resolution_native=%d", config.resolution_native);
printf(" \nconfig.scannum=%d", config.scannum);
printf(" \nconfig.sharpen=%d", config.sharpen);
printf(" \nconfig.is_dogeardetection=%d", config.is_dogeardetection);
fixedSize = GetPaperSize(config.papertype, 200.0f, config.paperAlign);
// m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyAutoCrop(islongcustomcrop ? islongcustomcrop : config.is_autocrop,
// config.autodescrew, config.fillbackground, cv::Size(fixedSize.x, fixedSize.y), config.is_convex,false,config.AutoCrop_threshold,config.noise,config.indent)));
if (config.is_autodiscradblank_normal || config.is_autodiscradblank_vince)
{
//m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyDiscardBlank()));
CImageApplyDiscardBlank *disBlank = new CImageApplyDiscardBlank();
//跳过空白页阈值
int area = 200;
int intensity = 15;
int maxHeight = 3307; //A3 height
//页面最大高度获取
if (config.papertype == 54)
maxHeight = 6614;
//阈值参数赋值
if (config.discardblank_percent < 10)
{
area = 70 + (int)((config.discardblank_percent - 1) * 13.33);
intensity = 8 + config.discardblank_percent / 2;
}
else if (config.discardblank_percent < 20)
{
area = 190 + (config.discardblank_percent - 10) * 14;
intensity = 15;
}
else if (config.discardblank_percent < 40)
{
area = 400 + (config.discardblank_percent - 20) * 10;
intensity = 20;
}
else if (config.discardblank_percent < 60)
{
area = 600 + (config.discardblank_percent - 40) * 20;
intensity = 20;
}
else if (config.discardblank_percent < 80)
{
area = 1000 + (config.discardblank_percent - 60) * 55;
intensity = 30;
}
else
{
area = 2100 + (config.discardblank_percent - 80) * (maxHeight - 2100) / 20;
intensity = 40;
}
//判断是否为跳过空白页发票
if (config.is_autodiscradblank_vince)
{
area *= 1.5;
intensity *= 1.5;
}
//设置参数阈值
// disBlank->setMinArea(area);
// disBlank->setIntensity(intensity);
printf("\n area =%d,intensity =%d ",area,intensity);
m_ials.push_back(shared_ptr<CImageApply>(disBlank));
//m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyDiscardBlank(config.areanum,config.devnmax)));
}
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyAutoCrop(islongcustomcrop ? islongcustomcrop : config.is_autocrop,
config.autodescrew, config.fillbackground, cv::Size(fixedSize.x, fixedSize.y), config.is_convex,false,config.AutoCrop_threshold,config.noise,config.indent)));
//除底色
if(config.fadeback && config.pixtype == 2)
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyFadeBackGroudColor(100,0,config.fadebackrange)));
//自定义裁切
if(config.cropRect.enable &&!config.is_autocrop)
{
printf("\n 自定义裁切");
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyCustomCrop(cv::Rect(config.cropRect.x,config.cropRect.y,config.cropRect.width,config.cropRect.height))));
}
// if (config.customGamma.enable)
// {
// m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyCustomGamma(imgparams.customGamma.table, imgparams.customGamma.tableLength)));
// }
//filter 0 r 1 g 2 b 3 none enhance color 0 none 1 r 2 g 3 b
if (config.filter != 3 || config.enhance_color)
{
int channel = 0; //filter none r g b enhance none r g b
if (config.filter != 3)
{
channel = config.filter;
}
else
{
channel = config.enhance_color + 4;
}
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyChannel(static_cast<CImageApplyChannel::Channel>(channel))));
}
if (config.brightness != 0 || config.contrast != 0 || config.gamma != 1.0)
{
double aa = (254 / 2000.0) * config.brightness + 0.5;
int bright = ceil(aa); //[-127,128] 0.128=256.0/2000.0
int contrast = 0.0; //= (int)(config.contrast * 0.036);;//[-36,36] 0.036=72.0/2000.0;
if (config.contrast < 0.0) // 暂不修改对比度,彩色文稿色偏
contrast = (int)(config.contrast * 0.036);
else
contrast = (int)(config.contrast * 0.018);
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyAdjustColors(bright, contrast, config.gamma)));
}
//答题卡除红
if (config.hsvcorrect && config.pixtype==2)
{
printf("\n 答题卡除红");
m_ials.push_back(shared_ptr<CImageApplyHSVCorrect>(new CImageApplyHSVCorrect(CImageApplyHSVCorrect::CorrectOption::Red_Removal)));
}
//防止渗透
if (config.refuseInflow)
{
printf("\n 防止渗透");
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyRefuseInflow()));
}
//色彩校正
if (config.colorCorrection && config.pixtype != 0)
{
printf("\n 色彩校正");
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyAutoContrast()));
}
//除摩尔纹 除网纹
if (config.textureRemove ||config.removeMorr)
{
printf("\n 除摩尔纹 除网纹");
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyTextureRemoval()));
}
//锐化
if (config.sharpen)
{
CImageApplyFilter::FilterMode sb = (CImageApplyFilter::FilterMode)config.sharpen;
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyFilter(sb)));
}
//自动颜色识别
// if (config.automaticcolor)
// m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyColorRecognition(config.automaticcolortype==1? CImageApplyColorRecognition::ColorRecognitionMode::Color_Gray:CImageApplyColorRecognition::ColorRecognitionMode::Color_Mono)));
//缩放
if (config.resolution_dst != config.resolution_native)
{
CImageApplyResize *apply;
bool islongcustomcrop = false;
if (config.papertype == 52 || config.normalCrop)
islongcustomcrop = true;
if (config.is_autocrop || islongcustomcrop)
{
double ratio = config.resolution_dst / 200.0; //
apply = new CImageApplyResize(CImageApplyResize::ResizeType::RATIO, cv::Size(0, 0), ratio, ratio);
}
else
{
Size dSize = GetPaperSize(config.papertype, config.resolution_dst, config.paperAlign);
apply = new CImageApplyResize(CImageApplyResize::ResizeType::DSIZE, cv::Size(dSize.x, dSize.y), 1.0, 1.0);
}
m_ials.push_back(shared_ptr<CImageApply>(apply));
}
//二值化
if (config.pixtype == 0) //threshold
{
if(config.errorExtention)
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyBWBinaray(CImageApplyBWBinaray::ThresholdType::ERROR_DIFFUSION)));
else
{
//m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyResize(CImageApplyResize::ResizeType::RATIO,cv::Size(0,0),600.0/(double(config.resolution_dst)),600.0/(double(config.resolution_dst)))));
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyBWBinaray(CImageApplyBWBinaray::ThresholdType::THRESH_BINARY,30,37,19)));
//m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyResize(CImageApplyResize::ResizeType::RATIO,cv::Size(0,0),(double(config.resolution_dst))/600.0,(double(config.resolution_dst))/600.0)));
}
//黑白降噪优化
if (config.detachnoise.is_detachnoise)
{
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyDetachNoise(config.detachnoise.detachnoise)));
}
}
if (config.en_fold)
{
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyConcatenation(CImageApplyConcatenation::horizontal, cv::Scalar(255, 255, 255))));
}
if (config.imageRotateDegree != 0.0 || config.is_backrotate180)
{
CImageApplyRotation::RotationType type;
if (config.imageRotateDegree > 89.0f && config.imageRotateDegree < 91.0f)
type = CImageApplyRotation::RotationType::Rotate_90_clockwise;
else if (config.imageRotateDegree > 269.0f && config.imageRotateDegree < 271.0f)
type = CImageApplyRotation::RotationType::Rotate_90_anti_clockwise;
else if (config.imageRotateDegree > 179.0f && config.imageRotateDegree < 181.0f)
type = CImageApplyRotation::RotationType::Rotate_180;
else
type = CImageApplyRotation::RotationType::Invalid;
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyRotation(type, config.is_backrotate180, config.resolution_dst, NULL)));
}
return true;
}
protected:
GScanCap m_hgimgconfig;
HGScanConfig m_scanconfig;
ImgStatus m_imgstatus;
std::vector<std::shared_ptr<CImageApply>> m_ials;
std::shared_ptr<CImageApplyDogEarDetection> m_dog;
std::shared_ptr<CSizedetect> m_sizedetect;
};