#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 "MultiFrameCapture_8478_HL.h" #include "StopWatch.h" #include "linux\sched.h" #include "deviceconfig.h" #define LOG_PATH "/usr/local/correct.log" const uint32_t WIDTH_8478 = 1224; FileTools ftm_cr_log(LOG_PATH); static std::string loggername = "MultiFrameCapture_8478_HL"; static double radio = 1.0; static int offsetStep1[12]; static int expStep1[2][3]; static int org_index = 0; 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]); } } MultiFrameCapture_8478_HL::MultiFrameCapture_8478_HL() : reset_pin(new GpioOut(50)), fpgaLoad(new Gpio(70)), fpga_conf_done(new Gpio(69)), fpga_conf_initn(new Gpio(71)), bcorrecting(false), snapthread(1) { LOG_INIT(); fpga_conf_done->setDirection(Gpio::in); fpgaComm.reset(new FpgaComm()); pimgdata_info = {0}; // fpga_reload(); // fpga_reset(); std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // fpgaComm->resetADC(); // fpgaComm->resetADC(); // fpgaComm->update(); video.reset(new VIDEO_CLASS()); fpgaComm->update(3); // GetFpgaparam(0x01,0); set_ADC_config_frequency(12); init_adc_8478(); snapthread.enqueue([]{ cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(5, &cpuset); pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); }); } MultiFrameCapture_8478_HL::~MultiFrameCapture_8478_HL() { if (video.get()) video.reset(); printf("Exit ~MultiFrameCapture_8478_HL() \n"); } void MultiFrameCapture_8478_HL::open() { } void MultiFrameCapture_8478_HL::open(HGScanConfig config, FPGAConfigParam_8478 fpgaparam) { fpgaComm->update(3); uint32_t reg8 = 0, reg5 = 0, reg12 = 0, reg11 = 0, reg10 = 0, reg2 = 0; fpgaComm->set_8478_type(true); // fpgaComm->read(2,reg2); // fpgaComm->write(2,(reg2&0xffffffe1)|0xc); // adc 配置 频率 set_ADC_config_frequency(12); // init_adc_8478(); printf(" dpi = %d \n", config.g200params.dpi); fpgaComm->read(11, reg11); fpgaComm->write(11, (reg11 & 0xffffffc0) | 0x12); // fpgaComm->write(13,0xdec0000); fpgaComm->write(13, 0xce40000); // 旗标位 18 -27位 // fpgaComm->write(13,0xd680000); fpgaComm->set_cis_type(true); m_config = config; m_fpgaparam = fpgaparam; int dpi = config.g200params.dpi == 0x02 ? 2 : (config.g200params.dpi == 0x03 ? 3 : 1); int mode = config.g200params.color; int phyHeight = paperHeight[(PaperSize)config.g200params.paper]; if(m_gscancap.papertype == 52 || m_gscancap.papertype == 54) phyHeight = m_gscancap.maxszie_sanp_height; int tdpi = config.g200params.dpi == 0x02 ? 300 : (config.g200params.dpi == 0x03 ? 600 : 200); int pixheight = ((int)((phyHeight / 25.4 * tdpi + 2) / 3)) * 3; if (fpgaparam.DpiMode == 0x10) pixheight = pixheight * 180 / 100; if (fpgaparam.DpiMode == 0x11) pixheight = pixheight * 130 / 100; frame_height = 300; frame_count = ceil((mode == 0x01 ? pixheight * 3 : pixheight) / (float)(frame_height)); // 彩色配置fpga 高度要为目标图像高度的3倍 if (frame_height * frame_count > FPGA_MAX_HEIGHT_SUP) frame_count = FPGA_MAX_HEIGHT_SUP / frame_height; fpgaComm->read(15, m_fpgaversion); int startsample = 0; ModeFpga fpgamod = { .colorMode = mode, .dpi = m_config.g200params.dpi, .led = 1, .sample = startsample, // 256+39 .adcA = 0, .adcB = 0, .selftest = 0, .sp = fpgaparam.Sp}; // 600DPI 0x1450 300DPI 0xe10 10138 fpgaComm->setRegs(0x01, *((int *)(&fpgamod))); fpgaComm->setSample(startsample); fpgaComm->enableLed(true); fpgaComm->setEnTestCol(false); fpgaComm->setEnTestBit(false); set_LED_PTN_8478(config.g200params.color == false); set_dpi_mode(config.g200params.dpi); set_pixel_count_8478(fpgaparam.Sp / 3 / (config.g200params.color ? 3 : 1), config.g200params.color == false); configFPGAParam(config.g200params.color, config.g200params.dpi); configFPGAParam_digital_gain(config.g200params.color, config.g200params.dpi); set_exp_8478_single(fpgaparam.ExposureF[0], fpgaparam.ExposureF[1], fpgaparam.ExposureF[2], fpgaparam.Sp / (config.g200params.color ? 3 : 1), true, config.g200params.color); set_exp_8478_single(fpgaparam.ExposureB[0], fpgaparam.ExposureB[1], fpgaparam.ExposureB[2], fpgaparam.Sp / (config.g200params.color ? 3 : 1), false, config.g200params.color); // set_exp_8478_single(1000,1000,1000,fpgaparam.Sp/(config.g200params.color?3:1),true,config.g200params.color); // set_exp_8478_single(1000,1000,1000,fpgaparam.Sp/(config.g200params.color?3:1),false,config.g200params.color); config.g200params.dpi == 3 ? set_EN_postion(0x54, 0x3a0) : set_EN_postion(0x54, 0x1f0); // video->set_buf_count(std::min(frame_count,20u)); video->set_buf_count(std::min(100u,frame_count)); uint32_t video_w = (config.g200params.dpi == 0x03 ? WIDTH_8478 * 2 : WIDTH_8478); if (config.g200params.dpi == 0x01) video_w = video_w * 2 / 3; video->open(video_w, frame_height * 2); fpgaComm->setFrameHeight(frame_height); printf("fpgaComm set height = %d \n", frame_height); fpgaComm->read(8, reg8); // fpgaComm->write(8,reg8|0x100); //行号 enable fpgaComm->write(8, reg8 & 0xfffffeff); // 行号 disable fpgaComm->read(5, reg5); // fpgaComm->write(5,reg5|0x2000); //测试数据 白+黑 enable fpgaComm->write(5, reg5 & 0xffffdfff); // 测试数据 白+黑 disable fpgaComm->read(12, reg12); // fpgaComm->write(12,reg5&0xfffff000+0x97e); //帧间隔延迟 >=22.5us // fpgaComm->write(12,reg5&0xe000e000+0xfa0067e); //帧间隔延迟 >=22.5us // fpgaComm->write(12,0x04e20400); //0x494e491 0x79de496 范围 0-12 16-28 (16-28 > 0-12) fpgaComm->read(10, reg10); fpgaComm->write(12, 0x00200010); // 58us 300*600 多帧 fpgaComm->write(10, 0x0150012a); // 58us 300*600 多帧 fpgaComm->setFrameNum(1); fpgaComm->capture(); // abort first frame video->read_frame(1000); fpgaComm->setFrameNum(frame_count); fpgaComm->update(3); // initLut(fpgaparam.LutPath, config.g200params.color); // initLut(config.g200params.is_textcorrect?fpgaparam.LutPath:fpgaparam.TextLutPath,config.g200params.color); // initLut(fpgaparam.TextLutPath, config.g200params.color); init_lutdate(); // init_imagedatabuffer(); } void MultiFrameCapture_8478_HL::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 == 17) && (gray_.Param_Setting.en_slow_300_clr == 1 && m_config.g200params.color == true)) lutpath = "/usr/local/huago/Graylutslow_moire300clr.bmp"; else if ((m_fpgaparam.DpiMode == 32) && (gray_.Param_Setting.en_long_Manuscript_200_clr == 1 && m_config.g200params.color == true)) lutpath = "/usr/local/huago/GraylutLong_Manuscript200clr.bmp"; else if ((m_fpgaparam.DpiMode == 33) && (gray_.Param_Setting.en_long_Manuscript_300_clr == 1 && m_config.g200params.color == true)) lutpath = "/usr/local/huago/GraylutLong_Manuscript300clr.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"; else if ((m_fpgaparam.DpiMode == 17) && (gray_.Param_Setting.en_slow_300_gray == 1 && m_config.g200params.color == false)) lutpath = "/usr/local/huago/Graylutslow_moire300gray.bmp"; else if ((m_fpgaparam.DpiMode == 32) && (gray_.Param_Setting.en_long_Manuscript_200_gray == 1 && m_config.g200params.color == false)) lutpath = "/usr/local/huago/GraylutLong_Manuscript200gray.bmp"; else if ((m_fpgaparam.DpiMode == 33) && (gray_.Param_Setting.en_long_Manuscript_300_gray == 1 && m_config.g200params.color == false)) lutpath = "/usr/local/huago/GraylutLong_Manuscript300gray.bmp"; initLut(lutpath, m_config.g200params.color); } void MultiFrameCapture_8478_HL::close() { if (video.get()) video->close(); // if(pimgdata_info.pdata) free(pimgdata_info.pdata); // pimgdata_info.pdata = nullptr; pimgdata_info.offset = pimgdata_info.frame_count = pimgdata_info.img_h = pimgdata_info.img_w = 0; printf("pimgdata_ free !!!!!\n"); // fpgaComm->resetADC(); // fpga_reload(); } void MultiFrameCapture_8478_HL::Fpga_regsAccess_reset(bool enable) { if (fpgaComm.get()) fpgaComm->regsAccess_reset(enable); if (enable) { set_ADC_config_frequency(12); init_adc_8478(); } } void MultiFrameCapture_8478_HL::start() { if (video.get()) video->start(); } void MultiFrameCapture_8478_HL::MultiFrameCapture_8478_HL::stop() { if (video.get()) video->stop(); } bool MultiFrameCapture_8478_HL::is_runing() { return false; } // static void printlog(std::string str) // { // std::ofstream o("/root/log.txt",std::ios::app|std::ios::binary); // if(o.is_open()) // { // o << str <capture(); printf("snap start !!!!! \n"); b_stop_snap = false; pimgdata_info.offset = pimgdata_info.frame_count = pimgdata_info.img_h = pimgdata_info.img_w = 0; snap_fu = snapthread.enqueue([this] { auto snap_func = [this](int height,int width, int channels, bool last_frame, unsigned int frame_index) { StopWatch sw; void *data = video->read_frame(500); if (data) { update_imgdatainfo(data,height,width); printf("memcpy date size = %d times = %f index = %d \n",height*width,sw.elapsed_ms(),frame_index); } else { printf("!!!!!!!!!! error read frame losted, i = %d \n", frame_index); //printlog("!!!!!!!!!! error read frame losted"); } }; int width = WIDTH_8478*3*2*(m_config.g200params.dpi == 3 ? 2 : 1)*(m_config.g200params.color ? 3 :1); if(m_config.g200params.dpi == 1) width = width *2/3; int height = frame_height/(m_config.g200params.color ? 3 :1); for (int i = 1; i <= frame_count; i++) { curr_frame_snap_index = i; snap_func(height,width, 0, (i == frame_count), i); if (b_stop_snap) { int snaped_frame_count = fpgaComm->getFrame_counter_val(); printf("!!!!!!!!!! revsed frame count = %d i = %d \n", snaped_frame_count, i); if (snaped_frame_count > i && snaped_frame_count > 0) // 正常情况下 snaped_frame_count 一定大于0 { int reversed_frame_count = snaped_frame_count - i; for (int j = 1; j <= reversed_frame_count; j++) { curr_frame_snap_index =j+i; snap_func(height, width,0, ((i + j) == reversed_frame_count), i + j); } } break; // 跳出当前读取多帧循环 } } printf("snap end !!!!! \n"); }); } void MultiFrameCapture_8478_HL::snap(frame_data_info info) { printf("snap start !!!!! \n"); b_stop_snap = false; info.offset = info.frame_count = info.img_h = info.img_w = 0; snap_fu = snapthread.enqueue([this, info]{ frame_data_info frame_info {0}; frame_info.pdata = info.pdata; frame_info.total = info.total; auto snap_func = [this,&frame_info](int height,int width, int channels, bool last_frame, unsigned int frame_index) { StopWatch sw; void *data = video->read_frame(500); if (data) { update_imgdatainfo(data,frame_info,height,width); printf("memcpy date size = %d times = %f index = %d \n",height*width,sw.elapsed_ms(),frame_index); } else printf("!!!!!!!!!! error read frame losted, i = %d \n", frame_index); }; int width = WIDTH_8478*3*2*(m_config.g200params.dpi == 3 ? 2 : 1)*(m_config.g200params.color ? 3 :1); if(m_config.g200params.dpi == 1) width = width *2/3; int height = frame_height/(m_config.g200params.color ? 3 :1); for (int i = 1; i <= frame_count; i++) { curr_frame_snap_index = i; snap_func(height,width, 0, (i == frame_count), i); if (b_stop_snap) { int snaped_frame_count = fpgaComm->getFrame_counter_val(); printf("!!!!!!!!!! revsed frame count = %d i = %d \n", snaped_frame_count, i); if (snaped_frame_count > i && snaped_frame_count > 0) // 正常情况下 snaped_frame_count 一定大于0 { int reversed_frame_count = snaped_frame_count - i; for (int j = 1; j <= reversed_frame_count; j++) { curr_frame_snap_index = i+j; snap_func(height, width,0, ((i + j) == reversed_frame_count), i + j); } } break; // 跳出当前读取多帧循环 } } pimgdata_info = frame_info; printf("snap end !!!!! \n"); }); } cv::Size MultiFrameCapture_8478_HL::frame_data_size() { return {2 * this->width() * (m_config.g200params.color ? 3 : 1), frame_height / (m_config.g200params.color ? 3 : 1) * frame_count}; } void MultiFrameCapture_8478_HL::stopsnap() { b_stop_snap = true; if(snap_fu.valid()) snap_fu.get(); } int MultiFrameCapture_8478_HL::getautosizeheight() { unsigned int val; unsigned int reg8 = 0; fpgaComm->read(8, reg8); // std::cout << "1 reg[8]:" << string_format("0x%08x", reg8) << std::endl; // fpgaComm->update(4); fpgaComm->read(14, val); int regv = val; val &= 0x0000ffff; // std::cout << string_format("ONE height = %d reg[14] = %d \n", val, regv); // fpgaComm->update(5); fpgaComm->write(8, reg8 & 0xfffffff7); // std::cout << string_format("ONE reg[8] = %d \n", reg8 & 0xfffffff7); std::this_thread::sleep_for(std::chrono::milliseconds(5)); // fpgaComm->update(6); fpgaComm->read(14, val); regv = val; val &= 0x0000ffff; fpgaComm->read(8, reg8); // std::cout << "2 reg[8]:" << string_format("0x%08x", reg8) << std::endl; 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); // fpgaComm->write(8,0x02260008); // fpgaComm->update(7); // fpgaComm->read(8, reg8); // std::cout << "2 reg[8]:" << string_format("0x%08x", reg8) << std::endl; return val; // return fpgaComm->getFrameHeight(); } void MultiFrameCapture_8478_HL::set_size(int width, int height) { if (video.get()) video->set_size(width, height); } void MultiFrameCapture_8478_HL::set_sp(int sp) { fpgaComm->setSp(sp); } void *MultiFrameCapture_8478_HL::readFrame(int timeout) { return video->read_frame(timeout); } cv::Mat MultiFrameCapture_8478_HL::read_one_frame() { fpgaComm->setFrameNum(1); fpgaComm->capture(); void *data = video->read_frame(1000); fpgaComm->setFrameNum(frame_count); if (data) { int width = WIDTH_8478 * 3 * 2 * (m_config.g200params.dpi == 3 ? 2 : 1) * (m_config.g200params.color ? 3 : 1); if (m_config.g200params.dpi == 1) width = width * 2 / 3; int height = frame_height / (m_config.g200params.color ? 3 : 1); cv::Mat mat(height, width, CV_8UC1, data); return merge_8478(mat, m_config.g200params.color, 0); } else return cv::Mat(); } frame_data_info MultiFrameCapture_8478_HL::ReadMultiFrame(int state) { printf(" ReadMultiFrame state : %d \n", state); if (state & 1) b_stop_snap = true; if (snap_fu.valid()) snap_fu.get(); if ((state & 0x2) || (!pimgdata_info.pdata)) return {0}; return pimgdata_info; } void MultiFrameCapture_8478_HL::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 MultiFrameCapture_8478_HL::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 MultiFrameCapture_8478_HL::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 MultiFrameCapture_8478_HL::regs() { return fpgaComm; } void MultiFrameCapture_8478_HL::reset() { fpga_reset(); std::this_thread::sleep_for(std::chrono::milliseconds(1000)); fpgaComm->resetADC(); // fpgaComm->setDelayTime(0X3e8); // fpgaComm->setRegs(0x00, fpgaComm->getRegs(0x00)); // fpgaComm->setRegs(0x01, fpgaComm->getRegs(0x01)); } int MultiFrameCapture_8478_HL::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; uint32_t width = WIDTH_8478 * 3 * (m_config.g200params.dpi == 3 ? 2 : 1); return m_config.g200params.dpi == 1 ? (width * 2 / 3) : width; } int MultiFrameCapture_8478_HL::height() { return fpgaComm->getFrameHeight(); } int MultiFrameCapture_8478_HL::color() { return fpgaComm->getColorMode() ? 16 : 0; } void MultiFrameCapture_8478_HL::init_autocorrect(int colormode) { std::thread t_correctthread = std::thread(&MultiFrameCapture_8478_HL::correctcolor, this, colormode); t_correctthread.detach(); // if(t_correctthread.joinable()) // t_correctthread.join(); } void MultiFrameCapture_8478_HL::configFPGAParam(int mode, int dpi) { printf("dpi = %d mode = %d \n", dpi, mode); FPGAConfigParam_8478 fpgaparam = Get_Static_CorrectParam().GetFpgaparam_8478(dpi, mode); for (int i = 0; i < 9; i++) { set_digital_offset_8478(i, fpgaparam.OffsetF_R[i], true, 0); set_digital_offset_8478(i, fpgaparam.OffsetF_G[i], true, 1); set_digital_offset_8478(i, fpgaparam.OffsetF_B[i], true, 2); set_digital_offset_8478(i, fpgaparam.OffsetB_R[i], false, 0); set_digital_offset_8478(i, fpgaparam.OffsetB_G[i], false, 1); set_digital_offset_8478(i, fpgaparam.OffsetB_B[i], false, 2); printf("\n OffsetF_R[%d] = %d OffsetF_G[%d] = %d OffsetF_B[%d] = %d ", i, fpgaparam.OffsetF_R[i], i, fpgaparam.OffsetF_G[i], i, fpgaparam.OffsetF_B[i]); printf("\n OffsetB_R[%d] = %d OffsetB_G[%d] = %d OffsetB_B[%d] = %d ", i, fpgaparam.OffsetB_R[i], i, fpgaparam.OffsetB_G[i], i, fpgaparam.OffsetB_B[i]); } } void MultiFrameCapture_8478_HL::configFPGAParam_digital_gain(int mode, int dpi) { FPGAConfigParam_8478 fpgaparam = Get_Static_CorrectParam().GetFpgaparam_8478(dpi, mode); for (int i = 0; i < 9; i++) { set_digital_gain_8478(i, fpgaparam.GainF_R[i], true, 0); set_digital_gain_8478(i, fpgaparam.GainF_G[i], true, 1); set_digital_gain_8478(i, fpgaparam.GainF_B[i], true, 2); set_digital_gain_8478(i, fpgaparam.GainB_R[i], false, 0); set_digital_gain_8478(i, fpgaparam.GainB_G[i], false, 1); set_digital_gain_8478(i, fpgaparam.GainB_B[i], false, 2); printf("\n GainF_R[%d] = %d GainF_G[%d] = %d GainF_B[%d] = %d ", i, fpgaparam.GainF_R[i], i, fpgaparam.GainF_G[i], i, fpgaparam.GainF_B[i]); printf("\n GainB_R[%d] = %d GainB_G[%d] = %d GainB_B[%d] = %d ", i, fpgaparam.GainB_R[i], i, fpgaparam.GainB_G[i], i, fpgaparam.GainB_B[i]); } } void MultiFrameCapture_8478_HL::openDevice(int dpi, int mode) { FPGAConfigParam_8478 fpgaparam = Get_Static_CorrectParam().GetFpgaparam_8478(dpi, mode); if (dpi == 0x10 || dpi == 0x20) dpi = 1; if (dpi == 0x11 || dpi == 0x21) dpi = 2; int channelwidth = dpi == 0x02 ? WIDTH_8478 : (dpi == 0x03 ? WIDTH_8478 * 2 : WIDTH_8478 * 2 / 3); int channels = mode == 0x01 ? 3 : 1; int width = channelwidth * channels; fpgaComm->set_8478_type(true); set_ADC_config_frequency(12); init_adc_8478(); uint32_t reg11 = 0, reg8 = 0, reg5 = 0, reg10 = 0, reg12 = 0; fpgaComm->read(11, reg11); fpgaComm->write(11, (reg11 & 0xffffffc0) | 0x12); // fpgaComm->write(13,0xdec0000); fpgaComm->write(13, 0xce40000); // 旗标位 18 -27位 // fpgaComm->write(13,0xd680000); video->set_buf_count(10); fpgaComm->set_cis_type(true); dpi == 3 ? set_EN_postion(0x54, 0x3a0) : set_EN_postion(0x54, 0x1f0); set_LED_PTN_8478(mode == false); set_dpi_mode(dpi); set_pixel_count_8478(fpgaparam.Sp / 3 / (mode ? 3 : 1), mode == false); frame_height = 300; frame_count = 1; // 最后一帧丢帧,多采集一帧防止图像数据缺失 fpgaComm->read(15, m_fpgaversion); int startsample = 0; 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 10138 fpgaComm->setRegs(0x01, *((int *)(&fpgamod))); fpgaComm->setSample(startsample); fpgaComm->enableLed(true); fpgaComm->setEnTestCol(false); fpgaComm->setEnTestBit(false); uint32_t video_w = dpi == 0x03 ? WIDTH_8478 * 2 : (dpi == 1 ? WIDTH_8478 * 2 / 3 : WIDTH_8478); video->open(video_w, frame_height * 2); fpgaComm->setFrameNum(frame_count); fpgaComm->setFrameHeight(frame_height); printf("fpgaComm set height = %d \n", frame_height); fpgaComm->read(8, reg8); // fpgaComm->write(8,reg8|0x100); //行号 enable fpgaComm->write(8, reg8 & 0xfffffeff); // 行号 disable fpgaComm->read(5, reg5); // fpgaComm->write(5,reg5|0x2000); //测试数据 白+黑 enable fpgaComm->write(5, reg5 & 0xffffdfff); // 测试数据 白+黑 disable fpgaComm->read(12, reg12); fpgaComm->read(10, reg10); // if(dpi == 3){ // fpgaComm->write(10,0x03b0037a); //120 us 600*600 多帧 // fpgaComm->write(12,0x02000100); //120 us 600*600 多帧 // } // else { fpgaComm->write(12, 0x00200010); // 58us 300*600 多帧 fpgaComm->write(10, 0x0150012a); // 58us 300*600 多帧 } configFPGAParam(mode, dpi); configFPGAParam_digital_gain(mode,dpi); fpgaComm->update(3); fpgaComm->capture(); // abort first frame for (int i = 0; i < frame_count; i++) video->read_frame(500); } void MultiFrameCapture_8478_HL::creatcorrectconfig(int dpi, int mode) { printf(" opendevice"); openDevice(dpi, mode); printf(" opendevice end "); bool isDone = false; int i = 1; initStep1(); set_led_off(); while (!isDone) // 先暗场 { std::string log = "==============================第" + std::to_string(i) + "次==============================="; ftm_cr_log.append_log(log); configFPGAParam(mode, dpi); configFPGAParam_digital_gain(mode,dpi); ftm_cr_log.append_log(log); 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) // 后明场 { FPGAConfigParam_8478 fpgaparam = Get_Static_CorrectParam().GetFpgaparam_8478(dpi, mode); set_exp_8478_single(fpgaparam.ExposureF[0], fpgaparam.ExposureF[1], fpgaparam.ExposureF[2], fpgaparam.Sp / (mode ? 3 : 1), true, mode); set_exp_8478_single(fpgaparam.ExposureB[0], fpgaparam.ExposureB[1], fpgaparam.ExposureB[2], fpgaparam.Sp / (mode ? 3 : 1), false, mode); std::string log = "==============================第" + std::to_string(i) + "次==============================="; ftm_cr_log.append_log(log); 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 MultiFrameCapture_8478_HL::saveLutImg(int dpi, int mode, bool black) { FPGAConfigParam_8478 param = Get_Static_CorrectParam().GetFpgaparam_8478(dpi, mode); if (dpi == 0x10 || dpi == 0x20) dpi = 1; if (dpi == 0x11 || dpi == 0x21) dpi = 2; int offset_indexs[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8}; int width = WIDTH_8478 * 3 * 2 * (dpi == 3 ? 2 : 1) * (mode ? 3 : 1); if (dpi == 1) width = width * 2 / 3; int height = frame_height / (mode ? 3 : 1); bool isNeedSave = true; std::string log; void *data = video->read_frame(10000); if (data == NULL) { isNeedSave = false; log = "WARNNING WARNNING WARNNING FAILDED TO READ IMAGE DATA !!!!!!!!!!!!!!!!!!!\r\n"; ftm_cr_log.append_log(log); if (m_captureCallback) m_captureCallback(mode, log); return isNeedSave; } cv::Mat src(height, width, 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); cv::Mat mrgmat = merge_8478(src, mode, 0); mrgmat = mrgmat(cv::Rect(0, 10, mrgmat.cols, mrgmat.rows - 20)); // cv::imwrite("correct.bmp",mrgmat); // return false; if (black) // 暗场 { double offValues_R[18]{0}; double offValues_G[18]{0}; double offValues_B[18]{0}; std::vector bflags(2 * 9 * (mode ? 3 : 1), false); for (volatile 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 (volatile int s = 0; s < 9; s++) // { int k = n * 9 + s; int offset_wdth; if ((k == 8) || (k == 17)) offset_wdth = dpi == 0x03 ? 432 : (dpi == 0x02 ? 216 : 144); else offset_wdth = dpi == 0x03 ? 864 : (dpi == 0x02 ? 432 : 288); cv::Scalar mean = cv::mean(img(cv::Rect(offset_total, 10, offset_wdth, img.rows - 10))); if (mode) { offValues_R[k] = mean.val[0]; offValues_G[k] = mean.val[1]; offValues_B[k] = mean.val[2]; // auto tmp_mat = img(cv::Rect(offset_total, 10, offset_wdth, img.rows - 10)); // offValues_R[k] = (*std::min_element(tmp_mat.begin(),tmp_mat.end(), // [](cv::Vec3b a, cv::Vec3b b) -> bool{ return a[0] < b[0]; }))[0]; // offValues_G[k] = (*std::min_element(tmp_mat.begin(),tmp_mat.end(), // [](cv::Vec3b a, cv::Vec3b b) -> bool{ return a[1] < b[1]; }))[1]; // offValues_B[k] = (*std::min_element(tmp_mat.begin(),tmp_mat.end(), // [](cv::Vec3b a, cv::Vec3b b) -> bool{ return a[2] < b[2]; }))[2]; printf("\noffValues[%d] R = %f G = %f B= %f", k, offValues_R[k], offValues_G[k], offValues_B[k]); } else{ offValues_R[k] = offValues_G[k] = offValues_B[k] = mean.val[0]; // auto tmp_mat = img(cv::Rect(offset_total, 10, offset_wdth, img.rows - 10)); // offValues_R[k] = offValues_G[k] = offValues_B[k] = *std::min_element(tmp_mat.begin(), // tmp_mat.end(), [](std::uint8_t a, std::uint8_t b) -> bool{ return a < b; }); printf("\noffValues[%d] = %f", k, offValues_R[k]); } offset_total += offset_wdth; } } // std::string clrmode = (mode == 0x01 ? "彩色" : " 灰度"); // log = "开始" + clrmode + "暗场校正 \n"; for (volatile int s = 0; s < 2; s++) { int offsets_R[9]{0}, offsets_G[9]{0}, offsets_B[9]{0}; // = (int *)(s == 0 ? ¶m.OffsetF[0] : ¶m.OffsetB[0]); memcpy(offsets_R, (s == 0 ? ¶m.OffsetF_R[0] : ¶m.OffsetB_R[0]), sizeof(param.OffsetF_R)); memcpy(offsets_G, (s == 0 ? ¶m.OffsetF_G[0] : ¶m.OffsetB_G[0]), sizeof(param.OffsetF_G)); memcpy(offsets_B, (s == 0 ? ¶m.OffsetF_B[0] : ¶m.OffsetB_B[0]), sizeof(param.OffsetF_B)); if (mode == IMAGE_GRAY) { for (volatile int j = 0; j < 9; j++) { int k = s * 9 + j; double diff = BLACK_DIFF(offValues_R[k]); //double diff = 3 - offValues_R[k]; double step = radio * diff; int preStep = offsetStep1[k]; 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_R[j] >= 512 && step > 0; isOutBounds |= offsets_R[j] <= 0 && step < 0; log += " 暗场校正 :" + std::to_string(k) + ";diff:" + std::to_string(diff) + ";light:" + std::to_string(offValues_R[k]) + ";offset:" + std::to_string(offsets_R[j]) + ";step:" + std::to_string(step) + "\r\n"; if (isOutBounds) log += " 第" + std::to_string(k) + "条带暗场校正异常,暗场值无法降低 \r\n"; //else if (abs(step) > 1 || isMinStep) else if (abs(step) > 1) { offsetStep1[k] = (int)(step); offsets_R[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_R[offset_indexs[k]] < 1) offsets_R[offset_indexs[k]] = 1; if (offsets_R[offset_indexs[k]] > 512) offsets_R[offset_indexs[k]] = 512; // 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_R[0]) + "," + std::to_string(offsets_R[1]) + "," + std::to_string(offsets_R[2]) + "," + std::to_string(offsets_R[3]) + "," + std::to_string(offsets_R[4]) + "," + std::to_string(offsets_R[5]) + "," + std::to_string(offsets_R[6]) + "," + std::to_string(offsets_R[7]) + "," + std::to_string(offsets_R[8]) + "\r\n"; // printf("\n%s",log.c_str()); // log += (s == 0 ? "彩色正面暗场校正完成 \r\n" : "彩色背面暗场校正完成 \r\n"); ftm_cr_log.append_log(log); if (m_captureCallback) m_captureCallback(mode, log); log = ""; } memcpy(offsets_G, offsets_R, sizeof(offsets_R)); memcpy(offsets_B, offsets_R, sizeof(offsets_R)); } else { double offValues[18]{0}; int offsets[9]{0}; for (int color = 0; color < 3; color++) { memcpy(offValues, color == 0 ? offValues_R : (color == 1 ? offValues_G : offValues_B), sizeof(offValues)); memcpy(offsets, color == 0 ? offsets_R : (color == 1 ? offsets_G : offsets_B), sizeof(offsets)); for (volatile int j = 0; j < 9; j++) { int k = s * 9 + j; double diff = BLACK_DIFF(offValues[k]); // double diff = 3 - offValues[k]; double step = radio * diff; int preStep = offsetStep1[k]; 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] >= 512 && 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) else if (abs(step) > 1) { 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]] > 512) offsets[offset_indexs[k]] = 512; // isNeedSave = false; bflags[18 * color + k] = false; } else { bflags[18 * color + 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]) + "," + std::to_string(offsets[6]) + "," + std::to_string(offsets[7]) + "," + std::to_string(offsets[7]) + "\r\n"; // log += (s == 0 ? "彩色正面暗场校正完成 \r\n" : "彩色背面暗场校正完成 \r\n"); // printf("\n%s",log.c_str()); ftm_cr_log.append_log(log); if (m_captureCallback) m_captureCallback(mode, log); log = ""; } memcpy(color == 0 ? offValues_R : (color == 1 ? offValues_G : offValues_B), offValues, sizeof(offValues)); memcpy(color == 0 ? offsets_R : (color == 1 ? offsets_G : offsets_B), offsets, sizeof(offsets)); } } memcpy((s == 0 ? ¶m.OffsetF_R[0] : ¶m.OffsetB_R[0]), offsets_R, sizeof(param.OffsetF_R)); memcpy((s == 0 ? ¶m.OffsetF_G[0] : ¶m.OffsetB_G[0]), offsets_G, sizeof(param.OffsetF_G)); memcpy((s == 0 ? ¶m.OffsetF_B[0] : ¶m.OffsetB_B[0]), offsets_B, sizeof(param.OffsetF_B)); } for (int i = 0; i < bflags.size(); i++) { if (!bflags[i]) isNeedSave = false; printf(" b_flags [%d] = %s ",i,bflags[i]?"true":"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 // 明场 { radio = 1.0; if (mode == IMAGE_COLOR) { double values[2][3]; cv::Scalar a = cv::mean(mrgmat(cv::Rect(0, 0, mrgmat.cols / 2, mrgmat.rows))); cv::Scalar b = cv::mean(mrgmat(cv::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]; } printf("\n mean F_R = %f F_G = %f F_B = %f B_R = %f B_G = %f B_B = %f ", values[0][0], values[0][1], values[0][2], values[1][0], values[1][1], values[1][2]); log = "开始彩色明场校正 \r\n"; if (m_captureCallback) m_captureCallback(mode, log); 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)); 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; 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 / 3 / (mode ? 3 : 1) - 15) && step > 0; isOutBounds |= exposures[x] <= 0 && step < 0; if (isOutBounds) log += " 第" + std::to_string(x) + "个明场校正异常 \r\n"; else if (abs(diff) >= 1 || isMinStep) { *((int *)expStep + k) = (int)(step); exposures[x] += step; if (exposures[x] > (param.Sp / 3 / (mode ? 3 : 1) - 15)) { exposures[x] = (param.Sp / 3 / (mode ? 3 : 1) - 15); } if (exposures[x] <= 0) exposures[x] = 1; isNeedSave = false; } log += " 曝光值:" + std::to_string(exposures[x]) + "\r\n"; log += " 调整步长:" + std::to_string(*((int *)expStep + k)) + "\r\n"; } memcpy((s == 0 ? ¶m.ExposureF[0] : ¶m.ExposureB[0]), exposures, sizeof(param.ExposureB)); } printf("\n%s", log.c_str()); ftm_cr_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(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 += " 灰色扫描灰度明场均值:" + std::to_string(values[0]) + "," + std::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 += " 明场:" + std::to_string(s) + ";diff:" + std::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 / 3 / (mode ? 3 : 1) - 15) && step > 0; isOutBounds |= exp <= 0 && step < 0; if (isOutBounds) log += " 第" + std::to_string(s) + "个明场校正异常 \r\n"; else if (abs(diff) > 1 || isMinStep) { exp += step; if (exp < 0) exp = 0; if (exp > (param.Sp / 3 / (mode ? 3 : 1) - 15)) exp = param.Sp / 3 / (mode ? 3 : 1) - 15; float coffe[3] = {1, 1, 1}; // 0.2, 1,0.51 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; } } printf("\n%s", log.c_str()); ftm_cr_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); } } } Get_Static_CorrectParam().SaveCorrectParam(param); printf("exit Save_lut \n"); return isNeedSave; } void MultiFrameCapture_8478_HL::correctcolor(int correctmode) { printf(" correctcolor start mode = %d \n", correctmode); auto _start = std::chrono::steady_clock::now(); std::map> mode = {{1, {1, 0}}, {2, {1, 1}}, {3, {2, 0}}, {4, {2, 1}}, {5, {3, 0}}, {6, {3, 1}}, {7, {16, 0}}, {8, {16, 1}}, {9, {17, 0}}, {10, {17, 1}},{11,{32,1}},{12,{32,0}},{13,{33,1}},{14,{33,0}}}; ThreadPool pool(2); std::queue> fu_correct; std::string loginfo = "Start Correctcolor \r\n"; if (m_captureCallback) m_captureCallback(0x01, loginfo); if (correctmode != 0) { creatcorrectconfig(mode[correctmode].first, mode[correctmode].second); auto param = Get_Static_CorrectParam().GetFpgaparam_8478(mode[correctmode].first, mode[correctmode].second); fu_correct.emplace(pool.enqueue([param](int dpi, int color) { creatLUTData(dpi, color, param); }, mode[correctmode].first, mode[correctmode].second)); } else { for (auto node : mode) { creatcorrectconfig(node.second.first, node.second.second); auto param = Get_Static_CorrectParam().GetFpgaparam_8478(node.second.first, node.second.second); fu_correct.emplace(pool.enqueue([param](int dpi, int color) { creatLUTData(dpi, color, param); }, node.second.first, node.second.second)); } } while (fu_correct.size()) { fu_correct.front().get(); fu_correct.pop(); } loginfo = "******Correct Done****** time " + std::to_string(std::chrono::duration(std::chrono::steady_clock::now() - _start).count()) + "s"; if (m_captureCallback) m_captureCallback(0x04, loginfo); } void MultiFrameCapture_8478_HL::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 MultiFrameCapture_8478_HL::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 MultiFrameCapture_8478_HL::init_imagedatabuffer() { if (pimgdata_info.pdata) free(pimgdata_info.pdata); pimgdata_info.pdata = nullptr; pimgdata_info.offset = pimgdata_info.frame_count = pimgdata_info.img_h = pimgdata_info.img_w = 0; if (frame_count != 0) { int t_frame_count = fpgaComm->getFrameNum(); int width = this->width() * (m_config.g200params.color ? 3 : 1); int height = frame_height * 2; pimgdata_info.pdata = malloc(height * t_frame_count * width); pimgdata_info.total = height * t_frame_count; pimgdata_info.offset = 0; pimgdata_info.frame_count = 0; pimgdata_info.img_h = 0; pimgdata_info.img_w = 0; printf("pimgdata_info.pdata = %p malloc_size = %d \n", pimgdata_info.pdata, height * t_frame_count * width, t_frame_count, width, height); } } void MultiFrameCapture_8478_HL::free_imagedatabuffer() { if (pimgdata_info.pdata) free(pimgdata_info.pdata); pimgdata_info.pdata = nullptr; printf("--- free imagedatabuf --- \n"); } // static void neon_memcpy(volatile void *dst, volatile void *src, int sz) // { // if (sz & 63) // sz = (sz & -64) + 64; // asm volatile ( // "NEONCopyPLD: \n" // " VLDM %[src]!,{d0-d7} \n" // " VSTM %[dst]!,{d0-d7} \n" // " SUBS %[sz],%[sz],#0x40 \n" // " BGT NEONCopyPLD \n" // : [dst]"+r"(dst), [src]"+r"(src), [sz]"+r"(sz) : : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "cc", "memory"); // } void MultiFrameCapture_8478_HL::update_imgdatainfo(void *itemmat, frame_data_info &info, uint32_t h, uint32_t w) { // StopWatch sw; if (info.pdata && itemmat) { // neon_memcpy(pimgdata_info.pdata + pimgdata_info.offset,itemmat,h*w); memcpy(info.pdata + info.offset, itemmat, h * w); info.offset += h * w; info.frame_count++; info.img_h += h; info.img_w = w; // printf("offset = %d item_total = %d \n", pimgdata_info.offset,pimgdata_info.frame_count); } // printf("size = %d frame memcpy time = %fms \n", h*w,sw.elapsed_ms()); } void MultiFrameCapture_8478_HL::update_imgdatainfo(void *itemmat, uint32_t h, uint32_t w) { if (pimgdata_info.pdata && itemmat) { memcpy(pimgdata_info.pdata + pimgdata_info.offset, itemmat, h * w); pimgdata_info.offset += h * w; pimgdata_info.frame_count++; pimgdata_info.img_h += h; pimgdata_info.img_w = w; } } void MultiFrameCapture_8478_HL::init_adc_8478() { // std::this_thread::sleep_for(std::chrono::milliseconds(100)); for (int bank = 0; bank < 4; bank++) for (int i = 1; i < 64; i++) { write_adc_8478(bank_change[bank], i, bank_value[i + 64 * bank], 1); write_adc_8478(bank_change[bank], i, bank_value[i + 64 * bank], 0); } // std::this_thread::sleep_for(std::chrono::milliseconds(100)); } void MultiFrameCapture_8478_HL::write_adc_8478(int bank, int addr, int val, bool A_or_B) { uint32_t reg5 = 0; fpgaComm->read(5, reg5); fpgaComm->write(5, reg5 | 0xc000); // adc 配置使能打开 // std::this_thread::sleep_for(std::chrono::milliseconds(1)); adc_8478_param p_adc{0}; p_adc.param.r_or_w_h = p_adc.param.r_or_w_l = 0; p_adc.param.addr_l = 0; p_adc.param.addr_h = addr; p_adc.param.val_l = bank; p_adc.param.val_h = val; fpgaComm->write(A_or_B ? 4 : 7, p_adc.value); uint32_t reg1_v; fpgaComm->read(1, reg1_v); Mode_FPGA reg1 = *((Mode_FPGA *)®1_v); A_or_B ? reg1.adcA = 1 : reg1.adcB = 1; fpgaComm->write(1, *((uint32_t *)®1)); A_or_B ? reg1.adcA = 0 : reg1.adcB = 0; fpgaComm->write(1, *((uint32_t *)®1)); // std::this_thread::sleep_for(std::chrono::microseconds(100)); fpgaComm->write(5, reg5 & 0xffff3fff); // adc 配置使能关闭 } uint32_t MultiFrameCapture_8478_HL::read_adc_8478(int bank, int addr, bool A_or_B) { uint32_t reg5 = 0; fpgaComm->read(5, reg5); fpgaComm->write(5, reg5 | 0xc000); // adc 配置使能打开 std::this_thread::sleep_for(std::chrono::milliseconds(1)); adc_8478_param p_adc{0}; p_adc.param.r_or_w_h = 0; p_adc.param.r_or_w_l = 2; p_adc.param.addr_l = 0; p_adc.param.addr_h = addr; p_adc.param.val_l = bank; p_adc.param.val_h = 0; fpgaComm->write(A_or_B ? 4 : 7, p_adc.value); uint32_t reg1_v; fpgaComm->read(1, reg1_v); Mode_FPGA reg1 = *((Mode_FPGA *)®1_v); A_or_B ? reg1.adcA = 1 : reg1.adcB = 1; fpgaComm->write(1, *((uint32_t *)®1)); A_or_B ? reg1.adcA = 0 : reg1.adcB = 0; fpgaComm->write(1, *((uint32_t *)®1)); std::this_thread::sleep_for(std::chrono::milliseconds(1)); fpgaComm->write(5, reg5 & 0xffff3fff); // adc 配置使能关闭 uint32_t read_reg = 0; fpgaComm->read(3, read_reg); return read_reg; } void MultiFrameCapture_8478_HL::set_exp_8478_single(int exp_r, int exp_g, int exp_b, int sp, bool A_or_B, bool is_gray) { int pix_counter = sp / 3 - 10; // set_pixel_count_8478(pix_counter,is_gray); int exp_max = pix_counter - 10; if (exp_r > exp_max) exp_r = exp_max; if (exp_g > exp_max) exp_g = exp_max; if (exp_b > exp_max) exp_b = exp_max; write_adc_8478(bank_change[1], 0x7, 0, A_or_B); // exp R start write_adc_8478(bank_change[1], 0x8, 0x35, A_or_B); write_adc_8478(bank_change[1], 0x9, (exp_r & 0x7f00) / 0x100, A_or_B); // exp R end write_adc_8478(bank_change[1], 0xa, exp_r & 0xff, A_or_B); write_adc_8478(bank_change[1], 0xe, 0, A_or_B); // exp G start write_adc_8478(bank_change[1], 0xf, 0x35, A_or_B); write_adc_8478(bank_change[1], 0x10, (exp_g & 0x7f00) / 0x100, A_or_B); // exp G end write_adc_8478(bank_change[1], 0x11, exp_g & 0xff, A_or_B); write_adc_8478(bank_change[1], 0x15, 0, A_or_B); // exp B start write_adc_8478(bank_change[1], 0x16, 0x35, A_or_B); write_adc_8478(bank_change[1], 0x17, (exp_b & 0x7f00) / 0x100, A_or_B); // exp B end write_adc_8478(bank_change[1], 0x18, exp_b & 0xff, A_or_B); } void MultiFrameCapture_8478_HL::set_led_off() { for (int i = 0; i < 2; i++) { write_adc_8478(bank_change[1], 0x7, 0, i); // exp R start write_adc_8478(bank_change[1], 0x8, 0, i); write_adc_8478(bank_change[1], 0x9, 0, i); // exp R end write_adc_8478(bank_change[1], 0xa, 0, i); write_adc_8478(bank_change[1], 0xe, 0, i); // exp G start write_adc_8478(bank_change[1], 0xf, 0, i); write_adc_8478(bank_change[1], 0x10, 0, i); // exp G end write_adc_8478(bank_change[1], 0x11, 0, i); write_adc_8478(bank_change[1], 0x15, 0, i); // exp B start write_adc_8478(bank_change[1], 0x16, 0, i); write_adc_8478(bank_change[1], 0x17, 0, i); // exp B end write_adc_8478(bank_change[1], 0x18, 0, i); } } void MultiFrameCapture_8478_HL::set_pixel_count_8478(int val, bool is_gray) { val = val - 10; fpgaComm->write(21, ((val & 0xffff) * 0x10000) * 3 + (val & 0xffff) * 3); fpgaComm->write(19, ((val & 0xffff) * 0x10000) * 3 + (val & 0xffff) * 3); write_adc_8478(bank_change[1], 1, (val & 0x7f00) / 0x100, true); // count0 -A write_adc_8478(bank_change[1], 2, val & 0xff, true); write_adc_8478(bank_change[1], 1, (val & 0x7f00) / 0x100, false); // count0 -B write_adc_8478(bank_change[1], 2, val & 0xff, false); if (is_gray) return; write_adc_8478(bank_change[1], 3, (val & 0x7f00) / 0x100, true); // count1 -A write_adc_8478(bank_change[1], 4, val & 0xff, true); write_adc_8478(bank_change[1], 3, (val & 0x7f00) / 0x100, false); // count1 -B write_adc_8478(bank_change[1], 4, val & 0xff, false); write_adc_8478(bank_change[1], 5, (val & 0x7f00) / 0x100, true); // count2 -A write_adc_8478(bank_change[1], 6, val & 0xff, true); write_adc_8478(bank_change[1], 5, (val & 0x7f00) / 0x100, false); // count2 -B write_adc_8478(bank_change[1], 6, val & 0xff, false); } void MultiFrameCapture_8478_HL::set_digital_offset_8478(int channel, int val, bool A_or_B, int color) { if (channel < 0 || channel > 8) return; if (color < 0 || color > 2) return; int s_addr = ((color == 0) ? 7 : ((color == 2) ? 1 : 0x1c)); int bank = color == 0 ? 0 : 3; val = val & 0x1ff; write_adc_8478(bank_change[bank], s_addr + channel * 2, val < 255 ? 1 : 0, A_or_B); write_adc_8478(bank_change[bank], s_addr + 1 + channel * 2, val & 0xff, A_or_B); } void MultiFrameCapture_8478_HL::set_digital_gain_8478(int channel, uint8_t val, bool A_or_B, int color) { if (channel < 0 || channel > 8) return; if (color < 0 || color > 2) return; int s_addr = ((color == 0) ? 0x19 : ((color == 2) ? 0x13 : 0x2e)); int bank = color == 0 ? 0 : 3; write_adc_8478(bank_change[bank], s_addr + channel, val, A_or_B); } void MultiFrameCapture_8478_HL::set_dpi_mode(int type) { write_adc_8478(bank_change[1], 0x38, 0x30, true); write_adc_8478(bank_change[1], 0x38, 0x30, false); int val = 0; if(type == 1) val = 3; if(type == 2) val = 0; if(type == 3) val = 1; write_adc_8478(bank_change[0], 0x33, val, true); write_adc_8478(bank_change[0], 0x33, val, false); } void MultiFrameCapture_8478_HL::set_BOS_postion(uint32_t rise, uint32_t fall) { write_adc_8478(bank_change[2], 0x1, (rise & 0xff00) / 0x100, true); // A面 BOS 起始位置 write_adc_8478(bank_change[2], 0x2, rise & 0xff, true); write_adc_8478(bank_change[2], 0x3, (fall & 0xff00) / 0x100, true); // A面 BOS 结束位置 write_adc_8478(bank_change[2], 0x4, fall & 0xff, true); write_adc_8478(bank_change[2], 0x1, (rise & 0xff00) / 0x100, false); // B面 BOS 起始位置 write_adc_8478(bank_change[2], 0x2, rise & 0xff, false); write_adc_8478(bank_change[2], 0x3, (fall & 0xff00) / 0x100, false); // B面 BOS 结束位置 write_adc_8478(bank_change[2], 0x4, fall & 0xff, false); } void MultiFrameCapture_8478_HL::set_EN_postion(uint32_t rise, uint32_t fall) { write_adc_8478(bank_change[2], 0xd, (rise & 0xff00) / 0x100, true); // A面 EN 起始位置 write_adc_8478(bank_change[2], 0xe, rise & 0xff, true); write_adc_8478(bank_change[2], 0xf, (fall & 0xff00) / 0x100, true); // A面 EN 结束位置 write_adc_8478(bank_change[2], 0x10, fall & 0xff, true); write_adc_8478(bank_change[2], 0xd, (rise & 0xff00) / 0x100, false); // B面 EN 起始位置 write_adc_8478(bank_change[2], 0xe, rise & 0xff, false); write_adc_8478(bank_change[2], 0xf, (fall & 0xff00) / 0x100, false); // B面 EN 结束位置 write_adc_8478(bank_change[2], 0x10, fall & 0xff, false); } void MultiFrameCapture_8478_HL::set_7864A_current_ctrl(uint32_t current) { if (current > 6) return; write_adc_8478(bank_change[2], 0x1a, current * 0x10 + current, false); write_adc_8478(bank_change[2], 0x1b, current * 0x10 + current, false); write_adc_8478(bank_change[2], 0x1c, current * 0x10 + current, false); write_adc_8478(bank_change[2], 0x1a, current * 0x10 + current, true); write_adc_8478(bank_change[2], 0x1b, current * 0x10 + current, true); write_adc_8478(bank_change[2], 0x1c, current * 0x10 + current, true); } void MultiFrameCapture_8478_HL::set_LED_PTN_8478(bool is_bw) { if (is_bw) { write_adc_8478(bank_change[0], 0x3d, 0x01, false); write_adc_8478(bank_change[0], 0x3d, 0x01, true); return; } write_adc_8478(bank_change[0], 0x3d, 0x11, false); write_adc_8478(bank_change[0], 0x3d, 0x11, true); } void MultiFrameCapture_8478_HL::set_ADC_config_frequency(uint32_t freq) { uint32_t reg2 = 0; fpgaComm->read(2, reg2); fpgaComm->write(2, (reg2 & 0xffffffe1) | (freq << 1)); // adc 配置 频率 } void MultiFrameCapture_8478_HL::set_cis_type_hl(bool is_hl) { uint32_t reg2 = 0; fpgaComm->read(2, reg2); fpgaComm->write(2, (reg2 & 0xffffffdf) | (is_hl ? 0x20: 0x0)); // 设置CIS类型 华菱 } cv::Mat MultiFrameCapture_8478_HL::merge_8478(cv::Mat src, bool color, uint32_t version) { if (!color) return src; cv::Mat dst(src.rows, src.cols / 3, CV_8UC3); uint32_t width = src.cols / 6; cv::insertChannel(src(cv::Rect(0, 0, src.cols / 6, src.rows)), dst(cv::Rect(0, 0, dst.cols / 2, dst.rows)), 0); cv::insertChannel(src(cv::Rect(src.cols / 3, 0, src.cols / 6, src.rows)), dst(cv::Rect(0, 0, dst.cols / 2, dst.rows)), 2); cv::insertChannel(src(cv::Rect(src.cols / 3 * 2, 0, src.cols / 6, src.rows)), dst(cv::Rect(0, 0, dst.cols / 2, dst.rows)), 1); cv::insertChannel(src(cv::Rect(src.cols / 6, 0, src.cols / 6, src.rows)), dst(cv::Rect(dst.cols / 2, 0, dst.cols / 2, dst.rows)), 0); cv::insertChannel(src(cv::Rect(src.cols / 6 * 3, 0, src.cols / 6, src.rows)), dst(cv::Rect(dst.cols / 2, 0, dst.cols / 2, dst.rows)), 2); cv::insertChannel(src(cv::Rect(src.cols / 6 * 5, 0, src.cols / 6, src.rows)), dst(cv::Rect(dst.cols / 2, 0, dst.cols / 2, dst.rows)), 1); return dst; } void MultiFrameCapture_8478_HL::single_correct(std::uint32_t mode) { std::vector sup_correct_dpi{1, 2, 3, 0x10, 0x11,0x20,0x21}; 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 = Get_Static_CorrectParam().GetFpgaparam_8478(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); } }