#include "MonoCapturer.h" #include "config.h" #include "applog.h" #include "gvideoisp1.h" #include "Gpio.h" #include "DevUtil.h" #include "FpgaComm.h" #include "CorrectParam.h" #include "correct_ultis.h" #include "stringex.hpp" #include "filetools.h" #include "CImageMerge.h" #include "jsonconfig.h" #include "ThreadPool.h" #include "deviceconfig.h" using namespace std; using namespace cv; #define LOG_PATH "/usr/local/correct.log" FileTools ft_log(LOG_PATH); static std::string loggername = "MonoCapturer"; static double radio = 1.0; static int offsetStep1[12]; static int expStep1[2][3]; static void initStep1() { printf("initStep aaaaaaaaaaa \n"); for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { expStep1[i][j] = 600; } } for (int i = 0; i < 12; i++) { offsetStep1[i] = 256; printf("offsetStep[%d]=%d \n", i, offsetStep1[i]); } } MonoCapturer::MonoCapturer() : // vdd_cis_3voff_pin(new GpioOut(CIS_3v3_Off)), // vdd_vis_5ven_pin(new GpioOut(CIS_5v_En)), reset_pin(new GpioOut(50)), // image_in_transfer_pin(new Gpio(Image_In_Transfer)), // initDone_pin(new Gpio(Fpga_InitDone)), fpgaLoad(new Gpio(70)), fpga_conf_done(new Gpio(69)), // gpio init 导出 scanservice 仅操作IO fpga_conf_initn(new Gpio(71)), // gpio init 导出 scanservice 仅操作IO bcorrecting(false), m_fpgaversion(0x00090001) { LOG_INIT(); fpga_conf_done->setDirection(Gpio::in); fpgaComm.reset(new FpgaComm()); // fpga_reset(); // fpgaComm->resetADC(); fpgaComm->setDelayTime(0X3e8); // fpgaComm->update(); video.reset(new VIDEO_CLASS()); fpgaComm->read(15, m_fpgaversion); } MonoCapturer::~MonoCapturer() { if (video.get()) video.reset(); printf("Exit ~MonoCapturer() \n"); } void MonoCapturer::open() { } void MonoCapturer::Fpga_regsAccess_reset(bool enable) { if (fpgaComm.get()) fpgaComm->regsAccess_reset(enable); } void MonoCapturer::open(HGScanConfig config, FPGAConfigParam fpgaparam) { m_config = config; m_fpgaparam = fpgaparam; fpgaComm->update(1); bool dunnancis = true; int dpi; if (dunnancis) dpi = config.g200params.dpi == 0x02 ? 2 : (config.g200params.dpi == 0x03 ? 3 : 2); else dpi = config.g200params.dpi; int mode = config.g200params.color; int channelwidth = dpi == 0x02 ? 1296 : (dpi == 0x03 ? 2592 : 864); int channels = mode == 0x01 ? 3 : 1; int width = channelwidth * channels; float resize = 1.0; if (fpgaparam.DpiMode == 0x10) { if (config.g200params.dpi == 1) resize = 2.07f; else if (config.g200params.dpi == 2) resize = 1.36667f; } auto phyHeight = paperHeight[(PaperSize)config.g200params.paper] * resize; printf("\n ########## phyHeight = %d ", phyHeight); int pixheight; // = ((int)((phyHeight / 25.4 * (dpi == 0x02 ? 300 : (dpi == 0x03 ? 600 : 200)) + 2) / 3)) * 3 * 2; if (dunnancis) { int tdpi = config.g200params.dpi == 0x02 ? 300 : (config.g200params.dpi == 0x03 ? 600 : 200); // int tdpi = config.g200params.dpi == 0x02 ? 285 : (config.g200params.dpi == 0x03 ? 570 : 190); pixheight = ((int)((phyHeight / 25.4 * tdpi + 2) / 3)) * 3 * 2; } else pixheight = ((int)((phyHeight / 25.4 * (config.g200params.dpi == 0x02 ? 300 : (config.g200params.dpi == 0x03 ? 600 : 200)) + 2) / 3) * 3) * 2; if (config.g200params.paper == (unsigned int)(PaperSize::G400_AUTO) || pixheight > 16380) // isp sup max height config 16383 pixheight = 16380; int dstheight = pixheight; int fpgaheight = mode == 0x1 ? dstheight / 2 * 3 : dstheight / 2; // 彩色配置fpga 高度要为目标图像高度的3倍 // fpgaparam = GetFpgaparam(config.g200params.dpi, mode);// == 0x02 ? 2 : (config.g200params.dpi == 0x03 ? 3 : 2) // FPGAConfigParam fpgaparam = GetFpgaparam(dpi, mode); printf("dpi = %d fpgaparam.sp=%d exp=%d gain=%d offset=%d LUT=%s \n", dpi, fpgaparam.Sp, fpgaparam.ExposureB[0], fpgaparam.GainB[0], fpgaparam.OffsetB[0], fpgaparam.LutPath.c_str()); // int startsample= cistype.GetCisType()==CISVendor::DUNNAN_CIS_V0?205:262; int startsample = 205; uint tmp_vs = 0; fpgaComm->read(15, tmp_vs); if (tmp_vs == 0x9000c) startsample = 201; else if (tmp_vs >= 0x90002) startsample = 205; else startsample = 208; // if((fpgaparam.MaxExp > 50) && (fpgaparam.MaxExp < 1000)) // startsample = fpgaparam.MaxExp; ModeFpga fpgamod = { .colorMode = mode, .dpi = dpi, .led = 1, .sample = startsample, // 256+39 .adcA = 0, .adcB = 0, .selftest = 0, .sp = fpgaparam.Sp}; // 600DPI 0x1450 300DPI 0xe10 fpgaComm->setRegs(0x01, *((int *)(&fpgamod))); fpgaComm->setSample(startsample); if (tmp_vs == 0x9000c) fpgaComm->setVsp(66, 67); else if (tmp_vs != 0x9000a) fpgaComm->setVsp(1, 2); else { fpgaComm->setVsp(40, 120); } fpgaComm->enableLed(true); fpgaComm->setEnTestCol(false); fpgaComm->setEnTestBit(false); // fpgaComm->update(2); configFPGAParam(mode, config.g200params.dpi); // fpgaComm->update(3); // fpgaComm->setFrameHeight(12); // fpgaComm->capture(); // auto data = video->read_frame(100); // fpgaComm->enableLed(false); video->open(width, dstheight); // 300dpi 7344/2 600dpi 7344 printf("opened video with width = %d height = %d \n", width, dstheight); fpgaComm->setFrameHeight(12); for (int i = 0; i < 1; i++) { fpgaComm->capture(); // abort first frame video->read_frame(100); std::this_thread::sleep_for(std::chrono::milliseconds(20)); printf("abort first frame \n"); } fpgaComm->setFrameHeight(fpgaheight); printf("fpgaComm set height = %d \n", fpgaheight); fpgaComm->update(3); // initLut(fpgaparam.LutPath, config.g200params.color); init_lutdate(); // initLut(m_config.g200params.is_textcorrect?m_fpgaparam.LutPath:m_fpgaparam.TextLutPath,m_config.g200params.color); } void MonoCapturer::init_lutdate() { DeviceConfig::Gray_Apply gray_; gray_.value = Get_static_deviceconfig().GetParam().gray_param; std::string lutpath = m_config.g200params.is_textcorrect?m_fpgaparam.LutPath:m_fpgaparam.TextLutPath; if((m_fpgaparam.DpiMode == 1) && (gray_.Param_Setting.en_200_clr == 1 && m_config.g200params.color == true)) lutpath = "/usr/local/huago/Graylut200clr.bmp"; else if ((m_fpgaparam.DpiMode == 2) && (gray_.Param_Setting.en_300_clr == 1 && m_config.g200params.color == true)) lutpath = "/usr/local/huago/Graylut300clr.bmp"; else if ((m_fpgaparam.DpiMode == 3) && (gray_.Param_Setting.en_600_clr == 1 && m_config.g200params.color == true)) lutpath = "/usr/local/huago/Graylut600clr.bmp"; else if ((m_fpgaparam.DpiMode == 16) && (gray_.Param_Setting.en_slow_clr == 1 && m_config.g200params.color == true)) lutpath = "/usr/local/huago/Graylutslow_moireclr.bmp"; else if ((m_fpgaparam.DpiMode == 1) && (gray_.Param_Setting.en_200_gray == 1 && m_config.g200params.color == false)) lutpath = "/usr/local/huago/Graylut200gray.bmp"; else if ((m_fpgaparam.DpiMode == 2) && (gray_.Param_Setting.en_300_gray == 1 && m_config.g200params.color == false)) lutpath = "/usr/local/huago/Graylut300gray.bmp"; else if ((m_fpgaparam.DpiMode == 3) && (gray_.Param_Setting.en_600_gray == 1 && m_config.g200params.color == false)) lutpath = "/usr/local/huago/Graylut600gray.bmp"; else if ((m_fpgaparam.DpiMode == 16) && (gray_.Param_Setting.en_slow_gray == 1 && m_config.g200params.color == false)) lutpath = "/usr/local/huago/Graylutslow_moiregray.bmp"; initLut(lutpath, m_config.g200params.color); } void MonoCapturer::close() { if (video.get()) video->close(); // fpga_reload(); } void MonoCapturer::start() { if (video.get()) video->start(); } void MonoCapturer::MonoCapturer::stop() { if (video.get()) video->stop(); } bool MonoCapturer::is_runing() { return false; } void MonoCapturer::snap() { fpgaComm->capture(); } void MonoCapturer::stopsnap() { } int MonoCapturer::getautosizeheight() { unsigned int val; unsigned int reg8 = 0; fpgaComm->read(8, reg8); fpgaComm->read(14, val); int regv = val; val &= 0x0000ffff; fpgaComm->write(8, reg8 & 0xfffffff7); std::this_thread::sleep_for(std::chrono::milliseconds(5)); fpgaComm->read(14, val); regv = val; val &= 0x0000ffff; fpgaComm->read(8, reg8); std::cout << string_format("TWO height = %d reg[14] = %d \n", val, regv); std::this_thread::sleep_for(std::chrono::milliseconds(5)); fpgaComm->write(8, reg8 | 0x8); return val; } void MonoCapturer::set_size(int width, int height) { if (video.get()) video->set_size(width, height); } void MonoCapturer::set_sp(int sp) { fpgaComm->setSp(sp); } void *MonoCapturer::readFrame(int timeout) { return video->read_frame(timeout); } void MonoCapturer::set_gain(int ix, int val) { for (int i = 0; i < 6; i++) { if (ix) fpgaComm->setAGain(i, val); else fpgaComm->setBGain(i, val); } } void MonoCapturer::set_offset(int ix, int val) { for (int i = 0; i < 6; i++) { if (ix) fpgaComm->setAOffset(i, val); else fpgaComm->setBOffset(i, val); std::this_thread::sleep_for(std::chrono::milliseconds(1)); } } void MonoCapturer::set_expo(int ix, int val) { switch (ix) { case 0: fpgaComm->setAExposureR(val); break; case 1: fpgaComm->setAExposureG(val); break; case 2: fpgaComm->setAExposureB(val); break; case 3: fpgaComm->setBExposureR(val); break; case 4: fpgaComm->setBExposureG(val); break; case 5: fpgaComm->setBExposureB(val); break; default: break; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); } std::shared_ptr MonoCapturer::regs() { return fpgaComm; } void MonoCapturer::reset() { fpga_reset(); // fpgaComm->resetADC(); // fpgaComm->setDelayTime(0X3e8); // fpgaComm->setRegs(0x00, fpgaComm->getRegs(0x00)); // fpgaComm->setRegs(0x01, fpgaComm->getRegs(0x01)); } int MonoCapturer::width() { int dpi = fpgaComm->getDpi(); int channel = 1; int width = dpi == 0x02 ? 1296 * channel : (dpi == 0x03 ? (2592 * channel) : (864 * channel)); // printf("get width = %d \n", width); return width; } int MonoCapturer::height() { return fpgaComm->getFrameHeight(); } int MonoCapturer::color() { return fpgaComm->getColorMode() ? 16 : 0; } void MonoCapturer::init_autocorrect(int colormode) { std::thread t_correctthread = std::thread(&MonoCapturer::correctcolor, this, colormode); t_correctthread.detach(); } void MonoCapturer::configFPGAParam(int mode, int dpi) { printf("dpi = %d mode = %d \n", dpi, mode); fpgaComm->resetADC(); FPGAConfigParam fpgaparam = GetFpgaparam(dpi, mode); // int offF[6]={0,0,0,0,0,200}; // int offB[6]={0,0,0,0,0,0}; for (int i = 0; i < 6; i++) { if (i < 3) { set_expo(i, fpgaparam.ExposureF[i]); printf("fpgaparam.ExposureF[%d] = %d \n", i, fpgaparam.ExposureF[i]); } else { set_expo(i, fpgaparam.ExposureB[i % 3]); printf("fpgaparam.ExposureB[%d] = %d \n", i, fpgaparam.ExposureB[i % 3]); } std::this_thread::sleep_for(std::chrono::milliseconds(2)); fpgaComm->setAOffset(i, fpgaparam.OffsetF[i]); // fpgaComm->setAOffset(i,offF[i]); printf("fpgaparam.setAOffset[%d] = %d \n", i, fpgaparam.OffsetF[i]); std::this_thread::sleep_for(std::chrono::milliseconds(3)); fpgaComm->setBOffset(i, fpgaparam.OffsetB[i]); // fpgaComm->setBOffset(i, offB[i]); printf("fpgaparam.OffsetB[%d] = %d \n", i, fpgaparam.OffsetB[i]); std::this_thread::sleep_for(std::chrono::milliseconds(3)); fpgaComm->setAGain(i, fpgaparam.GainF[i]); printf("fpgaparam.GainF[%d] = %d \n", i, fpgaparam.GainF[i]); std::this_thread::sleep_for(std::chrono::milliseconds(3)); fpgaComm->setBGain(i, fpgaparam.GainB[i]); printf("fpgaparam.GainB[%d] = %d \n", i, fpgaparam.GainB[i]); std::this_thread::sleep_for(std::chrono::milliseconds(3)); } } void MonoCapturer::openDevice(int dpi, int mode) { // reset_pin->setValue(Gpio::Low); // std::this_thread::sleep_for(std::chrono::milliseconds(50)); // reset_pin->setValue(Gpio::High);a fpgaComm->read(15, m_fpgaversion); int config_dpi = dpi != 3 ? 2 : dpi; int channelwidth = config_dpi == 0x02 ? 1296 : (config_dpi == 0x03 ? 2592 : 864); int channels = mode == 0x01 ? 3 : 1; int width = channelwidth * channels; int dstheight = 200; int fpgaheight = mode == 0x1 ? dstheight / 2 * 3 : dstheight; // 彩色配置fpga 高度要为目标图像高度的3倍 FPGAConfigParam fpgaparam = GetFpgaparam(dpi, mode); printf("fpgaparam.sp=%d exp=%d gain=%d offset=%d LUT=%s", fpgaparam.Sp, fpgaparam.ExposureB[0], fpgaparam.GainB[0], fpgaparam.OffsetB[0], fpgaparam.LutPath.c_str()); // int startsample= cistype.GetCisType()==CISVendor::DUNNAN_CIS_V0?205:262; int startsample = 205; uint tmp_vs = 0; fpgaComm->read(15, tmp_vs); if (tmp_vs == 0x9000c) startsample = 201; else if (tmp_vs >= 0x90002) startsample = 205; else startsample = 208; ModeFpga fpgamod = { .colorMode = mode, .dpi = config_dpi, .led = 1, .sample = startsample, // 256+39 .adcA = 0, .adcB = 0, .selftest = 0, .sp = fpgaparam.Sp}; // 600DPI 0x1450 300DPI 0xe10 fpgaComm->setRegs(0x01, *((int *)(&fpgamod))); fpgaComm->setSample(startsample); fpgaComm->enableLed(true); fpgaComm->setEnTestCol(false); fpgaComm->setEnTestBit(false); if (tmp_vs == 0x9000c) fpgaComm->setVsp(66, 67); else if (tmp_vs != 0x9000a) fpgaComm->setVsp(1, 2); else { // ifstream iF("/home/vspF"); // ifstream iB("/home/vspB"); // int vspF,vspB; // iF >> vspF; // iB >> vspB; // if(vspF ==0 || vspB == 0) // { // vspF = 75; // vspB = 85; // } // printf("!!!!!!!!!!! vspF=%d vspB = %d \n",vspF,vspB); // fpgaComm->setVsp(vspF,vspB); fpgaComm->setVsp(40, 120); } configFPGAParam(mode, dpi); video->open(width, dstheight); // 300dpi 7344/2 600dpi 7344 printf("opened video with width = %d height = %d \n", width, dstheight); fpgaComm->setFrameHeight(12); for (int i = 0; i < 1; i++) { fpgaComm->capture(); // abort first frame video->read_frame(100); std::this_thread::sleep_for(std::chrono::milliseconds(20)); printf("abort first frame \n"); } fpgaComm->setFrameHeight(fpgaheight); } void MonoCapturer::creatcorrectconfig(int dpi, int mode) { openDevice(dpi, mode); bool isDone = false; int i = 1; initStep1(); while (!isDone) // 先暗场 { string log = "==============================第" + to_string(i) + "次==============================="; ft_log.append_log(log); configFPGAParam(mode, dpi); ft_log.append_log(log); fpgaComm->enableLed(false); std::this_thread::sleep_for(std::chrono::milliseconds(3)); fpgaComm->capture(); std::this_thread::sleep_for(std::chrono::milliseconds(3)); isDone = saveLutImg(dpi, mode, true); // 0 color_black 1 color_white 2 gray_balck 3 gray_white i++; } i = 1; isDone = false; initStep1(); while (!isDone) // 后明场 { configFPGAParam(mode, dpi); string log = "==============================第" + to_string(i) + "次==============================="; ft_log.append_log(log); fpgaComm->enableLed(true); std::this_thread::sleep_for(std::chrono::milliseconds(3)); fpgaComm->capture(); std::this_thread::sleep_for(std::chrono::milliseconds(3)); isDone = saveLutImg(dpi, mode, false); i++; } printf("creatcorrectconfig %s \n", (mode == IMAGE_COLOR ? " Color" : " Gray")); // creatLUTData(dpi, mode); video->close(); } static int savelutindex = 0; bool MonoCapturer::saveLutImg(int dpi, int mode, bool black) { int config_dpi = dpi != 3 ? 2 : dpi; int offset_indexs[] = {3, 4, 5, 2, 1, 0, 0, 1, 2, 5, 4, 3}; int channels = mode == IMAGE_COLOR ? 3 : 1; int height = 100; int width = config_dpi == 0x02 ? 1296 : (config_dpi == 0x03 ? 2592 : 864); int orgimgwidth = width * 2 * 3 * channels; int dstwidth = width * 2 * 3; bool isNeedSave = true; string log; void *data = video->read_frame(10000); if (data == NULL) { isNeedSave = false; log = "WARNNING WARNNING WARNNING FAILDED TO READ IMAGE DATA !!!!!!!!!!!!!!!!!!!\r\n"; ft_log.append_log(log); if (m_captureCallback) m_captureCallback(mode, log); return isNeedSave; } cv::Mat src(height, orgimgwidth, CV_8UC1, data); // cv::imwrite(std::to_string(savelutindex++) + ".jpg", src); CImageMerge t_marge; cv::Mat mrgmat = t_marge.MergeImage(mode == 0x01, src, dstwidth, height, m_fpgaversion); mrgmat = mrgmat(cv::Rect(0, 20, mrgmat.cols, mrgmat.rows - 20)); // cv::imwrite(std::to_string(savelutindex++) + "mrg.jpg", mrgmat); // return false; FPGAConfigParam param = GetFpgaparam(dpi, mode); if (black) // 暗场 { double offValues[12]; double offValues_min[12]; std::vector bflags; for (int n = 0; n < 2; n++) { cv::Mat img = mrgmat(cv::Rect(mrgmat.cols * n / 2, 10, mrgmat.cols / 2, mrgmat.rows - 10)).clone(); int offset_total = 0; for (int s = 0; s < 6; s++) // { int k = n * 6 + s; int offset_wdth; if ((k == 5) || (k == 6)) { offset_wdth = config_dpi == 0x03 ? 864 : (config_dpi == 0x02 ? 432 : 288); } else { offset_wdth = config_dpi == 0x03 ? 1296 : (config_dpi == 0x02 ? 648 : 432); } double min, max; // auto t_mat= img(cv::Rect(offset_total, 10, offset_wdth, img.rows - 10)); // cv::minMaxLoc(t_mat,&min,&max); cv::Scalar mean = cv::mean(img(cv::Rect(offset_total, 10, offset_wdth, img.rows - 10))); if (mode) { auto tmp_mat = img(cv::Rect(offset_total, 10, offset_wdth, img.rows - 10)); auto tmp = *std::min_element(tmp_mat.begin(), tmp_mat.end(), [](cv::Vec3b a, cv::Vec3b b) -> bool { return (a[0] + a[1] + a[2]) < (b[0] + b[1] + b[2]); }); offValues_min[k] = (tmp[0] + tmp[1] + tmp[2]) / 3.0; } else { auto tmp_mat = img(cv::Rect(offset_total, 10, offset_wdth, img.rows - 10)); offValues_min[k] = *std::min_element(tmp_mat.begin(), tmp_mat.end(), [](std::uint8_t a, std::uint8_t b) -> bool { return a < b; }); } // printf("AAAAAAAAAAAAAAAAAAAAAAAAAAA min = %.2f max= %.2f mean = %0.2f \n",min,max); offset_total += offset_wdth; offValues[k] = mean.val[0]; bflags.push_back(false); // offValues[k] = min; } } // std::string clrmode = (mode == 0x01 ? "彩色" : " 灰度"); // log = "开始" + clrmode + "暗场校正 \n"; for (int s = 0; s < 2; s++) { int offsets[6]; // = (int *)(s == 0 ? ¶m.OffsetF[0] : ¶m.OffsetB[0]); memcpy(offsets, (s == 0 ? ¶m.OffsetF[0] : ¶m.OffsetB[0]), sizeof(param.OffsetF)); for (volatile int j = 0; j < 6; j++) { int k = s * 6 + j; // double diff = BLACK_DIFF(offValues[k]); double diff = 3 - offValues_min[k]; if (offValues[k] > 25) { diff = 25 - offValues[k]; } // double diff = 3-offValues[k]; double step = radio * diff; int preStep = offsetStep1[k]; printf("offsetStep1[%d]=%d \n", k, offsetStep1[k]); if (step * preStep < 0) { step = 0 - preStep / 2; } else { radio = 1; } if (step < 1 && step > 0) step = 1; if (step < 0 && step > -1) step = -1; // FMT_STEP(step); bool isMinStep = abs(step) == 1 && step == offsetStep1[k]; bool isOutBounds = offsets[j] >= 255 && step > 0; isOutBounds |= offsets[j] <= 0 && step < 0; log += " 暗场校正 :" + std::to_string(k) + ";diff:" + std::to_string(diff) + ";light:" + std::to_string(offValues[k]) + ";offset:" + std::to_string(offsets[j]) + ";step:" + std::to_string(step) + "\r\n"; if (isOutBounds) log += " 第" + std::to_string(k) + "条带暗场校正异常,暗场值无法降低 \r\n"; else if (abs(step) > 1 || isMinStep) { offsetStep1[k] = (int)(step); offsets[offset_indexs[k]] += step; log += "offsetStep1" + std::to_string(k) + " = " + std::to_string(offsetStep1[k]) + ", offset_indexs" + std::to_string(k) + " =" + std::to_string(offset_indexs[k]) + "\r\n"; if (offsets[offset_indexs[k]] < 1) offsets[offset_indexs[k]] = 1; if (offsets[offset_indexs[k]] > 255) offsets[offset_indexs[k]] = 255; // isNeedSave = false; bflags[k] = false; } else { bflags[k] = true; printf("channel[%d] black correct done\n", k); } log += (s == 0 ? "彩色正面" : "彩色背面"); log += "偏移值:" + std::to_string(offsets[0]) + "," + std::to_string(offsets[1]) + "," + std::to_string(offsets[2]) + "," + std::to_string(offsets[3]) + "," + std::to_string(offsets[4]) + "," + std::to_string(offsets[5]) + "\r\n"; // log += (s == 0 ? "彩色正面暗场校正完成 \r\n" : "彩色背面暗场校正完成 \r\n"); ft_log.append_log(log); if (m_captureCallback) m_captureCallback(mode, log); log = ""; } auto siez = sizeof(param.OffsetF); memcpy((s == 0 ? ¶m.OffsetF[0] : ¶m.OffsetB[0]), offsets, sizeof(param.OffsetF)); } for (int i = 0; i < bflags.size(); i++) { if (!bflags[i]) isNeedSave = false; } if (isNeedSave) { printf("Save LUT image path :%s \n", param.Flat_BwPath.c_str()); log = "暗场校正完成 \r\n"; if (m_captureCallback) m_captureCallback(mode, log); // log =""; imwrite(param.Flat_BwPath, mrgmat); } } else // 明场 { if (mode == IMAGE_COLOR) { double values[2][3]; cv::Scalar a = mean(mrgmat(Rect(0, 0, mrgmat.cols / 2, mrgmat.rows))); cv::Scalar b = mean(mrgmat(Rect(mrgmat.cols / 2, 0, mrgmat.cols / 2, mrgmat.rows))); for (int j = 0; j < 3; j++) { values[0][j] = a.val[2 - j]; values[1][j] = b.val[2 - j]; } log = "开始彩色明场校正 \r\n"; if (m_captureCallback) m_captureCallback(mode, log); double coefficient[3] = {1.2, 0.6, 1.2}; for (int s = 0; s < 2; s++) { int exposures[3]; // = (int *)(s == 0 ? param.ExposureF : param.ExposureB); memcpy(exposures, (s == 0 ? ¶m.ExposureF[0] : ¶m.ExposureB[0]), sizeof(param.ExposureB)); for (int x = 0; x < 3; x++) { int k = (3 * s + x); int diff = LIGHT_DIFF(param.MaxBright, *((double *)values + k)); if(x == 0) diff = LIGHT_DIFF(175, *((double *)values + k)); //int diff = LIGHT_DIFF(param.MaxBright,((values[s][0]*coefficient[0]+values[s][1]*coefficient[1]+values[s][2]*coefficient[2])/3.0)); log += " 明场:" + std::to_string(k) + ";diff:" + std::to_string(diff) + "\r\n"; if (abs(diff) > 30) radio = 2; else radio = 1; double step = diff * radio; // double step = diff / coefficient[x]; int preStep = *((int *)expStep + k); if (step * preStep < 0) { step = 0 - preStep / 2; } if (step < 1 && step > 0) step = 1; if (step < 0 && step > -1) step = -1; bool isMinStep = abs(step) == 1 && step == *((int *)expStep + k); bool isOutBounds = exposures[x] >= (param.Sp - 5) && step > 0; isOutBounds |= exposures[x] <= 0 && step < 0; if (isOutBounds) log += " 第" + to_string(x) + "个明场校正异常 \r\n"; else if (abs(diff) >= 1 || isMinStep) { *((int *)expStep + k) = (int)(step); exposures[x] += step; if (exposures[x] > (param.Sp - 5)) { exposures[x] = (param.Sp - 5); } if (exposures[x] < 0) exposures[x] = 0; isNeedSave = false; } log += " 曝光值:" + to_string(exposures[x]) + "\r\n"; log += " 调整步长:" + to_string(*((int *)expStep + k)) + "\r\n"; } memcpy((s == 0 ? ¶m.ExposureF[0] : ¶m.ExposureB[0]), exposures, sizeof(param.ExposureB)); } ft_log.append_log(log); if (m_captureCallback) m_captureCallback(mode, log); if (isNeedSave) { log = "彩色明场校正完成\r\n"; if (m_captureCallback) m_captureCallback(mode, log); // log =""; // imwrite("/home/linaro/"+to_string(dpi)+"color.jpg", mrgmat); imwrite(param.Flat_WhitePath, mrgmat); } } else { double values[2]; values[0] = cv::mean(mrgmat(cv::Rect(0, 0, mrgmat.cols / 2, mrgmat.rows))).val[0]; values[1] = cv::mean(mrgmat(cv::Rect(mrgmat.cols / 2, 0, mrgmat.cols / 2, mrgmat.rows))).val[0]; log = "-----开始灰色明场校正-----\r\n"; log += " 灰色扫描灰度明场均值:" + to_string(values[0]) + "," + to_string(values[1]) + "\r\n"; if (m_captureCallback) m_captureCallback(mode, log); for (int s = 0; s < 2; s++) { int *exposures = (int *)(s == 0 ? param.ExposureF : param.ExposureB); int diff = LIGHT_DIFF(param.MaxBright, values[s]); if (abs(diff) > 30) radio = 2; else radio = 1; double step = diff * radio; log += " 明场:" + to_string(s) + ";diff:" + to_string(diff) + "\r\n"; int preStep = expStep[s][0]; if (step * preStep < 0) { step = 0 - preStep / 2; } else { radio = 1; } if (step < 1 && step > 0) step = 1; if (step < 0 && step > -1) step = -1; int exp = *(exposures + 1); // std::string ss1(string_format("exp[%d] = %d step = %.3f \r\n", s, exp, step)); // log += ss1; bool isMinStep = abs(step) == 1 && step == expStep[s][0]; bool isOutBounds = exp >= (param.Sp - 5) && step > 0; isOutBounds |= exp <= 0 && step < 0; if (isOutBounds) log += " 第" + to_string(s) + "个明场校正异常 \r\n"; else if (abs(diff) > 1 || isMinStep) { exp += step; if (exp < 0) exp = 0; if (exp > (param.Sp - 5)) exp = (param.Sp - 5); // float coffe[3] = {0.8, 1, 1}; // 0.2, 1,0.51 float coffe[3] = {1, 1, 1}; for (int k = 0; k < 3; k++) { *(exposures + k) = (int)(exp * coffe[k]); expStep[s][k] = (int)(step); std::string exps(string_format("expStep[%d][%d] = %.3f\r\n", s, k, step)); log += exps; std::string ss(string_format("exposures[%d] = %0.3f \r\n", k, exposures[k])); log += ss; } isNeedSave = false; } } ft_log.append_log(log); if (m_captureCallback) m_captureCallback(mode, log); if (isNeedSave) { printf("Save LUT image path :%s \n", param.Flat_WhitePath.c_str()); log = "灰度明场校正完成\r\n"; if (m_captureCallback) m_captureCallback(mode, log); log = ""; imwrite(param.Flat_WhitePath, mrgmat); } } } SaveFpgaparam(param); printf("exit Save_lut \n"); return isNeedSave; } void MonoCapturer::correctcolor(int correctmode) { auto _start = std::chrono::steady_clock::now(); ThreadPool pool(2); std::queue> fu_correct; std::string loginfo = "Start Correctcolor 200DPI COLOR \r\n"; if ((correctmode == 0) || (correctmode == 2)) { if (m_captureCallback) m_captureCallback(0x01, loginfo); creatcorrectconfig(0x01, IMAGE_COLOR); auto param = GetFpgaparam(0x01, IMAGE_COLOR); fu_correct.emplace(pool.enqueue([param]() {creatLUTData(0x01,IMAGE_COLOR,param);creatLUTData_gray(0x01,IMAGE_COLOR,param); })); loginfo = "-----------200DPI COLOR Correct Done----------- \r\n\r\n "; if (m_captureCallback) m_captureCallback(0x01, loginfo); } if ((correctmode == 0) || (correctmode == 1)) { loginfo = "Start Correctcolor 200DPI GRAY \r\n"; if (m_captureCallback) m_captureCallback(0x01, loginfo); creatcorrectconfig(0x01, IMAGE_GRAY); auto param = GetFpgaparam(0x01, IMAGE_GRAY); fu_correct.emplace(pool.enqueue([param]() {creatLUTData(0x01,IMAGE_GRAY,param);creatLUTData_gray(0x01,IMAGE_GRAY,param); })); loginfo = "-----------200DPI Gray Correct Done----------- \r\n\r\n "; if (m_captureCallback) m_captureCallback(0x02, loginfo); } if ((correctmode == 0) || (correctmode == 4)) { loginfo = "Start Correctcolor 300DPI COLOR \r\n"; if (m_captureCallback) m_captureCallback(0x01, loginfo); creatcorrectconfig(0x02, IMAGE_COLOR); auto param = GetFpgaparam(0x02, IMAGE_COLOR); fu_correct.emplace(pool.enqueue([param]() {creatLUTData(0x02,IMAGE_COLOR,param);creatLUTData_gray(0x02,IMAGE_COLOR,param); })); loginfo = "-----------300DPI COLOR Correct Done----------- \r\n\r\n "; if (m_captureCallback) m_captureCallback(0x02, loginfo); } if ((correctmode == 0) || (correctmode == 3)) { loginfo = "Start Correctcolor 300DPI GRAY \r\n"; if (m_captureCallback) m_captureCallback(0x01, loginfo); creatcorrectconfig(0x02, IMAGE_GRAY); auto param = GetFpgaparam(0x02, IMAGE_GRAY); fu_correct.emplace(pool.enqueue([param]() {creatLUTData(0x02,IMAGE_GRAY,param);creatLUTData_gray(0x02,IMAGE_GRAY,param); })); loginfo = "-----------300DPI Gray Correct Done----------- \r\n\r\n "; if (m_captureCallback) m_captureCallback(0x03, loginfo); } if ((correctmode == 0) || (correctmode == 6)) { loginfo = "Start Correctcolor 600DPI COLOR \r\n"; if (m_captureCallback) m_captureCallback(0x01, loginfo); creatcorrectconfig(0x03, IMAGE_COLOR); auto param = GetFpgaparam(0x03, IMAGE_COLOR); fu_correct.emplace(pool.enqueue([param]() {creatLUTData(0x03,IMAGE_COLOR,param);creatLUTData_gray(0x03,IMAGE_COLOR,param); })); loginfo = "-----------600DPI COLOR Correct Done----------- \r\n\r\n "; if (m_captureCallback) m_captureCallback(0x03, loginfo); } if ((correctmode == 0) || (correctmode == 5)) { loginfo = "Start Correctcolor 600DPI GRAY \r\n"; if (m_captureCallback) m_captureCallback(0x01, loginfo); creatcorrectconfig(0x03, IMAGE_GRAY); auto param = GetFpgaparam(0x03, IMAGE_GRAY); fu_correct.emplace(pool.enqueue([param]() {creatLUTData(0x03,IMAGE_GRAY,param);creatLUTData_gray(0x03,IMAGE_GRAY,param); })); loginfo = "-----------600DPI Gray Correct Done----------- \r\n\r\n "; if (m_captureCallback) m_captureCallback(0x03, loginfo); } loginfo = "Start Correctcolor slow moire COLOR \r\n"; if (m_captureCallback) m_captureCallback(0x01, loginfo); creatcorrectconfig(0x10, IMAGE_COLOR); auto param = GetFpgaparam(0x10, IMAGE_COLOR); fu_correct.emplace(pool.enqueue([param]() {creatLUTData(0x10,IMAGE_COLOR,param);creatLUTData_gray(0x10,IMAGE_COLOR,param); })); loginfo = "-----------slow moire COLOR Correct Done----------- \r\n\r\n "; if (m_captureCallback) m_captureCallback(0x10, loginfo); loginfo = "Start Correctcolor slow moire GRAY \r\n"; if (m_captureCallback) m_captureCallback(0x01, loginfo); creatcorrectconfig(0x10, IMAGE_GRAY); param = GetFpgaparam(0x10, IMAGE_GRAY); fu_correct.emplace(pool.enqueue([param]() {creatLUTData(0x10,IMAGE_GRAY,param);creatLUTData_gray(0x10,IMAGE_GRAY,param); })); loginfo = "-----------slow moire Gray Correct Done----------- \r\n\r\n "; if (m_captureCallback) m_captureCallback(0x03, loginfo); if ((correctmode < 0) || (correctmode > 6)) { loginfo = "不支持的校正模式...\r\n"; if (m_captureCallback) m_captureCallback(0x03, loginfo); } while (fu_correct.size()) { fu_correct.front().get(); fu_correct.pop(); } loginfo = "******Correct Done****** " + std::to_string(std::chrono::duration(std::chrono::steady_clock::now() - _start).count()) + "s"; if (m_captureCallback) m_captureCallback(0x04, loginfo); } void MonoCapturer::single_correct(std::uint32_t mode) { std::vector sup_correct_dpi{1, 2, 3, 0x10}; union correct_mode_ { struct { uint32_t dpi : 16; uint32_t color_mode : 8; uint32_t correct_mode : 8; } param; uint32_t value; }; correct_mode_ tmp; tmp.value = mode; if (std::count(sup_correct_dpi.begin(), sup_correct_dpi.end(), tmp.param.dpi) && (tmp.param.color_mode < 2)) { auto param = GetFpgaparam(tmp.param.dpi, tmp.param.color_mode); if (tmp.param.correct_mode == 1) creatLUTData(tmp.param.dpi, tmp.param.color_mode, param); else if (tmp.param.correct_mode == 2) creatLUTData_gray(tmp.param.dpi, tmp.param.color_mode, param); } } void MonoCapturer::fpga_reset() { reset_pin->setValue(Gpio::Low); std::this_thread::sleep_for(std::chrono::milliseconds(50)); reset_pin->setValue(Gpio::High); std::this_thread::sleep_for(std::chrono::milliseconds(50)); } void MonoCapturer::fpga_reload() { // fpga 代码重载 fpgaLoad->setValue(Gpio::Low); std::this_thread::sleep_for(std::chrono::milliseconds(15)); fpga_conf_initn->setValue(Gpio::Low); std::this_thread::sleep_for(std::chrono::milliseconds(15)); printf("\n fpga_conf_done value %d", fpga_conf_done->getValue()); fpgaLoad->setValue(Gpio::High); std::this_thread::sleep_for(std::chrono::milliseconds(15)); fpga_conf_initn->setValue(Gpio::High); // std::this_thread::sleep_for(std::chrono::milliseconds(5)); printf("\n fpga_conf_done value %d", fpga_conf_done->getValue()); // while(fpga_conf_done->getValue() == Gpio::GpioLevel::Low) // std::this_thread::sleep_for(std::chrono::milliseconds(5)); std::this_thread::sleep_for(std::chrono::seconds(3)); printf("\n fpga_conf_done value %d", fpga_conf_done->getValue()); fpgaComm->resetADC(); fpgaComm->update(0); } void MonoCapturer::set_fpga_vsp(int a, int b) { fpgaComm->setVsp(a, b); }