916 lines
27 KiB
C++
916 lines
27 KiB
C++
|
#include "Capturer.h"
|
|||
|
#include "DevUtil.h"
|
|||
|
#include <thread>
|
|||
|
#include <time.h>
|
|||
|
#include <sstream>
|
|||
|
#include "Gpio.h"
|
|||
|
#include "FpgaComm.h"
|
|||
|
#include "gvideoisp1.h"
|
|||
|
#include "config.h"
|
|||
|
#include <iostream>
|
|||
|
#include <functional>
|
|||
|
#include "applog.h"
|
|||
|
#include "stringex.hpp"
|
|||
|
#include <opencv2/opencv.hpp>
|
|||
|
#include <opencv2/imgproc/types_c.h>
|
|||
|
#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<IRegsAccess> 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();
|
|||
|
}
|