rk3399_arm_lvds/capimage/MonoCapturer.cpp

1046 lines
38 KiB
C++
Raw Normal View History

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