twain3.0/huagao/Device/ImageMatQueue.cpp

926 lines
28 KiB
C++
Raw Normal View History

#include "StdAfx.h"
#include "ImageMatQueue.h"
#include "PublicFunc.h"
#include "ImageProcess/ImageApplyHeaders.h"
#include "ImageMultiOutput.h"
#include "filetools.h"
#include <math.h>
#include "StopWatch.h"
2022-05-24 12:05:47 +00:00
#include "ImageProcess/ImageMulti.h"
2022-06-29 12:24:24 +00:00
#include <Psapi.h>
2021-12-16 08:21:35 +00:00
using namespace cv;
using namespace std;
#define DECODE_COLOR_BGR 1
#define DECODE_GRAY 6
ImageMatQueue::ImageMatQueue(void)
: bRun(false)
, is_scanning(false)
2021-08-24 10:17:32 +00:00
, fx(1.001)
, fy(1.007)
, DogEar_index(0)
, is_DogEar(false)
, benablecache(false)
{
2021-08-24 10:17:32 +00:00
atm_orgin_image_remains = 0;
2021-08-24 10:17:32 +00:00
m_dogear.reset(new CImageApplyDogEarDetection(40, 1.0, 200));
m_snowflake.init(1, 1);
}
ImageMatQueue::~ImageMatQueue(void)
{
m_rawBuffs.Clear();
m_rawBuffs.ShutDown();
clear_cachefiles();
m_imgCacheinfo.ShutDown();
m_imagedata.Clear();
m_imagedata.ShutDown();
if (m_threadProc.get()) {
bRun = false;
m_threadProc->join();
m_threadProc.reset();
}
if (m_threadcache.get())
{
benablecache = false;
if (m_threadcache->joinable())
{
m_threadcache->join();
m_threadcache.reset();
}
}
}
void ImageMatQueue::run()
{
init_cachethread();
if (!m_threadProc.get()) {
bRun = true;
m_threadProc.reset(new thread(&ImageMatQueue::proc, this));
}
}
bool ImageMatQueue::get_isDogEar()
{
return is_DogEar;
}
void ImageMatQueue::reset_DogEar()
{
is_DogEar = false;
DogEar_index = 0;
}
int ImageMatQueue::orginimgcount()
{
return atm_orgin_image_remains;
}
void ImageMatQueue::updatefixratio(float& hratio, float& vratio)
{
if (hratio > 0.10f && hratio < 3.0f && vratio >0.10f && vratio < 3.0f) {
this->fx = hratio;
this->fy = vratio;
}
else
{
2021-08-24 10:17:32 +00:00
FileTools::writelog(log_ERROR, "error horizental or vertical ratio");
}
}
2021-08-24 10:17:32 +00:00
void ImageMatQueue::SetGetimgnumcall(std::function<void(bool, int)> getimgnumcall)
{
m_Getimagenumber = getimgnumcall;
}
void ImageMatQueue::SetDogEarCallback(std::function<void(int)> dogearcall)
{
m_DogEarDetection_callback = dogearcall;
}
2020-09-21 01:25:46 +00:00
static int paperIndex = 0;
void ImageMatQueue::pushMat(std::shared_ptr<IDecode> data)
{
2021-08-24 10:17:32 +00:00
if (m_Getimagenumber)
{
#ifdef UV
2021-08-24 10:17:32 +00:00
if (scanParam.hardwarecaps.en_uv)
m_Getimagenumber(true, 2);
else
m_Getimagenumber(true, 1);
#else
m_Getimagenumber(true, 1);
#endif
}
m_rawBuffs.Put(data);
atm_orgin_image_remains++;
2020-09-21 01:25:46 +00:00
//string paperindexinfo = "Get the index of "+to_string(++paperIndex)+" Paper";
//FileTools::write_log("D:\\1.txt", paperindexinfo);
}
std::shared_ptr<std::vector<unsigned char>> ImageMatQueue::popBmpdata()
{
return m_imagedata.Take();
}
bool ImageMatQueue::valid()
{
return m_imagedata.Size();
}
void ImageMatQueue::clear()
{
if(m_rawBuffs.Size()>0)
m_rawBuffs.Clear();
clear_cachefiles();
if (m_imagedata.Size() > 0)
m_imagedata.Clear();
atm_orgin_image_remains = 0;
}
void ImageMatQueue::rawBuffsclear()
{
m_rawBuffs.Clear();
}
void ImageMatQueue::setparam(const GScanCap& param)
{
2020-09-21 01:25:46 +00:00
paperIndex = 0;
ischeck_dogear = param.is_dogeardetection;
2020-09-21 01:25:46 +00:00
//FileTools::write_log("D:\\1.txt", "RESET PAPER COUNT");
scanParam = param;
//scanParam.is_duplex = 0;
//scanParam.imageRotateDegree = 90.0f;
m_iaList.clear();
2021-11-20 03:09:04 +00:00
2022-09-20 01:08:11 +00:00
if (scanParam.fillhole.is_fillhole) {
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyOutHole(25,
{scanParam.fillholeratio_up/100.0f,scanParam.fillholeratio_down/100.0f,scanParam.fillholeratio_left/100.0f,scanParam.fillholeratio_right/100.0f},
40)));
2021-11-20 06:24:33 +00:00
} //确保能够获取正反两面图
if (param.is_autodiscradblank_normal || param.is_autodiscradblank_vince) {
2022-09-20 01:08:11 +00:00
if (param.is_autodiscradblank_normal)
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyDiscardBlank(40, 30, param.discardblank_percent, 200)));
else
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyDiscardBlank(40, 30, param.discardblank_percent * 15 / 10, 150)));
}
2021-11-20 03:09:04 +00:00
{
2022-07-06 03:47:08 +00:00
bool islongcustomcrop = param.papertype == TwSS::USStatement;// || param.papertype == TwSS::MaxSize);
2021-11-20 03:09:04 +00:00
//bool isautocrop = param.papertype == TwSS::None;
CSize fixedSize;
#ifdef REAL300DPI
fixedSize = papersize.GetPaperSize(param.papertype, param.resolution_dst > 240.0f ? 300.0f : 200.0f, param.paperAlign);
#else // REAL300DPI
2022-05-24 12:05:47 +00:00
fixedSize = papersize.GetPaperSize(param.papertype, param.resolution_native, param.paperAlign);
2021-11-20 03:09:04 +00:00
#endif
bool normalCrop = ((param.autodescrew) || (islongcustomcrop ? islongcustomcrop : param.is_autocrop) || (param.fillbackground)) ? false : param.normalCrop;
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyAutoCrop(islongcustomcrop ? islongcustomcrop : param.is_autocrop,
param.autodescrew, param.fillbackground, cv::Size(fixedSize.cx, fixedSize.cy), param.is_convex, false, param.AutoCrop_threshold, param.noise, param.indent, normalCrop,param.hsvFilter==0)));
2021-11-20 03:09:04 +00:00
/* m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyAutoCrop(true, param.autodescrew, param.fillbackground, cv::Size(fixedSize.cx, fixedSize.cy), param.is_convex, false, param.AutoCrop_threshold, param.noise, param.indent)));
if(!(islongcustomcrop ? islongcustomcrop : param.is_autocrop))
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyResize(CImageApplyResize::ResizeType::DSIZE, cv::Size(fixedSize.cx, fixedSize.cy), 1.0, 1.0)));*/
}
2022-05-24 12:05:47 +00:00
//if (param.pixtype == 2 || param.filter != 3 || param.enhance_color)
//{
// m_iaList.push_back(shared_ptr<CImageApplyHSVCorrect>(new CImageApplyHSVCorrect(CImageApplyHSVCorrect::CorrectOption::LowSaturation_Removal, true)));
//}
if (param.fadeback)//&& param.pixtype == 2
{
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyFadeBackGroudColor(100,0,param.fadeback_range)));
}
//filter 0 r 1 g 2 b 3 none enhance color 0 none 1 r 2 g 3 b
if (param.filter != 3 || param.enhance_color) {
int channel = 0; //filter none r g b enhance none r g b
if (param.filter != 3) { channel = param.filter; }
else { channel = param.enhance_color + 4; }
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyChannel(static_cast<CImageApplyChannel::Channel>(channel))));
}
if (param.brightness != 0 || param.contrast != 0 || param.gamma != 1.0) {
double aa = (254 / 2000.0) * param.brightness + 0.5;
int bright = ceil(aa);//[-127,128] 0.128=256.0/2000.0
2021-08-24 10:17:32 +00:00
int contrast = 0.0; //= (int)(param.contrast * 0.036);;//[-36,36] 0.036=72.0/2000.0;
2021-11-20 06:24:33 +00:00
if (param.contrast < 0.0) // 暂不修改对比度,彩色文稿色偏
contrast = (int)(param.contrast * 0.036);
else
contrast = (int)(param.contrast * 0.018);
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyAdjustColors(bright, contrast, param.gamma)));
}
2022-05-24 12:05:47 +00:00
2021-11-20 06:24:33 +00:00
//答题卡除红
if ((scanParam.hsvcorrect || scanParam.hsvFilter)&&scanParam.pixtype==2)
{
CImageApplyHSVCorrect::CorrectOption hsv;//= config.hsvcorrect?CImageApplyHSVCorrect::CorrectOption::Red_Removal:
if (scanParam.hsvcorrect)
hsv = CImageApplyHSVCorrect::CorrectOption::Red_Removal;
else
hsv = CImageApplyHSVCorrect::CorrectOption::FXB_Colour_Cast;
m_iaList.push_back(shared_ptr<CImageApplyHSVCorrect>(new CImageApplyHSVCorrect(hsv)));
}
2021-11-20 06:24:33 +00:00
//锐化
if (param.sharpen) {
SharpenBlur sb = (SharpenBlur)param.sharpen;
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplySharpen(sb)));
}
2021-11-20 06:24:33 +00:00
//自动颜色识别
if (param.automaticcolor)
2021-08-24 10:17:32 +00:00
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyColorRecognition(param.automaticcolortype == 1 ? CImageApplyColorRecognition::ColorRecognitionMode::Color_Gray : CImageApplyColorRecognition::ColorRecognitionMode::Color_Mono)));
2021-11-20 06:24:33 +00:00
//缩放
if (param.resolution_dst != param.resolution_native)
{
CImageApplyResize* apply;
bool islongcustomcrop = false;
2021-09-23 01:19:47 +00:00
if (param.papertype == TwSS::USStatement || param.normalCrop)
islongcustomcrop = true;
if (param.is_autocrop || islongcustomcrop) {
double ratio = param.resolution_dst / 200.0;//
apply = new CImageApplyResize(CImageApplyResize::ResizeType::RATIO, cv::Size(0, 0), ratio, ratio);
}
else {
CSize dSize = papersize.GetPaperSize(param.papertype, param.resolution_dst, param.paperAlign);
apply = new CImageApplyResize(CImageApplyResize::ResizeType::DSIZE, cv::Size(dSize.cx, dSize.cy), 1.0, 1.0);
}
m_iaList.push_back(shared_ptr< CImageApply>(apply));
}
2021-11-20 06:24:33 +00:00
//二值化
if (param.pixtype == 0) //threshold
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyBWBinaray(CImageApplyBWBinaray::ThresholdType::THRESH_BINARY)));
2021-11-20 06:24:33 +00:00
//黑白降噪优化
2021-08-24 10:17:32 +00:00
if (scanParam.detachnoise.is_detachnoise && scanParam.pixtype == 0)
{
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyDetachNoise(scanParam.detachnoise.detachnoise)));
}
2021-08-24 10:17:32 +00:00
if (scanParam.en_fold)
{
2021-08-24 10:17:32 +00:00
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyConcatenation(CImageApplyConcatenation::horizontal, cv::Scalar(255, 255, 255))));
}
if (param.imageRotateDegree != 0.0 || param.is_backrotate180 || param.is_autotext)
{
CImageApplyRotation::RotationType type;
if (param.imageRotateDegree > 89.0f && param.imageRotateDegree < 91.0f)
type = CImageApplyRotation::RotationType::Rotate_90_clockwise;
else if (param.imageRotateDegree > 269.0f && param.imageRotateDegree < 271.0f)
type = CImageApplyRotation::RotationType::Rotate_90_anti_clockwise;
else if (param.imageRotateDegree > 179.0f && param.imageRotateDegree < 181.0f)
type = CImageApplyRotation::RotationType::Rotate_180;
else
type = CImageApplyRotation::RotationType::Invalid;
if (param.is_autotext)
type = CImageApplyRotation::RotationType::AutoTextOrientation;
TCHAR szIniFile[MAX_PATH] = { 0 };
SHGetSpecialFolderPath(NULL, szIniFile, CSIDL_WINDOWS, TRUE);
#ifdef LANXUM
2021-11-20 06:24:33 +00:00
_tcscat(szIniFile, _T("\\twain_32\\LANXUMSCAN\\tessdata\\osd.traineddata"));
2021-11-20 03:09:04 +00:00
#elif defined AUGE
2021-11-20 06:24:33 +00:00
_tcscat(szIniFile, _T("\\twain_32\\AuGeScan\\tessdata\\osd.traineddata"));
2021-09-23 01:19:47 +00:00
#elif defined HANVON
2021-11-20 06:24:33 +00:00
_tcscat(szIniFile, _T("\\twain_32\\HanvonScan\\tessdata\\osd.traineddata"));
#elif defined MAKERIGHTWAY
_tcscat(szIniFile, _T("\\twain_32\\RIGHTWAYSCAN\\tessdata\\osd.traineddata"));
2022-05-24 12:05:47 +00:00
#elif defined NOLOGO
_tcscat(szIniFile, _T("\\twain_32\\Scan\\tessdata\\osd.traineddata"));
2022-06-29 12:24:24 +00:00
#elif defined CUMTENN
_tcscat(szIniFile, _T("\\twain_32\\CumTennScan\\tessdata\\osd.traineddata"));
#else
_tcscat(szIniFile, _T("\\twain_32\\HuaGoScan\\tessdata\\osd.traineddata"));
#endif //
int iLen = WideCharToMultiByte(CP_ACP, 0, szIniFile, -1, NULL, 0, NULL, NULL);
char* chRtn = new char[iLen * sizeof(char)];
WideCharToMultiByte(CP_ACP, 0, szIniFile, -1, chRtn, iLen, NULL, NULL);
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyRotation(type, param.is_backrotate180, param.resolution_dst, chRtn)));
delete[] chRtn;
}
2021-11-20 03:09:04 +00:00
}
void ImageMatQueue::EnqueueBmpBuffer(std::shared_ptr<std::vector<unsigned char>> bmpdata)
{
m_imagedata.Put(bmpdata);
}
void ImageMatQueue::PaniusCount(int count)
{
2021-08-24 10:17:32 +00:00
atm_orgin_image_remains -= count;
#ifdef UV
2021-08-24 10:17:32 +00:00
if (scanParam.hardwarecaps.en_uv)
{
2021-08-24 10:17:32 +00:00
if (m_Getimagenumber)
m_Getimagenumber(false, 2);
}
else
2021-08-24 10:17:32 +00:00
if (m_Getimagenumber)
m_Getimagenumber(false, 1);
#else
if (m_Getimagenumber)
2021-08-24 10:17:32 +00:00
m_Getimagenumber(false, 1);
#endif
}
void ImageMatQueue::init_cachethread()
{
2021-08-24 10:17:32 +00:00
if (!m_threadcache.get())
{
benablecache = true;
m_threadcache.reset(new thread(&ImageMatQueue::cache_run, this));
}
}
static int index = 0;
void ImageMatQueue::cache_run()
{
2021-08-24 10:17:32 +00:00
while (benablecache)
{
if (m_rawBuffs.Size() == 0)
{
this_thread::sleep_for(chrono::milliseconds(2));
continue;
}
if (m_rawBuffs.Size() > 0)
{
CacheInfo info;
auto buffs = m_rawBuffs.Take()->getImageBuffs();
buffs.size() == 2 ? info.scannerType = ScannerSerial::G200Serial : info.scannerType = ScannerSerial::G400Serial;
2022-06-29 12:24:24 +00:00
for (auto& buf : buffs)
{
StopWatch sw;
index++;
string path = FileTools::get_appdata_path() + to_string(m_snowflake.nextid()) + ".jpg";
if (!access(path.c_str(), 0))
{
remove(path.c_str());
2021-08-24 10:17:32 +00:00
FileTools::writelog(log_ERROR, "exist file " + path + " maybe lost previous session scanned image");
}
CFile frb;
if (frb.Open(CString(path.c_str()), CFile::modeWrite | CFile::modeCreate | CFile::typeBinary))
{
if (*(buf->data()) != -1 && *(buf->data() + 1) != -40 && *(buf->data() + 2) != -1 && *(buf->data() + 3) != -32)
{
frb.Write(buf->data() + 12, buf->size() - 12);
FileTools::writelog(log_ERROR, "usb data error -image data");
}
else
frb.Write(buf->data(), buf->size());
frb.Flush();
frb.Close();
info.path = path;
m_imgCacheinfo.Put(info);
}
else
{
FileTools::writelog(log_ERROR, "error while openning cache file :" + path);
}
2021-11-20 06:24:33 +00:00
FileTools::writelog(log_INFO, " 磁盘写入图片数据耗时 " + to_string(sw.elapsed_ms()) + " buffer size = " + to_string(buf->size()));
buf->clear();
buf.reset();
sw.reset();
}
}
}
}
2022-05-24 12:05:47 +00:00
void ImageMatQueue::MultiOut(cv::Mat& pDid)
{
IMageMulti imgmulti(scanParam.multioutput);
auto rets = imgmulti.apply(pDid);
switch (scanParam.multioutput)
{
case 0: {
for (int x = 0; x < rets.size(); x++) {
if(rets[x].empty())
continue;
std::shared_ptr<std::vector<uchar>> data;
if(x == 2)
data = Mat2BmpBw(rets[x], scanParam.resolution_dst).getBmpDataBuffer();
else
data = Mat2Bmp(rets[x], scanParam.resolution_dst).getBmpDataBuffer();
EnqueueBmpBuffer(data);
data.reset();
}
break;
}
case 1: {
for (auto& node : rets) {
if(node.empty())
continue;
auto data = Mat2Bmp(node, scanParam.resolution_dst).getBmpDataBuffer();
EnqueueBmpBuffer(data);
data.reset();
}
break;
}
case 2:
case 3:{
for (int x = 0; x < rets.size(); x++) {
if (rets[x].empty())
continue;
std::shared_ptr<std::vector<uchar>> data;
if (x == 1)
data = Mat2BmpBw(rets[x], scanParam.resolution_dst).getBmpDataBuffer();
else
{
scanParam.multioutput == 2 ? void(0) : cv::cvtColor(rets[x], rets[x], cv::COLOR_BGR2GRAY);
data = Mat2Bmp(rets[x], scanParam.resolution_dst).getBmpDataBuffer();
}
EnqueueBmpBuffer(data);
data.reset();
}
break;
}
default:
break;
}
}
void ImageMatQueue::clear_cachefiles()
{
while (m_imgCacheinfo.Size() > 0)
{
auto tpath = m_imgCacheinfo.Take();
if (isFileExist(tpath.path))
remove(tpath.path.c_str());
}
}
bool ImageMatQueue::empty()
{
2021-08-24 10:17:32 +00:00
return m_imgCacheinfo.Size() == 0 && (m_imagedata.Size() == 0) && (m_rawBuffs.Size() == 0) && !is_scanning && atm_orgin_image_remains == 0;
}
bool ImageMatQueue::queuesempty()
{
return atm_orgin_image_remains <= 0 && m_imagedata.Size() == 0;
}
2021-11-20 03:09:04 +00:00
static int indeximg = 0;
void ImageMatQueue::proc()
{
while (bRun)
{
2021-09-03 06:12:28 +00:00
if (m_imagedata.Size() > 0)
{
this_thread::sleep_for(chrono::milliseconds(10));
continue;
}
string msg;
auto info = m_imgCacheinfo.Take();
2022-05-24 12:05:47 +00:00
FileTools::writelog(log_DEBUG, "get tmp file "+info.path);
2021-08-24 10:17:32 +00:00
if (info.path.length() == 0 || !isFileExist(info.path))
{
msg = "error while checking file :" + info.path + " ,file lost";
FileTools::writelog(log_ERROR, msg);
continue;
}
2022-06-29 12:24:24 +00:00
//if(scanParam.resolution_dst < 500)
duplex_process(info);
//else {
// ImreadModes rmc;
// if (scanParam.filter != 3 || scanParam.enhance_color || scanParam.hsvcorrect)
// rmc = IMREAD_COLOR;
// else
// rmc = scanParam.pixtype == 2 ? IMREAD_COLOR : IMREAD_GRAYSCALE;
// StopWatch sw;
// cv::Mat imgfront;
// cv::Mat imgback;
// if (info.scannerType == G200Serial)
// {
// auto back = m_imgCacheinfo.Take();
// if (!isFileExist(back.path))
// {
// msg = "error while reading g200 back image " + back.path + " ,file not exist";
// FileTools::writelog(log_ERROR, msg);
// }
// imgfront = imread(info.path, rmc);
// msg = "reading image front time elapsed_ms:" + std::to_string(sw.elapsed_ms());
// FileTools::writelog(log_DEBUG, msg);
// sw.reset();
// imgback = imread(back.path, rmc);
// msg = "reading image back time elapsed_ms:" + std::to_string(sw.elapsed_ms());
// FileTools::writelog(log_DEBUG, msg);
// sw.reset();
// if (!imgfront.empty() && !imgback.empty())
// {
// if (scanParam.imageRotateDegree != 0.0 && scanParam.imageRotateDegree != 180.0) {
// cv::flip(imgback, imgback, 0);
// cv::flip(imgback, imgback, 1);
// }
// cv::resize(imgback, imgback, cv::Size(), fx, fy);//用于修正与佳能机器幅面大小不匹配问题 此系数请勿轻易动
// cv::resize(imgfront, imgfront, cv::Size(), fx, fy);
// remove(info.path.c_str());
// remove(back.path.c_str());
// }
// else
// {
// msg = "get empty mat! empty ";
// msg += (imgfront.empty() ? " front image" : " back image");
// FileTools::writelog(log_ERROR, msg);
// }
// }
// else
// {
// auto mat = imread(info.path, rmc);
// if (!mat.empty())
// {
// imgfront = mat(Rect(0, 0, mat.cols / 2, mat.rows - 10));//避免图像尾部出现无效数据丢弃10行数据
// imgback = mat(Rect(mat.cols / 2, 0, mat.cols / 2, mat.rows - 10));//避免图像尾部出现无效数据丢弃10行数据
// if (scanParam.imageRotateDegree != 0.0 && scanParam.imageRotateDegree != 180.0) {
// cv::flip(imgfront, imgfront, 0);
// cv::flip(imgfront, imgfront, 1);
// }
// mat.release();
// remove(info.path.c_str());
// }
// else
// {
// msg = "g400 get empty mat! empty ";
// FileTools::writelog(log_ERROR, msg);
// }
// }
// if (!imgfront.empty() && !imgback.empty()) {
// if (scanParam.is_duplex)
// {
// single_process(scanParam.is_switchfrontback ? imgback : imgfront);
// imgfront.release();
// std::this_thread::sleep_for(std::chrono::milliseconds(4399));
// //::SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1);
// //::EmptyWorkingSet(GetCurrentProcess());
// single_process(scanParam.is_switchfrontback ? imgfront : imgback);
// std::this_thread::sleep_for(std::chrono::milliseconds(4399));
// imgback.release();
// }
// else
// {
// imgback.release();
// single_process(imgfront);
// std::this_thread::sleep_for(std::chrono::milliseconds(4399));
// imgfront.release();
// }
// }
// PaniusCount();
//}
}
}
2022-06-29 12:24:24 +00:00
void ImageMatQueue::splitimg(std::vector<cv::Mat>& mats) {
CImageApplyRotation autotext(CImageApplyRotation::RotationType::Rotate_90_clockwise, true, scanParam.resolution_dst, NULL);
autotext.apply(mats, true);
CImageApplySplit m_split;
std::vector<cv::Mat> tmp;
for (int i = 0; i < mats.size();i++) {
if (!mats[i].empty()){
auto sptmp = m_split.apply(mats[i],i);
for (auto& matvar : sptmp){
if (!matvar.empty())
tmp.push_back(matvar);
}
}
}
if (tmp.size() >= 2)
std::swap(tmp[0], tmp[1]);
mats.swap(tmp);
}
2022-06-29 12:24:24 +00:00
void ImageMatQueue::duplex_process(CacheInfo info)
{
std::string msg;
ImreadModes rmc;
if (scanParam.filter != 3 || scanParam.enhance_color || scanParam.hsvcorrect)
rmc = IMREAD_COLOR;
else
rmc = scanParam.pixtype == 2 ? IMREAD_COLOR : IMREAD_GRAYSCALE;
std::vector<cv::Mat> mats;
std::vector<Mat> uvmats;
StopWatch sw;
if (info.scannerType == ScannerSerial::G200Serial)
{
auto back = m_imgCacheinfo.Take();
if (!isFileExist(back.path))
{
2022-06-29 12:24:24 +00:00
msg = "error while reading g200 back image " + back.path + " ,file not exist";
FileTools::writelog(log_ERROR, msg);
}
sw.reset();
cv::Mat imgfront = imread(info.path, rmc);
msg = "reading image front time elapsed_ms:" + std::to_string(sw.elapsed_ms());
FileTools::writelog(log_DEBUG, msg);
sw.reset();
cv::Mat imgback = imread(back.path, rmc);
msg = "reading image back time elapsed_ms:" + std::to_string(sw.elapsed_ms());
FileTools::writelog(log_DEBUG, msg);
sw.reset();
if (!imgfront.empty() && !imgback.empty())
{
if (scanParam.imageRotateDegree != 0.0 && scanParam.imageRotateDegree != 180.0) {
cv::flip(imgback, imgback, 0);
cv::flip(imgback, imgback, 1);
}
2022-06-29 12:24:24 +00:00
mats.push_back(scanParam.is_switchfrontback ? imgback : imgfront);
mats.push_back(scanParam.is_switchfrontback ? imgfront : imgback);
remove(info.path.c_str());
remove(back.path.c_str());
}
else
{
msg = "get empty mat! empty ";
msg += (imgfront.empty() ? " front image" : " back image");
FileTools::writelog(log_ERROR, msg);
}
2022-06-29 12:24:24 +00:00
for (size_t i = 0; i < mats.size(); i++)
{
if (!mats[i].empty())
cv::resize(mats[i], mats[i], cv::Size(), fx, fy);//用于修正与佳能机器幅面大小不匹配问题 此系数请勿轻易动
}
//if (scanParam.en_fold != 0) { //对折前旋转屏蔽 20211214 奥鸽要求
// cv::flip(mats[0], mats[0], 1);
// cv::flip(mats[0], mats[0], 0);
//}
}
else
{
auto mat = imread(info.path, rmc);
if (!mat.empty())
{
Mat front = mat(Rect(0, 0, mat.cols / 2, mat.rows - 10));//避免图像尾部出现无效数据丢弃10行数据
Mat back = mat(Rect(mat.cols / 2, 0, mat.cols / 2, mat.rows - 10));//避免图像尾部出现无效数据丢弃10行数据
if (scanParam.imageRotateDegree != 0.0 && scanParam.imageRotateDegree != 180.0) {
cv::flip(front, front, 0);
cv::flip(front, front, 1);
}
2022-06-29 12:24:24 +00:00
#ifdef UV
mats.push_back(scanParam.is_switchfrontback ? front : back);
mats.push_back(scanParam.is_switchfrontback ? back : front);
#else
2022-06-29 12:24:24 +00:00
mats.push_back(scanParam.is_switchfrontback ? front : back);
mats.push_back(scanParam.is_switchfrontback ? back : front);
#endif
front.release();
back.release();
remove(info.path.c_str());
}
else
{
2022-06-29 12:24:24 +00:00
msg = "g400 get empty mat! empty ";
FileTools::writelog(log_ERROR, msg);
}
#ifdef UV
if (scanParam.hardwarecaps.en_uv)//EN UV
{
auto uvinfo = m_imgCacheinfo.Take();
auto matuv = imread(uvinfo.path, IMREAD_COLOR);
if (!matuv.empty())
{
2022-06-29 12:24:24 +00:00
Mat front = matuv(Rect(0, 0, mat.cols / 2, mat.rows));
Mat back = matuv(Rect(mat.cols / 2, 0, mat.cols / 2, mat.rows));
if (scanParam.imageRotateDegree != 0.0 && scanParam.imageRotateDegree != 180.0) {
cv::flip(front, front, 0);
cv::flip(front, front, 1);
}
2022-06-29 12:24:24 +00:00
uvmats.push_back(scanParam.is_switchfrontback ? front : back);
uvmats.push_back(scanParam.is_switchfrontback ? back : front);
2021-08-24 10:17:32 +00:00
front.release();
back.release();
2022-06-29 12:24:24 +00:00
remove(uvinfo.path.c_str());
}
2022-06-29 12:24:24 +00:00
}
#endif
2022-06-29 12:24:24 +00:00
}//g400 serials
FileTools::writelog(log_DEBUG, " start image process ");
std::vector<cv::RotatedRect> rects;
std::vector<int> angleResults;
bool isDesaskew = false;
sw.reset();
for (int j = 0; j < m_iaList.size(); j++) {
m_iaList[j]->apply(mats, scanParam.is_duplex);
CImageApply* ptr = m_iaList[j].get();
if (typeid(*ptr) == typeid(CImageApplyAutoCrop))
{
//rects = dynamic_cast<CImageApplyAutoCrop*>(ptr)->rotatedROIs();
2022-06-29 12:24:24 +00:00
isDesaskew = dynamic_cast<CImageApplyAutoCrop*>(ptr)->isDesaskew();
}
2022-06-29 12:24:24 +00:00
else if (typeid(*ptr) == typeid(CImageApplyRotation))
angleResults = dynamic_cast<CImageApplyRotation*>(ptr)->angleResults();
}
2021-11-20 03:09:04 +00:00
#ifdef UV
2022-06-29 12:24:24 +00:00
if (!uvmats.empty())
{
//拼接原图和UV图
for (int j = 0; j < mats.size(); j++)
{
2022-06-29 12:24:24 +00:00
if (!scanParam.is_duplex && j == 1) {
mats[j].release();
break;
}
if (!mats[j].empty())
{
2022-06-29 12:24:24 +00:00
cv::Mat mergeOrgin_UV = ImageApplyUV::Apply(mats[j], uvmats[j], rects[j], isDesaskew, angleResults.size() > 0 ? angleResults[j] : 0, scanParam.pixtype);
if (!mergeOrgin_UV.empty())
mats[j] = mergeOrgin_UV;
}
}
2022-06-29 12:24:24 +00:00
rects.clear();
uvmats.clear();
}
#endif
2022-06-29 12:24:24 +00:00
FileTools::writelog(log_DEBUG, " image process finish");
if (!scanParam.is_duplex && mats.size() > 1) {
mats.pop_back();
}
if (scanParam.is_split)
{
splitimg(mats);
}
for (int i = 0; i < mats.size(); i++) {
if (!mats[i].empty()) {
IMat2Bmp idata;
2021-08-24 10:17:32 +00:00
#ifdef UV
2022-06-29 12:24:24 +00:00
if (scanParam.pixtype == 1 && mats[i].channels() == 3)//gray
cv::cvtColor(mats[i], mats[i], COLOR_BGR2GRAY);
2021-08-24 10:17:32 +00:00
#else
if (scanParam.pixtype == 1 && (scanParam.hsvcorrect || scanParam.fadeback))// && scanParam.hsvcorrect
2022-06-29 12:24:24 +00:00
if (mats[i].channels() == 3)
cvtColor(mats[i], mats[i], cv::COLOR_BGR2GRAY);
2021-08-24 10:17:32 +00:00
#endif
2022-06-29 12:24:24 +00:00
if (scanParam.en_multi_output) {
MultiOut(mats[i]);
}
else
{
2022-06-29 12:24:24 +00:00
idata = (scanParam.pixtype == 0 || (((scanParam.automaticcolortype == 0) && (scanParam.automaticcolor == true)) && (mats[i].channels() == 1))) ?
(IMat2Bmp)Mat2BmpBw(mats[i], scanParam.resolution_dst) : Mat2Bmp(mats[i], scanParam.resolution_dst);
if (!scanParam.multi_output_red)
mats[i].release();
//cv::imwrite("D:\\img\\" + to_string(indeximg++) + ".jpg", mats[i]);
auto data = idata.getBmpDataBuffer();
EnqueueBmpBuffer(data);
data.reset();
}
}
2022-06-29 12:24:24 +00:00
else
{
FileTools::writelog(log_ERROR, "enqueue image is empty " + std::to_string(index++));
}
}
2022-06-29 12:24:24 +00:00
if (scanParam.multi_output_red) {
for (int i = 0; i < mats.size(); i++) {
if (!mats[i].empty()) {
ImageMultiOutput m_mlt;
Mat ret = m_mlt.GetMultiFilterMat(mats[i], 2);
mats[i].release();
if (!ret.empty()) {
if (!scanParam.is_duplex && i == 1) {
ret.release();
2022-06-29 12:24:24 +00:00
break;
}
2022-06-29 12:24:24 +00:00
Mat2Bmp mb(ret, scanParam.resolution_dst);
auto data = mb.getBmpDataBuffer();
ret.release();
EnqueueBmpBuffer(data);
data.reset();
}
}
}
2022-06-29 12:24:24 +00:00
}
2022-06-29 12:24:24 +00:00
mats.clear();
#ifdef UV
2022-06-29 12:24:24 +00:00
PaniusCount(scanParam.hardwarecaps.en_uv ? 2 : 1);
#else
2022-06-29 12:24:24 +00:00
PaniusCount();
#endif
}
2022-06-29 12:24:24 +00:00
void ImageMatQueue::single_process(cv::Mat& mat)
{
FileTools::writelog(log_DEBUG, " start image process ");
StopWatch sw;
for (int j = 0; j < m_iaList.size(); j++) {
m_iaList[j]->apply(mat, false);
}
FileTools::writelog(log_DEBUG, " image process finish");
std::vector<cv::Mat> mats;
mats.push_back(mat);
if (scanParam.is_split)
{
splitimg(mats);
}
for (int i = 0; i < mats.size(); i++) {
if (!mats[i].empty()) {
IMat2Bmp idata;
if (scanParam.pixtype == 1 && (scanParam.hsvcorrect!=0 || scanParam.fadeback))
2022-06-29 12:24:24 +00:00
if (mats[i].channels() == 3)
cvtColor(mats[i], mats[i], cv::COLOR_BGR2GRAY);
if (scanParam.en_multi_output) {
MultiOut(mats[i]);
}
else
{
idata = (scanParam.pixtype == 0 || (((scanParam.automaticcolortype == 0) && (scanParam.automaticcolor == true)) && (mats[i].channels() == 1))) ?
(IMat2Bmp)Mat2BmpBw(mats[i], scanParam.resolution_dst) : Mat2Bmp(mats[i], scanParam.resolution_dst);
if (!scanParam.multi_output_red)
mats[i].release();
//cv::imwrite("D:\\img\\" + to_string(indeximg++) + ".jpg", mats[i]);
auto data = idata.getBmpDataBuffer();
EnqueueBmpBuffer(data);
data.reset();
2021-12-16 08:21:35 +00:00
}
}
2022-06-29 12:24:24 +00:00
else
{
FileTools::writelog(log_ERROR, "enqueue image is empty " + std::to_string(index++));
}
2021-12-16 08:21:35 +00:00
}
2022-06-29 12:24:24 +00:00
if (scanParam.multi_output_red) {
for (int i = 0; i < mats.size(); i++) {
if (!mats[i].empty()) {
ImageMultiOutput m_mlt;
Mat ret = m_mlt.GetMultiFilterMat(mats[i], 2);
mats[i].release();
if (!ret.empty()) {
if (!scanParam.is_duplex && i == 1) {
ret.release();
break;
}
Mat2Bmp mb(ret, scanParam.resolution_dst);
auto data = mb.getBmpDataBuffer();
ret.release();
EnqueueBmpBuffer(data);
data.reset();
}
}
}
}
mats.clear();
2021-12-16 08:21:35 +00:00
}
G400Decode::G400Decode(std::shared_ptr<std::vector<char>> buff)
{
m_buffs.push_back(buff);
}
G200Decode::G200Decode(std::shared_ptr<std::vector<char>> buff)
{
const int int_buffer_size = 1024;
int buffer_size = buff->size();
int b_buffer_size = 0;
int f_buffer_size = 0;
std::shared_ptr<std::vector<char>> buffB(new std::vector<char>(buff->size()));
std::shared_ptr<std::vector<char>> buffF(new std::vector<char>(buff->size()));;
unsigned char* bbuf = (unsigned char*)(buffB->data());
unsigned char* fbuf = (unsigned char*)(buffF->data());
unsigned char* buf = (unsigned char*)(buff->data());
for (int i = 0; i < (buffer_size / int_buffer_size); i++) {
if (buf[(i + 1) * int_buffer_size - 1] == 0) {
memcpy(bbuf + b_buffer_size, buf + i * int_buffer_size, int_buffer_size - 1);
b_buffer_size += (int_buffer_size - 1);
}
else if (buf[(i + 1) * int_buffer_size - 1] == 255) {
memcpy(fbuf + f_buffer_size, buf + i * int_buffer_size, int_buffer_size - 1);
f_buffer_size += (int_buffer_size - 1);
}
}
buffB->resize(b_buffer_size);
buffF->resize(f_buffer_size);
m_buffs.push_back(buffB);
m_buffs.push_back(buffF);
buff.reset();
}