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