#include "StdAfx.h" #include "ImageMatQueue.h" #include "PublicFunc.h" #include "ImageProcess/ImageApplyHeaders.h" #include "ImageMultiOutput.h" #include "filetools.h" #include #include "StopWatch.h" #include "ImageProcess/ImageMulti.h" #include using namespace cv; using namespace std; #define DECODE_COLOR_BGR 1 #define DECODE_GRAY 6 ImageMatQueue::ImageMatQueue(void) : bRun(false) , is_scanning(false) , fx(1.001) , fy(1.007) , DogEar_index(0) , is_DogEar(false) , benablecache(false) { atm_orgin_image_remains = 0; m_dogear.reset(new CImageApplyDogEarDetection(40, 1.0, 200)); m_colorcast.reset(new CImageApplyColorCastCorrect()); 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 { FileTools::writelog(log_ERROR, "error horizental or vertical ratio"); } } void ImageMatQueue::SetGetimgnumcall(std::function getimgnumcall) { m_Getimagenumber = getimgnumcall; } void ImageMatQueue::SetDogEarCallback(std::function dogearcall) { m_DogEarDetection_callback = dogearcall; } static int paperIndex = 0; void ImageMatQueue::pushMat(std::shared_ptr data) { if (m_Getimagenumber) { #ifdef UV 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++; //string paperindexinfo = "Get the index of "+to_string(++paperIndex)+" Paper"; //FileTools::write_log("D:\\1.txt", paperindexinfo); } std::shared_ptr> 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) { paperIndex = 0; ischeck_dogear = param.is_dogeardetection; //FileTools::write_log("D:\\1.txt", "RESET PAPER COUNT"); scanParam = param; //scanParam.is_duplex = 0; //scanParam.imageRotateDegree = 90.0f; m_iaList.clear(); if (scanParam.fillhole.is_fillhole) { m_iaList.push_back(shared_ptr(new CImageApplyOutHole(25, {scanParam.fillholeratio_up/100.0f,scanParam.fillholeratio_down/100.0f,scanParam.fillholeratio_left/100.0f,scanParam.fillholeratio_right/100.0f}, 40))); } //确保能够获取正反两面图 if (param.is_autodiscradblank_normal || param.is_autodiscradblank_vince) { if (param.is_autodiscradblank_normal) m_iaList.push_back(shared_ptr(new CImageApplyDiscardBlank(40, 30, param.discardblank_percent, 200))); else m_iaList.push_back(shared_ptr(new CImageApplyDiscardBlank(40, 30, param.discardblank_percent * 15 / 10, 150))); } { bool islongcustomcrop = param.papertype == TwSS::USStatement;// || param.papertype == TwSS::MaxSize); //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 fixedSize = papersize.GetPaperSize(param.papertype, param.resolution_native, param.paperAlign); #endif bool normalCrop = ((param.autodescrew) || (islongcustomcrop ? islongcustomcrop : param.is_autocrop) || (param.fillbackground)) ? false : param.normalCrop; m_iaList.push_back(shared_ptr(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))); /* m_iaList.push_back(shared_ptr(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(new CImageApplyResize(CImageApplyResize::ResizeType::DSIZE, cv::Size(fixedSize.cx, fixedSize.cy), 1.0, 1.0)));*/ } //if (param.pixtype == 2 || param.filter != 3 || param.enhance_color) //{ // m_iaList.push_back(shared_ptr(new CImageApplyHSVCorrect(CImageApplyHSVCorrect::CorrectOption::LowSaturation_Removal, true))); //} if ((param.pixtype == 2) && (param.is_colorcast)) { m_iaList.push_back(m_colorcast); } if (param.fadeback)//&& param.pixtype == 2 { m_iaList.push_back(shared_ptr(new CImageApplyFadeBackGroudColor(50,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(new CImageApplyChannel(static_cast(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 int contrast = 0.0; //= (int)(param.contrast * 0.036);;//[-36,36] 0.036=72.0/2000.0; if (param.contrast < 0.0) // 暂不修改对比度,彩色文稿色偏 contrast = (int)(param.contrast * 0.036); else contrast = (int)(param.contrast * 0.018); m_iaList.push_back(shared_ptr(new CImageApplyAdjustColors(bright, contrast, param.gamma))); } //答题卡除红 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(new CImageApplyHSVCorrect(hsv))); } //锐化 if (param.sharpen) { SharpenBlur sb = (SharpenBlur)param.sharpen; m_iaList.push_back(shared_ptr(new CImageApplySharpen(sb))); } //自动颜色识别 if (param.automaticcolor) m_iaList.push_back(shared_ptr(new CImageApplyColorRecognition(param.automaticcolortype == 1 ? CImageApplyColorRecognition::ColorRecognitionMode::Color_Gray : CImageApplyColorRecognition::ColorRecognitionMode::Color_Mono))); //缩放 if (param.resolution_dst != param.resolution_native) { CImageApplyResize* apply; bool islongcustomcrop = false; 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)); } //二值化 if (param.pixtype == 0) //threshold m_iaList.push_back(shared_ptr(new CImageApplyBWBinaray(CImageApplyBWBinaray::ThresholdType::THRESH_BINARY))); //黑白降噪优化 if (scanParam.detachnoise.is_detachnoise && scanParam.pixtype == 0) { m_iaList.push_back(shared_ptr(new CImageApplyDetachNoise(scanParam.detachnoise.detachnoise))); } if (scanParam.en_fold) { m_iaList.push_back(shared_ptr(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 _tcscat(szIniFile, _T("\\twain_32\\LANXUMSCAN\\tessdata\\osd.traineddata")); #elif defined AUGE _tcscat(szIniFile, _T("\\twain_32\\AuGeScan\\tessdata\\osd.traineddata")); #elif defined HANVON _tcscat(szIniFile, _T("\\twain_32\\HanvonScan\\tessdata\\osd.traineddata")); #elif defined MAKERIGHTWAY _tcscat(szIniFile, _T("\\twain_32\\RIGHTWAYSCAN\\tessdata\\osd.traineddata")); #elif defined NOLOGO _tcscat(szIniFile, _T("\\twain_32\\Scan\\tessdata\\osd.traineddata")); #elif defined CUMTENN _tcscat(szIniFile, _T("\\twain_32\\CumTennScan\\tessdata\\osd.traineddata")); #elif defined ZHUOYUYUN _tcscat(szIniFile, _T("\\twain_32\\ZhuoYuYunScan\\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(new CImageApplyRotation(type, param.is_backrotate180, param.resolution_dst, chRtn))); delete[] chRtn; } } void ImageMatQueue::EnqueueBmpBuffer(std::shared_ptr> bmpdata) { m_imagedata.Put(bmpdata); } void ImageMatQueue::PaniusCount(int count) { atm_orgin_image_remains -= count; #ifdef UV if (scanParam.hardwarecaps.en_uv) { if (m_Getimagenumber) m_Getimagenumber(false, 2); } else if (m_Getimagenumber) m_Getimagenumber(false, 1); #else if (m_Getimagenumber) m_Getimagenumber(false, 1); #endif } void ImageMatQueue::init_cachethread() { if (!m_threadcache.get()) { benablecache = true; m_threadcache.reset(new thread(&ImageMatQueue::cache_run, this)); } } static int index = 0; void ImageMatQueue::cache_run() { 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; 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()); 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); } FileTools::writelog(log_INFO, " 磁盘写入图片数据耗时 " + to_string(sw.elapsed_ms()) + " buffer size = " + to_string(buf->size())); buf->clear(); buf.reset(); sw.reset(); } } } } 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> 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> 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() { 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; } static int indeximg = 0; void ImageMatQueue::proc() { while (bRun) { if (m_imagedata.Size() > 0) { this_thread::sleep_for(chrono::milliseconds(10)); continue; } string msg; auto info = m_imgCacheinfo.Take(); FileTools::writelog(log_DEBUG, "get tmp file "+info.path); if (info.path.length() == 0 || !isFileExist(info.path)) { msg = "error while checking file :" + info.path + " ,file lost"; FileTools::writelog(log_ERROR, msg); continue; } //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(); //} } } void ImageMatQueue::splitimg(std::vector& mats) { CImageApplyRotation autotext(CImageApplyRotation::RotationType::Rotate_90_clockwise, true, scanParam.resolution_dst, NULL); autotext.apply(mats, true); CImageApplySplit m_split; std::vector 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); } 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 mats; std::vector uvmats; StopWatch sw; if (info.scannerType == ScannerSerial::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); } 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); } 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); } 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); } #ifdef UV mats.push_back(scanParam.is_switchfrontback ? front : back); mats.push_back(scanParam.is_switchfrontback ? back : front); #else 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 { 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()) { 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); } uvmats.push_back(scanParam.is_switchfrontback ? front : back); uvmats.push_back(scanParam.is_switchfrontback ? back : front); front.release(); back.release(); remove(uvinfo.path.c_str()); } } #endif }//g400 serials FileTools::writelog(log_DEBUG, " start image process "); std::vector rects; std::vector 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(ptr)->rotatedROIs(); isDesaskew = dynamic_cast(ptr)->isDesaskew(); } else if (typeid(*ptr) == typeid(CImageApplyRotation)) angleResults = dynamic_cast(ptr)->angleResults(); } #ifdef UV if (!uvmats.empty()) { //拼接原图和UV图 for (int j = 0; j < mats.size(); j++) { if (!scanParam.is_duplex && j == 1) { mats[j].release(); break; } if (!mats[j].empty()) { 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; } } rects.clear(); uvmats.clear(); } #endif //string path = FileTools::get_appdata_path() + to_string(m_snowflake.nextid()) + ".jpg"; //cv::imwrite(path, mats[0]); //path = FileTools::get_appdata_path() + to_string(m_snowflake.nextid()) + ".jpg"; //cv::imwrite(path, mats[1]); 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; #ifdef UV if (scanParam.pixtype == 1 && mats[i].channels() == 3)//gray cv::cvtColor(mats[i], mats[i], COLOR_BGR2GRAY); #else if (scanParam.pixtype == 1 && (scanParam.hsvcorrect || scanParam.fadeback || scanParam.hsvFilter))// && scanParam.hsvcorrect if (mats[i].channels() == 3) cvtColor(mats[i], mats[i], cv::COLOR_BGR2GRAY); #endif 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(); } } else { FileTools::writelog(log_ERROR, "enqueue image is empty " + std::to_string(index++)); } } 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(); #ifdef UV PaniusCount(scanParam.hardwarecaps.en_uv ? 2 : 1); #else PaniusCount(); #endif } 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 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)) 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(); } } else { FileTools::writelog(log_ERROR, "enqueue image is empty " + std::to_string(index++)); } } 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(); } G400Decode::G400Decode(std::shared_ptr> buff) { m_buffs.push_back(buff); } G200Decode::G200Decode(std::shared_ptr> 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> buffB(new std::vector(buff->size())); std::shared_ptr> buffF(new std::vector(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(); }