tx-gxx-linux/device/gxx-linux/capimage/MonoCapturer.cpp

911 lines
32 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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