#include "Capturer.h" #include "DevUtil.h" #include #include #include #include "Gpio.h" #include "FpgaComm.h" #include "gvideoisp1.h" #include "config.h" #include #include #include "applog.h" #include "stringex.hpp" #include #include #include "filetools.h" using namespace std; #define LOG_PATH "/usr/local/correct.log" FileTools ft(LOG_PATH); static std::string loggername = "Capturer"; bool isAutoCorrect = true; int offsetStep[12]; int expStep[2][3]; double radio = 1; cv::Mat mBuffMat; cv::Mat out; #define LIGHT_DIFF(maxthre, x) ((maxthre)-x) #define BLACK_DIFF(x) (10 - x) #define FMT_STEP(x) \ do \ { \ if (x < 1 && x > 0) \ { \ x = 1; \ } \ if (step < 0 && step > -1) \ { \ x = -1; \ } \ } while (0) void initStep() { for (int i = 0; i < 12; i++) { offsetStep[i] = 256; } for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { expStep[i][j] = 1200; } } } //设置一面的offset值 void setOffset(int *config, int step) { for (int i = 0; i < 6; i++) { int *offset = config + i; *offset += step; if (*offset < 0) *offset = 1; if (*offset > 255) *offset = 255; } } Capturer::Capturer() : vdd_cis_3voff_pin(new GpioOut(CIS_3v3_Off)), vdd_vis_5ven_pin(new GpioOut(CIS_5v_En)), reset_pin(new GpioOut(Fpga_Reset)), 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) { LOG_INIT(); fpgaComm.reset(new FpgaComm()); fpga_reset(); fpgaComm->resetADC(); fpgaComm->setDelayTime(0X3e8); video.reset(new VIDEO_CLASS()); } Capturer::~Capturer() { } void Capturer::Fpga_regsAccess_reset(bool enable){ if(fpgaComm.get()) fpgaComm->regsAccess_reset(enable); } void Capturer::open() { cisconfigs = getcisparams(); int height = 6000; set_sp(0x0208); fpgaComm->setColorMode(1); // int height = 2000; // set_sp(0x0bf0); // fpgaComm->setColorMode(0); fpgaComm->setDpi(1); fpgaComm->setSample(256); fpgaComm->enableLed(true); //设置曝光值等 int exp[2][3]; int gains[2][6]; int offsets[2][6]; for (int i = 0; i < 3; i++) set_expo(i, 0x300); //0x1b0); for (int i = 0; i < 2; i++) { set_gain(i, 300); set_offset(i, 150); } fpgaComm->setFrameHeight(12); std::this_thread::sleep_for(std::chrono::milliseconds(1)); fpgaComm->capture(); std::this_thread::sleep_for(std::chrono::milliseconds(10)); video.reset(new VIDEO_CLASS()); video->open(1632, height); fpgaComm->setFrameHeight(12); for (int i = 0; i < 1; i++) { fpgaComm->capture(); std::this_thread::sleep_for(std::chrono::milliseconds(20)); } fpgaComm->setFrameHeight(height); } static int val = 0; static double exp_ratio = 0.1; void Capturer::open(HGScanConfig config) { if (val > 4000) val = 0; if (exp_ratio > 2.0) exp_ratio = 0.1; cisconfigs = getcisparams(); auto hgsize = papersMap[(PaperSize)config.g200params.paper]; int height = hgsize.height; fpgaComm->setColorMode(config.g200params.color ? 1 : 0); auto info = jsonconfig().getscannerinfo(); //set_sp(config.g200params.color ? cisconfigs.color.sp : cisconfigs.gray.sp); //0x03fa : 0x0bf0 int clrsp, graysp; // if (scannerSp.count((SpeedMode)info.speedmode) <= 0) // { // #ifdef G200 // clrsp = scannerSp[SpeedMode::PPM100].colorSp; // graysp = scannerSp[SpeedMode::PPM100].colorSp; // #else // clrsp = scannerSp[SpeedMode::PPM70].colorSp; // graysp = scannerSp[SpeedMode::PPM70].colorSp; // #endif // } // else // { // clrsp = scannerSp[(SpeedMode)info.speedmode].colorSp; // graysp = scannerSp[(SpeedMode)info.speedmode].colorSp; // } clrsp=info.color_sp; graysp = info.gray_sp; set_sp(config.g200params.color ? clrsp : graysp); HG_LOG("\n capture color sp =%d, gray sp =%d",clrsp,graysp); //set_sp(config.g200params.color ? 0x335 : 0x99f); //G100 0x438 0xca8 60 ppm 0x335 : 0x99f 100ppm //G200 SP极限值205 0x27c 0x775 140ppm //fpgaComm->setDpi(config.g200params.dpi); //0 300dpi 1 200dpi fpgaComm->setDpi(1); fpgaComm->setSample(256); fpgaComm->enableLed(true); //设置曝光值等 configFPGAParam(false, config.g200params.color); //fpgaComm->setFrameHeight(12); //std::this_thread::sleep_for(std::chrono::milliseconds(1)); //fpgaComm->capture(); std::this_thread::sleep_for(std::chrono::milliseconds(10)); video->open(1632, config.g200params.color ? height : height / 3); fpgaComm->setFrameHeight(12); for (int i = 0; i < 1; i++) { fpgaComm->capture(); std::this_thread::sleep_for(std::chrono::milliseconds(20)); } fpgaComm->setFrameHeight(config.g200params.color ? height : height / 3); //fpgaComm->update(); } void Capturer::close() { if (video) { video->close(); } fpga_reload(); } void Capturer::start() { if (video) video->start(); } void Capturer::stop() { if (video) video->stop(); } void Capturer::reset() { fpga_reset(); fpgaComm->resetADC(); fpgaComm->setDelayTime(0X3e8); fpgaComm->setRegs(0x00, fpgaComm->getRegs(0x00)); fpgaComm->setRegs(0x01, fpgaComm->getRegs(0x01)); } void Capturer::set_size(int width, int height) { if (video) video->set_size(width, height); } void Capturer::snap() { fpgaComm->capture(); } std::shared_ptr Capturer::regs() { return fpgaComm; } void Capturer::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 Capturer::fpga_reload() // { // //fpga 代码重载 // fpgaLoad->setValue(Gpio::Low); // std::this_thread::sleep_for(std::chrono::milliseconds(15)); // fpgaLoad->setValue(Gpio::High); // std::this_thread::sleep_for(std::chrono::milliseconds(15)); // fpgaComm->resetADC(); // } void Capturer::set_expo(int ix, int val) { switch (ix) { case 0: fpgaComm->setAExposureB(val); break; case 1: fpgaComm->setAExposureG(val); //!< ok break; case 2: fpgaComm->setAExposureR(val); //!< ok break; case 3: fpgaComm->setBExposureB(val); break; case 4: fpgaComm->setBExposureG(val); break; case 5: fpgaComm->setBExposureR(val); break; default: break; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); } void Capturer::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 Capturer::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 Capturer::configFPGAParam(bool iscorrect, int mode) { int exposures[2][3]; int gains[2][6]; int offsets[2][6]; if (iscorrect) { memcpy(&exposures[0][0], mode == IMAGE_COLOR ? cisconfigs.colorCorrect.expF : cisconfigs.grayCorrect.expF, sizeof(int) * 3); memcpy(&exposures[1][0], mode == IMAGE_COLOR ? cisconfigs.colorCorrect.expB : cisconfigs.grayCorrect.expB, sizeof(int) * 3); memcpy(&gains[0][0], mode == IMAGE_COLOR ? cisconfigs.colorCorrect.gainF : cisconfigs.grayCorrect.gainF, sizeof(int) * 6); memcpy(&gains[1][0], mode == IMAGE_COLOR ? cisconfigs.colorCorrect.gainB : cisconfigs.grayCorrect.gainB, sizeof(int) * 6); memcpy(&offsets[0][0], mode == IMAGE_COLOR ? cisconfigs.colorCorrect.offsetsF : cisconfigs.grayCorrect.offsetsF, sizeof(int) * 6); memcpy(&offsets[1][0], mode == IMAGE_COLOR ? cisconfigs.colorCorrect.offsetsB : cisconfigs.grayCorrect.offsetsB, sizeof(int) * 6); } else { memcpy(&exposures[0][0], mode == IMAGE_COLOR ? cisconfigs.color.expF : cisconfigs.gray.expF, sizeof(int) * 3); memcpy(&exposures[1][0], mode == IMAGE_COLOR ? cisconfigs.color.expB : cisconfigs.gray.expB, sizeof(int) * 3); memcpy(&gains[0][0], mode == IMAGE_COLOR ? cisconfigs.color.gainF : cisconfigs.gray.gainF, sizeof(int) * 6); memcpy(&gains[1][0], mode == IMAGE_COLOR ? cisconfigs.color.gainB : cisconfigs.gray.gainB, sizeof(int) * 6); memcpy(&offsets[0][0], mode == IMAGE_COLOR ? cisconfigs.color.offsetsF : cisconfigs.gray.offsetsF, sizeof(int) * 6); memcpy(&offsets[1][0], mode == IMAGE_COLOR ? cisconfigs.color.offsetsB : cisconfigs.gray.offsetsB, sizeof(int) * 6); } //static int val = 0; //int step = 100; // for(int i = 0;i<2;i++) // { // for(int j =0 ;j<3;j++) // { // exposures[i][j] =i==0? cisconfigs.gray.expF[j]*exp_ratio:cisconfigs.gray.expB[j]*exp_ratio; // printf("exp_ratio = %0.2f \r\n",exp_ratio); // } // } // val+=step; // exp_ratio += 0.1; // for (int i = 0; i < 2; i++) // { // for (int j = 0; j < 6; j++) // { // printf("gains[%d][%d] = %d \r\n", i, j, gains[i][j]); // printf("offsets[%d][%d] = %d \r\n", i, j, offsets[i][j]); // if (j < 3) // { // printf("exposures[%d][%d] = %d \r\n", i, j, exposures[i][j]); // } // } // } setFGPAParmas(exposures, gains, offsets); } void Capturer::setFGPAParmas(int exposures[2][3], int gains[2][6], int offsets[2][6]) { //set exposuretime fpgaComm->setAExposureB(exposures[0][0]); std::this_thread::sleep_for(std::chrono::milliseconds(15)); fpgaComm->setAExposureG(exposures[0][1]); std::this_thread::sleep_for(std::chrono::milliseconds(15)); fpgaComm->setAExposureR(exposures[0][2]); std::this_thread::sleep_for(std::chrono::milliseconds(15)); fpgaComm->setBExposureB(exposures[1][0]); std::this_thread::sleep_for(std::chrono::milliseconds(15)); fpgaComm->setBExposureG(exposures[1][1]); std::this_thread::sleep_for(std::chrono::milliseconds(15)); fpgaComm->setBExposureR(exposures[1][2]); // set Gain and offset for (int i = 0; i < 6; i++) { //LOGD("setAGain %d =:%d", i , gains[0][i]); fpgaComm->setAGain(i, gains[0][i]); // A面增加 std::this_thread::sleep_for(std::chrono::milliseconds(15)); fpgaComm->setBGain(i, gains[1][i]); // B面增益 std::this_thread::sleep_for(std::chrono::milliseconds(15)); fpgaComm->setAOffset(i, offsets[0][i]); // A面偏置 std::this_thread::sleep_for(std::chrono::milliseconds(15)); fpgaComm->setBOffset(i, offsets[1][i]); //B面偏置 } } void *Capturer::readFrame(int timeout) { auto ret= video->read_frame(timeout); return ret; } bool Capturer::is_runing() { return true; } int Capturer::color() { return fpgaComm->getColorMode() ? 16 : 0; } int Capturer::height() { return fpgaComm->getFrameHeight(); } int Capturer::width() { return 1632; } void Capturer::set_sp(int sp) { fpgaComm->setSp(sp); } void Capturer::init_autocorrect(int colormode) { std::thread t_correctthread = std::thread(&Capturer::autocorrect, this, colormode); t_correctthread.detach(); } void Capturer::autocorrect(int colormode) { bcorrecting = true; cisconfigs = getcisparams(); scannerinfo = getscannerinfo(); ft.clear(); ft.append_log("start correct"); if (m_captureCallback) { m_captureCallback(colormode, colormode ? "------开始彩色校正------\r\n" : "------开始灰度校正------\r\n"); } creatcorrectconfig(colormode ? IMAGE_COLOR : IMAGE_GRAY); creatLUTData(colormode ? IMAGE_COLOR : IMAGE_GRAY, CISVendor::HUALIN_CIS_V0); if (colormode) { memcpy(cisconfigs.color.offsetsF, cisconfigs.colorCorrect.offsetsF, sizeof(int) * 6); memcpy(cisconfigs.color.offsetsB, cisconfigs.colorCorrect.offsetsB, sizeof(int) * 6); memcpy(cisconfigs.color.expF, cisconfigs.colorCorrect.expF, sizeof(int) * 3); memcpy(cisconfigs.color.expB, cisconfigs.colorCorrect.expB, sizeof(int) * 3); } else { memcpy(cisconfigs.gray.offsetsF, cisconfigs.grayCorrect.offsetsF, sizeof(int) * 6); memcpy(cisconfigs.gray.offsetsB, cisconfigs.grayCorrect.offsetsB, sizeof(int) * 6); memcpy(cisconfigs.gray.expF, cisconfigs.grayCorrect.expF, sizeof(int) * 3); memcpy(cisconfigs.gray.expB, cisconfigs.grayCorrect.expB, sizeof(int) * 3); } savecisparams(cisconfigs); initLut(); if (m_captureCallback) m_captureCallback(4, colormode ? "------彩色校正完成------\r\n" : "------灰度校正完成------\r\n"); reset(); bcorrecting = false; HG_LOG("init_autocorrect exit \n"); } void Capturer::creatcorrectconfig(int mode) { std::string msg = mode == IMAGE_COLOR ? "彩色" : "灰度"; //LOG_TRACE("creatcorrectconfig \r\n"); ft.append_log("开始" + msg + "暗场校正"); if (m_captureCallback) m_captureCallback(mode, "开始" + msg + "暗场校正\r\n"); openDevice(mode); bool isDone = false; int i = 1; initStep(); while (!isDone) //先暗场 { configFPGAParam(true, mode); string log = "==============================第" + to_string(i) + "次=============================== \r\n"; ft.append_log(log); if (m_captureCallback) m_captureCallback(mode, log); std::this_thread::sleep_for(std::chrono::milliseconds(100)); fpgaComm->enableLed(false); std::this_thread::sleep_for(std::chrono::milliseconds(200)); //fpgaComm->update(); fpgaComm->capture(); std::this_thread::sleep_for(std::chrono::milliseconds(500)); isDone = saveLutImg(mode, mode == IMAGE_COLOR ? 0 : 2); // 0 color_black 1 color_white 2 gray_balck 3 gray_white i++; } i = 1; isDone = false; initStep(); ft.append_log("开始" + msg + "明场校正"); if (m_captureCallback) m_captureCallback(mode, "开始" + msg + "明场校正 \r\n"); while (!isDone) //后明场 { configFPGAParam(true, mode); string log = "==============================第" + to_string(i) + "次=============================== \r\n"; ft.append_log(log); std::this_thread::sleep_for(std::chrono::milliseconds(100)); fpgaComm->enableLed(true); fpgaComm->update(); std::this_thread::sleep_for(std::chrono::milliseconds(200)); fpgaComm->capture(); std::this_thread::sleep_for(std::chrono::milliseconds(500)); isDone = saveLutImg(mode, mode == IMAGE_COLOR ? 1 : 3); //isDone = true; i++; } LOG_TRACE(string_format("creatcorrectconfig %s \r\n", (mode == IMAGE_COLOR ? " Color" : " Gray"))); video->close(); std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } void Capturer::openDevice(int mode) { this->reset(); // #ifdef G00 int width = 1632; int height = 6000; // #else // int width = 1728; // int height = 6000; // #endif video->open(width, mode == IMAGE_COLOR ? height : height / 3); std::this_thread::sleep_for(std::chrono::milliseconds(20)); fpgaComm->capture(); video->read_frame(200); //丢弃第一张无效图像 LOG_TRACE(string_format("cisconfigs.grayCorrect.sp = %d \r\n", cisconfigs.grayCorrect.sp)); //fpgaComm->setSp(mode == IMAGE_COLOR ? cisconfigs.colorCorrect.sp : cisconfigs.grayCorrect.sp); auto info = getscannerinfo(); fpgaComm->setSp(mode == IMAGE_COLOR ? info.color_sp : info.gray_sp); //0x438 : 0xca8 fpgaComm->setSample(256); fpgaComm->setDpi(1); fpgaComm->setColorMode(mode == IMAGE_COLOR ? 1 : 0); fpgaComm->setFrameHeight(mode == IMAGE_COLOR ? height : height / 3); fpgaComm->enableLed(true); } static int savelutindex = 0; bool Capturer::saveLutImg(int mode, int index) { int offset_indexs[12] = {0, 1, 2, 5, 4, 3, 3, 4, 5, 2, 1, 0}; int count = 1; int height = 6000; int width = 1632; bool isNeedSave = true; string log; for (int i = 0; i < 1; i++) { void *data = video->read_frame(1500); if (data == NULL) { log = "图像采集失败!\r\n"; ft.append_log(log); isNeedSave = false; if (m_captureCallback) m_captureCallback(mode, log); } if (data && isNeedSave) { if (mode == IMAGE_COLOR) { cv::Mat mergeMat = GetMergeMat(data, this->width(), this->height(), this->color()); cv::cvtColor(mergeMat, mergeMat, CV_RGB2BGR); if (i == 0) { double values[2][3]; cv::Scalar a = cv::mean(mergeMat(cv::Rect(0, 0, mergeMat.cols / 2, mergeMat.rows))); cv::Scalar b = cv::mean(mergeMat(cv::Rect(mergeMat.cols / 2, 0, mergeMat.cols / 2, mergeMat.rows))); for (int j = 0; j < 3; j++) { values[0][j] = a.val[2 - j]; values[1][j] = b.val[2 - j]; } double offValues[12]; for (int n = 0; n < 2; n++) { cv::Mat img = mergeMat(cv::Rect(mergeMat.cols * n / 2, 0, mergeMat.cols / 2, mergeMat.rows)); int offset_total = 0; for (int s = 0; s < 6; s++) // { int k = n * 6 + s; int offset_wdth; if ((s == 0 && k == 0) || (s == 5 && k == 11)) offset_wdth = 288; else offset_wdth = 432; cv::Scalar mean; mean = cv::mean(img(cv::Rect(offset_total, 0, offset_wdth, img.rows))); if ((s == 0 && k == 0) || (s == 5 && k == 11)) offset_total += 288; else offset_total += 432; offValues[k] = mean.val[0]; } } log += " 彩色A面RGB值:" + std::to_string(values[0][0]) + "," + std::to_string(values[0][1]) + "," + std::to_string(values[0][2]) + "\r\n"; log += " 彩色B面RGB值:" + std::to_string(values[1][0]) + "," + std::to_string(values[1][1]) + "," + std::to_string(values[1][2]) + "\r\n"; ft.append_log(log); if (m_captureCallback) m_captureCallback(mode, log); if (index % 2 == 1) { //明场 //imwrite(std::to_string(savelutindex++) + "clwh.jpg", mergeMat); log = "开始彩色明场校正 \r\n"; for (int s = 0; s < 2; s++) { int *exposures = (int *)(s == 0 ? cisconfigs.colorCorrect.expF : cisconfigs.colorCorrect.expB); for (int x = 0; x < 3; x++) { int k = (3 * s + x); int diff = LIGHT_DIFF(scannerinfo.clr_maxbright, *((double *)values + k)); log += " 明场:" + std::to_string(k) + ";diff:" + std::to_string(diff) + "\r\n"; double step = diff * radio; int preStep = *((int *)expStep + k); if (step * preStep < 0) { step = 0 - preStep / 2; } FMT_STEP(step); bool isMinStep = abs(step) == 1 && step == *((int *)expStep + k); bool isOutBounds = exposures[x] >= 1770 && step > 0; isOutBounds |= exposures[x] <= 0 && step < 0; if (isOutBounds) log += " 第" + to_string(x) + "个明场校正异常 \r\n"; else if (abs(diff) >= 2 || isMinStep) { *((int *)expStep + k) = (int)(step); exposures[x] += step; if (exposures[x] > 1770) { exposures[x] = 1770; } if (exposures[x] < 0) exposures[x] = 0; isNeedSave = false; } log += " 曝光值:" + to_string(exposures[x]) + "\r\n"; log += " 调整步长:" + to_string(*((int *)expStep + k)) + "\r\n"; if (isNeedSave) log += "彩色明场校正完成\r\n"; } } ft.append_log(log); if (m_captureCallback) m_captureCallback(mode, log); } else //彩色暗场 { int *offsets; //imwrite(std::to_string(savelutindex++) + "clrblk.jpg", mergeMat); log = "开始彩色暗场校正"; for (int s = 0; s < 2; s++) { offsets = (int *)(s == 0 ? cisconfigs.colorCorrect.offsetsF : cisconfigs.colorCorrect.offsetsB); for (int j = 0; j < 6; j++) { int k = s * 6 + j; double diff = BLACK_DIFF(offValues[k]); double step = radio * diff; int preStep = offsetStep[k]; if (step * preStep < 0) { step = 0 - preStep / 2; } else { radio = 1; } FMT_STEP(step); bool isMinStep = abs(step) == 1 && step == offsetStep[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) { offsetStep[k] = (int)(step); offsets[offset_indexs[k]] += step; log += "offsetStep" + std::to_string(k) + " = " + std::to_string(offsetStep[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; } 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"; if (isNeedSave) log += (s == 0 ? "彩色正面暗场校正完成 \r\n" : "彩色背面暗场校正完成 \r\n"); } } ft.append_log(log); if (m_captureCallback) m_captureCallback(mode, log); } if (isNeedSave) { mBuffMat.release(); mBuffMat = mergeMat; } } if (isNeedSave && i == 0) { if (i > 0) { out.release(); cv::vconcat(mBuffMat, mergeMat, out); } else { mergeMat.copyTo(out); cv::cvtColor(out, out, CV_BGR2RGB); } char buffer[40]; sprintf(buffer, "/usr/local/huago/lut_%d.bmp", index); imwrite(buffer, out); LOG_TRACE(string_format("save image %s ", buffer)); } else if (i != 0) { cv::vconcat(mBuffMat, mergeMat, mBuffMat); } } else { // 灰色模式 cv::Mat src = GetMergeMat(data, this->width(), this->height(), this->color()); //imwrite(std::to_string(savelutindex++) + "graywh.jpg", src); char buffer[40]; sprintf(buffer, "/usr/local/huago/lut_%d.bmp", index); double values[2]; values[0] = cv::mean(src(cv::Rect(0, 0, src.cols / 2, src.rows))).val[0]; values[1] = cv::mean(src(cv::Rect(src.cols / 2, 0, src.cols / 2, src.rows))).val[0]; double offValues[12]; for (int n = 0; n < 2; n++) { cv::Mat img = src(cv::Rect(src.cols * n / 2, 0, src.cols / 2, src.rows)); int offset_total = 0; for (int s = 0; s < 6; s++) // { int k = n * 6 + s; int offset_wdth; if ((s == 0 && k == 0) || (s == 5 && k == 11)) offset_wdth = 288; else offset_wdth = 432; cv::Scalar mean; mean = cv::mean(img(cv::Rect(offset_total, 0, offset_wdth, img.rows))); if ((s == 0 && k == 0) || (s == 5 && k == 11)) offset_total += 288; else offset_total += 432; offValues[k] = mean.val[0]; } } if (index % 2 == 1) //灰度明场 { log = "-----开始灰色明场校正-----\r\n"; log += " 灰色扫描灰度明场均值:" + to_string(values[0]) + "," + to_string(values[1]) + "\r\n"; for (int s = 0; s < 2; s++) { int *exposures = (int *)(s == 0 ? cisconfigs.grayCorrect.expF : cisconfigs.grayCorrect.expB); int diff = LIGHT_DIFF(scannerinfo.gray_maxbright, values[s]); 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; } FMT_STEP(step); 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 >= 1770 && step > 0; isOutBounds |= exp <= 0 && step < 0; if (isOutBounds) log += " 第" + to_string(s) + "个明场校正异常 \r\n"; else if (abs(diff) > 2 || isMinStep) { exp += step; if (exp < 0) exp = 0; if (exp > 1770) exp = 1770; 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; } } ft.append_log(log); if (m_captureCallback) m_captureCallback(mode, log); } else //灰度暗场 { log = "开始灰色暗场校正 \r\n"; for (int s = 0; s < 2; s++) { int *offsets = (int *)(s == 0 ? cisconfigs.grayCorrect.offsetsF : cisconfigs.grayCorrect.offsetsB); for (int j = 0; j < 6; j++) { int k = s * 6 + j; double diff = BLACK_DIFF(offValues[k]); double step = radio * diff; int preStep = offsetStep[k]; if (step * preStep < 0) { step = 0 - preStep / 2; } else { radio = 1; } FMT_STEP(step); bool isMinStep = abs(step) == 1 && step == offsetStep[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(i) + "面暗场校正异常,暗场值无法降低 \r\n"; else if (abs(step) > 1 || isMinStep) { offsetStep[k] = (int)(step); offsets[offset_indexs[k]] += step; log += "offsetStep" + std::to_string(k) + " = " + std::to_string(offsetStep[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; } } 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"; if (isNeedSave) log += "灰色暗场校正完成 \r\n"; } //final report ft.append_log(log); if (m_captureCallback) m_captureCallback(mode, log); } if (isNeedSave) { LOG_TRACE(string_format("save image path %s", buffer)); imwrite(buffer, src); } } } } return isNeedSave; } void Capturer::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(); }