1307 lines
55 KiB
C++
1307 lines
55 KiB
C++
#include "MultiFrameCapture.h"
|
||
#include <thread>
|
||
// #include <opencv2/opencv.hpp>
|
||
#include "DevUtil.h"
|
||
#include "Gpio.h"
|
||
#include "FpgaComm.h"
|
||
#include "gvideoisp1.h"
|
||
#include "CameraParam.h"
|
||
#include "correct_ultis.h"
|
||
#include "filetools.h"
|
||
#include "USBProtocol.h"
|
||
#include "utilsfunc.h"
|
||
#include "CImageMerge.h"
|
||
#include "Jpegcompress.h"
|
||
#include "CSizedetect.h"
|
||
#include "ThreadPool.h"
|
||
|
||
#include "HCamDevice.h"
|
||
|
||
const int vsp_A = 45;
|
||
const int vsp_B = 45;
|
||
|
||
// using namespace cv;
|
||
MultiFrameCapture::MultiFrameCapture(ScannerGlue glue,
|
||
std::shared_ptr<FpgaComm> fpga,
|
||
CISVendor vendor) : reset_pin(new GpioOut(Fpga_Reset)),
|
||
fpgaLoad(new Gpio(Fpga_Load)),
|
||
fpga_conf_initn(new Gpio(Fpga_InitN)),
|
||
snaped_index(0),
|
||
frame_count(1),
|
||
b_snap_run(true),
|
||
b_stop_snap(false),
|
||
b_imgproc(true),
|
||
m_glue(glue),
|
||
pimgdata_info({0}),
|
||
iImageremain(0),
|
||
bScanning(false)
|
||
#ifdef TEST_SIMCAP
|
||
,
|
||
m_test_pimg(nullptr), m_test_pimg_len(0)
|
||
#endif
|
||
{
|
||
m_capFpageregs = fpga;
|
||
video.reset(new HCamDevice);
|
||
|
||
// reset_pin->setDirection("out");
|
||
// reset_pin->setValue(Gpio::Low);
|
||
// fpga_conf_initn->setDirection("out");
|
||
// fpga_conf_initn->setValue(Gpio::High);
|
||
// fpgaLoad->setDirection("out");
|
||
// fpgaLoad->setValue(Gpio::High);
|
||
|
||
reset_fpga();
|
||
|
||
m_snap_thread.reset(new std::thread(&MultiFrameCapture::snaprun, this));
|
||
m_imgproc_thread.reset(new std::thread(&MultiFrameCapture::procimage, this));
|
||
}
|
||
|
||
MultiFrameCapture::~MultiFrameCapture()
|
||
{
|
||
if (m_capFpageregs.get())
|
||
m_capFpageregs.reset();
|
||
|
||
if (video.get())
|
||
video.reset();
|
||
|
||
m_frameinfos.Clear();
|
||
m_frameinfos.ShutDown();
|
||
if (m_imgproc_thread.get())
|
||
{
|
||
if (m_imgproc_thread->joinable())
|
||
{
|
||
b_imgproc = false;
|
||
m_imgproc_thread->join();
|
||
}
|
||
}
|
||
if (pimgdata_info.pdata)
|
||
{
|
||
free(pimgdata_info.pdata);
|
||
pimgdata_info.pdata = nullptr;
|
||
}
|
||
#ifdef TEST_SIMCAP
|
||
if (m_test_pimg)
|
||
free(m_test_pimg);
|
||
#endif
|
||
}
|
||
|
||
void MultiFrameCapture::SetParent(void *scanner)
|
||
{
|
||
}
|
||
|
||
void MultiFrameCapture::open()
|
||
{
|
||
// reset_fpga();
|
||
m_capFpageregs->resetADC();
|
||
m_capFpageregs->set_cis_type(false); // 适配A4 CIS
|
||
const bool dunnancis = true;
|
||
is_size_error = false;
|
||
// m_frames.clear();
|
||
m_preproclist.clear();
|
||
if (m_config.params.enableSizeDetect)
|
||
{
|
||
if (((PaperSize)m_config.params.pageSize != PaperSize::G400_AUTO) && ((PaperSize)m_config.params.pageSize != PaperSize::G400_MAXAUTO))
|
||
{
|
||
LOG("init CSizedetect \n");
|
||
// m_preproclist.push_back(shared_ptr<IPreproc>(new CSizedetect(m_config.params.pageSize, m_config.params.dpi)));
|
||
}
|
||
}
|
||
int dpi = m_config.params.dpi == 0x02 ? 2 : (m_config.params.dpi == 0x03 ? 3 : 2);
|
||
if (m_config.params.pageSize == 17 || m_config.params.pageSize == 19)
|
||
dpi = 2;
|
||
int mode = m_config.params.isColor;
|
||
int channelwidth = dpi == 0x02 ? 864 : (dpi == 0x03 ? 1728 : 864); // 1296 2592 864
|
||
int channels = mode == 0x01 ? 3 : 1;
|
||
int width = channelwidth * channels;
|
||
auto phyHeight = paperHeight[(PaperSize)m_config.params.pageSize];
|
||
int pixheight; // = ((int)((phyHeight / 25.4 * (dpi == 0x02 ? 300 : (dpi == 0x03 ? 600 : 200)) + 2) / 3)) * 3 * 2;
|
||
int tdpi = m_config.params.dpi == 0x02 ? 300 : (m_config.params.dpi == 0x03 ? 600 : 200);
|
||
|
||
m_fpgaparam = GetFpgaparam(m_config.params.dpi, mode);
|
||
unsigned int sp_dst = m_fpgaparam.Sp;
|
||
if (m_config.params.pageSize == 17 || m_config.params.pageSize == 19)
|
||
{
|
||
sp_dst = mode == 1 ? 4144 : 12432; // sp_dst = mode == 1 ? 3327 : 9981;
|
||
tdpi = 300;
|
||
}
|
||
pixheight = ((int)((phyHeight / 25.4 * tdpi + 2) / 3)) * 3;
|
||
pixheight = m_config.params.dpi > 1 ? std::min(pixheight, 24016) : std::min(pixheight, 36236);
|
||
if ((m_config.params.pageSize == 17 || m_config.params.pageSize == 19) && m_config.params.dpi == 3)
|
||
pixheight /= 2;
|
||
// pixheight = 8100;
|
||
printf("########## pixheight = %d phyHeight = %d m_config.params.pageSize %d dpi = %d\n", pixheight, phyHeight, m_config.params.pageSize, dpi);
|
||
|
||
frame_height = 300 * channels;
|
||
// frame_height = (dpi > 2 ? 300 : 180) * channels;
|
||
frame_count = ceil((mode == 0x01 ? pixheight * 3 : pixheight) / (float)(frame_height)); // 彩色配置fpga 高度要为目标图像高度的3倍
|
||
frame_count += 1; // 最后一帧丢帧,多采集一帧防止图像数据缺失
|
||
if (frame_height * frame_count > FPGA_MAX_HEIGHT_SUP)
|
||
frame_count = FPGA_MAX_HEIGHT_SUP / frame_height;
|
||
|
||
int startsample = 202; // 205
|
||
ModeFpga fpgamod = {
|
||
.colorMode = mode,
|
||
.dpi = dpi,
|
||
.led = 1,
|
||
.sample = startsample, // 256+39
|
||
.adcA = 0,
|
||
.adcB = 0,
|
||
.selftest = 0,
|
||
.sp = sp_dst}; // 600DPI 0x1450 300DPI 0xe10
|
||
readframe_timeout = sp_dst / 4 / (mode == 1 ? 1 : 3);
|
||
|
||
m_capFpageregs->setRegs(0x01, *((int *)(&fpgamod)));
|
||
m_capFpageregs->setSample(startsample);
|
||
// auto info = GetScanInfoFromJson();
|
||
// m_capFpageregs->setVsp(info.SleepTime, info.SleepTime);
|
||
m_capFpageregs->setVsp(vsp_A, vsp_B);
|
||
// m_capFpageregs->setVsp(85, 85); //2.13版本fpga
|
||
m_capFpageregs->enableLed(true);
|
||
m_capFpageregs->setEnTestCol(false);
|
||
m_capFpageregs->setEnTestBit(false);
|
||
|
||
// m_capFpageregs->setFrame_interval_max(static_cast<int>(sp_dst * 4 / (mode ? 1 : 3))); //dpi > 2 ? 7200 : 3600
|
||
// m_capFpageregs->setFrame_interval_min(static_cast<int>(sp_dst * 0.1 / (mode ? 1 : 3) )); //1540
|
||
m_capFpageregs->setFrame_interval_max(0x1010); // dpi > 2 ? 7200 : 3600
|
||
m_capFpageregs->setFrame_interval_min(0xa98); // dpi > 2 ? 900 : 1540 a98
|
||
printf("interval_max = %d interval_min = %d \n", static_cast<int>(sp_dst * 4 / (mode ? 1 : 3)), static_cast<int>(sp_dst * 0.1 / (mode ? 1 : 3)));
|
||
// m_capFpageregs->setFrameNum(1);
|
||
configFPGAParam(mode, m_config.params.dpi);
|
||
StopWatch swwv4l2open;
|
||
video->open_video(width, frame_height / channels * 2); // 300dpi 7344/2 600dpi 7344 //FRAME_HEIGHT * 2
|
||
printf("opened video with width = %d height = %d time eplased = %.2f sp_dst =%d \n", width, frame_height / channels * 2, swwv4l2open.elapsed_ms(), fpgamod.sp);
|
||
// m_capFpageregs->setFrameHeight(12);
|
||
m_capFpageregs->setFrameNum(1);
|
||
|
||
m_capFpageregs->setFrameHeight(frame_height);
|
||
m_capFpageregs->update();
|
||
m_capFpageregs->capture(); // abort first frame
|
||
printf(" getFrame_counter_val %d \n", m_capFpageregs->getFrame_counter_val());
|
||
// video->read_frame(,400);
|
||
unsigned char *buf = NULL;
|
||
video->HtCamReadCaptureFrame((void **)&buf, 400);
|
||
// std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||
printf("abort first frame \n");
|
||
|
||
// printf(" getFrame_counter_val %d \n",m_capFpageregs->getFrame_counter_val());
|
||
m_capFpageregs->setFrameNum(frame_count);
|
||
printf("frame count = %d height = %d \n", frame_count, frame_height);
|
||
m_capFpageregs->setFrameHeight(frame_height);
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||
if (m_config.params.pageSize == 17 || m_config.params.pageSize == 19)
|
||
initLut(GetFpgaparam(2, mode).TextLutPath, m_config.params.isColor);
|
||
else
|
||
initLut(m_fpgaparam.TextLutPath, m_config.params.isColor);
|
||
|
||
m_capFpageregs->update();
|
||
init_imagedatabuffer();
|
||
}
|
||
|
||
void MultiFrameCapture::snap()
|
||
{
|
||
#ifndef TEST_SIMCAP
|
||
std::lock_guard<std::mutex> m_lock(m_mtx_snap);
|
||
b_stop_snap = b_end_snap = false;
|
||
m_capFpageregs->capture();
|
||
snaped_index++;
|
||
m_cv_snap.notify_all();
|
||
#endif
|
||
}
|
||
|
||
void MultiFrameCapture::stopsnap(bool autosize)
|
||
{
|
||
if (autosize)
|
||
{
|
||
b_stop_snap = true;
|
||
}
|
||
}
|
||
|
||
void MultiFrameCapture::close()
|
||
{
|
||
if (video.get())
|
||
video->close_video();
|
||
|
||
// reload_fpga();
|
||
reset_fpga();
|
||
}
|
||
|
||
int MultiFrameCapture::read(int addr)
|
||
{
|
||
return m_capFpageregs->read(addr);
|
||
}
|
||
|
||
void *MultiFrameCapture::readFrameTest(int timeout)
|
||
{
|
||
return nullptr;
|
||
}
|
||
|
||
void MultiFrameCapture::UpdateScanParam(HG_ScanConfiguration config)
|
||
{
|
||
m_config = config;
|
||
printf("pageSize:%d\r\n", m_config.params.pageSize);
|
||
printf("isColor:%d\r\n", m_config.params.isColor);
|
||
printf("dpi:%d\r\n", m_config.params.dpi);
|
||
|
||
#ifdef TEST_SIMCAP
|
||
if (m_test_pimg)
|
||
free(m_test_pimg);
|
||
|
||
FILE *f_img;
|
||
if (m_config.params.isColor == 1) // color
|
||
f_img = fopen("/home/root/color.bmp", "rb");
|
||
else
|
||
f_img = fopen("/home/root/gray.bmp", "rb");
|
||
|
||
if (f_img == nullptr)
|
||
printf("!!!!!!!!!! error while reading image \r\n");
|
||
|
||
fseek(f_img, 0, SEEK_END);
|
||
m_test_pimg_len = ftell(f_img);
|
||
m_test_pimg = (unsigned char*)malloc(m_test_pimg_len);
|
||
fseek(f_img, 0, SEEK_SET);
|
||
fread(m_test_pimg,1,m_test_pimg_len,f_img);
|
||
printf("!!!!!!!!!! info: reading image len = %d m_test_pimg = %p \r\n", m_test_pimg_len, m_test_pimg);
|
||
fclose(f_img);
|
||
#endif
|
||
}
|
||
|
||
void MultiFrameCapture::createCorrect(int correctmode)
|
||
{
|
||
if (m_correctThread.joinable())
|
||
m_correctThread.join();
|
||
stop_countdown();
|
||
m_correctThread = std::thread(&MultiFrameCapture::correctcolor, this, correctmode);
|
||
}
|
||
|
||
void MultiFrameCapture::setFPGATriggerMode(bool autotrigger, int delay)
|
||
{
|
||
}
|
||
|
||
void MultiFrameCapture::setFanMode(int mode)
|
||
{
|
||
m_capFpageregs->setFanMode(mode);
|
||
}
|
||
|
||
void MultiFrameCapture::fpgaReload()
|
||
{
|
||
fpgaLoad->setValue(Gpio::Low);
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(15));
|
||
fpgaLoad->setValue(Gpio::High);
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(15));
|
||
m_capFpageregs->resetADC();
|
||
}
|
||
|
||
bool MultiFrameCapture::capturerImage()
|
||
{
|
||
// if (m_config.params.pageSize == (int)PaperSize::G400_AUTO ||
|
||
// m_config.params.pageSize == (int)PaperSize::G400_MAXAUTO ||
|
||
// m_config.params.pageSize == (int)PaperSize::G400_MAXSIZE)
|
||
// {
|
||
// }
|
||
// else
|
||
// {
|
||
// int color = this->color();
|
||
// int channels = color ? 3 : 1;
|
||
// int width = this->width() * channels * 6;
|
||
// int dpi = m_config.params.dpi;
|
||
// for (int i = 0; i < frame_count; i++)
|
||
// {
|
||
// V4L2_DATAINFO_Ex frame_info;
|
||
// StopWatch sw_read;
|
||
// auto data = video->read_frame(150);
|
||
// printf("!!!!!!!!!!! read frame[%d] = %.2f \n", i, sw_read.elapsed_ms());
|
||
// frame_info.lost_frame = data ? false : true;
|
||
// frame_info.last_frame = (i == (frame_count - 1));
|
||
// frame_info.frame_index = i;
|
||
// if (data)
|
||
// {
|
||
// printf("+++++++ success: read frame[%d] \n", i);
|
||
// cv::Mat mat(FRAME_HEIGHT, width, CV_8UC1, data);
|
||
// StopWatch sw_clone;
|
||
// frame_info.mat = mat.clone();
|
||
// printf("!!!!!!!!!! Clone time = %0.3f \n",sw_clone.elapsed_ms());
|
||
// frame_info.pixtype = color;
|
||
// frame_info.dpi = dpi;
|
||
// frame_info.width = frame_info.height = 0; // 从mat信息中获取宽高信息
|
||
// }
|
||
// else
|
||
// {
|
||
// printf("------- error: lost frame[%d] \n", i);
|
||
// }
|
||
// m_frameinfos.Put(frame_info);
|
||
// }
|
||
// }
|
||
return true;
|
||
}
|
||
|
||
void MultiFrameCapture::waitsnapdone(int state)
|
||
{
|
||
#ifdef TEST_SIMCAP
|
||
HG_JpegCompressInfo info;
|
||
info.DataLength = m_test_pimg_len;
|
||
info.pJpegData = m_test_pimg;
|
||
|
||
m_glue.m_imageready(info);
|
||
#else
|
||
printf("!!!!!!!!!!!!!!!! m_cv_snapdone wait \n");
|
||
V4L2_DATAINFO_Ex info;
|
||
info.snaped_index = snaped_index;
|
||
info.snap_end = true;
|
||
info.error_code = state;
|
||
if (b_end_snap)
|
||
{
|
||
m_frameinfos.Put(info);
|
||
return;
|
||
}
|
||
std::unique_lock<std::mutex> lock(m_mtx_snapdone);
|
||
m_cv_snapdone.wait(lock);
|
||
b_end_snap = true;
|
||
m_frameinfos.Put(info);
|
||
printf("!!!!!!!!!!!!!!!! m_cv_snapdone wait done \n");
|
||
#endif
|
||
}
|
||
|
||
bool MultiFrameCapture::IsImageQueueEmpty()
|
||
{
|
||
printf(" m_frameinfos.Size = %d iImageremain = %d bScanning = %d\n", m_frameinfos.Size(), iImageremain.operator int(), bScanning);
|
||
return (m_frameinfos.Size() == 0 && iImageremain == 0) && !bScanning;
|
||
}
|
||
|
||
void MultiFrameCapture::resetimageremain()
|
||
{
|
||
iImageremain = 0;
|
||
}
|
||
|
||
std::atomic_int &MultiFrameCapture::getimageremain()
|
||
{
|
||
return iImageremain;
|
||
}
|
||
|
||
void MultiFrameCapture::clearimages()
|
||
{
|
||
m_frameinfos.Clear();
|
||
}
|
||
|
||
void MultiFrameCapture::setScanFlag(bool brun)
|
||
{
|
||
bScanning = brun;
|
||
}
|
||
|
||
void MultiFrameCapture::reset_fpga()
|
||
{
|
||
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));
|
||
m_capFpageregs->resetADC();
|
||
}
|
||
|
||
void MultiFrameCapture::reload_fpga()
|
||
{
|
||
fpgaLoad->setValue(Gpio::Low);
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||
fpga_conf_initn->setValue(Gpio::Low);
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||
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(15));
|
||
std::this_thread::sleep_for(std::chrono::seconds(5));
|
||
printf("reload done \n");
|
||
}
|
||
|
||
void MultiFrameCapture::set_gain(int ix, int val)
|
||
{
|
||
for (int i = 0; i < 6; i++)
|
||
{
|
||
if (ix)
|
||
m_capFpageregs->setAGain(i, val);
|
||
else
|
||
m_capFpageregs->setBGain(i, val);
|
||
}
|
||
}
|
||
|
||
void MultiFrameCapture::set_offset(int ix, int val)
|
||
{
|
||
for (int i = 0; i < 6; i++)
|
||
{
|
||
if (ix)
|
||
m_capFpageregs->setAOffset(i, val);
|
||
else
|
||
m_capFpageregs->setBOffset(i, val);
|
||
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||
}
|
||
}
|
||
|
||
void MultiFrameCapture::set_expo(int ix, int val)
|
||
{
|
||
switch (ix)
|
||
{
|
||
case 0:
|
||
m_capFpageregs->setAExposureR(val);
|
||
break;
|
||
case 1:
|
||
m_capFpageregs->setAExposureG(val);
|
||
break;
|
||
case 2:
|
||
m_capFpageregs->setAExposureB(val);
|
||
break;
|
||
case 3:
|
||
m_capFpageregs->setBExposureR(val);
|
||
break;
|
||
case 4:
|
||
m_capFpageregs->setBExposureG(val);
|
||
break;
|
||
case 5:
|
||
m_capFpageregs->setBExposureB(val);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||
}
|
||
|
||
void MultiFrameCapture::configFPGAParam(int mode, int dpi)
|
||
{
|
||
FPGAConfigParam fpgaparam = GetFpgaparam(dpi, mode);
|
||
// m_capFpageregs->resetADC();
|
||
// std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||
int value_a, value_b;
|
||
for (int i = 0; i < 6; i++)
|
||
{
|
||
if (i < 3)
|
||
{
|
||
set_expo(i, fpgaparam.ExposureF[i]);
|
||
LOG("fpgaparam.ExposureF[%d] = %d \n", i, fpgaparam.ExposureF[i]);
|
||
}
|
||
else
|
||
{
|
||
set_expo(i, fpgaparam.ExposureB[i % 3]);
|
||
LOG("fpgaparam.ExposureB[%d] = %d\n", i % 3, fpgaparam.ExposureB[i % 3]);
|
||
}
|
||
int A_value, B_value;
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(3));
|
||
m_capFpageregs->setAOffset(i, fpgaparam.OffsetF[i]);
|
||
LOG("fpgaparam.setAOffset[%d] = %d \n", i, fpgaparam.OffsetF[i]);
|
||
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(3));
|
||
m_capFpageregs->getAOffset(i, A_value, B_value);
|
||
LOG("fpgaparam.getAOffset[%d] = A_value = %d B_value = %d \n", i, A_value, B_value);
|
||
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(3));
|
||
m_capFpageregs->setBOffset(i, fpgaparam.OffsetB[i]);
|
||
LOG("fpgaparam.setBOffset[%d] = %d \n", i, fpgaparam.OffsetB[i]);
|
||
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(3));
|
||
m_capFpageregs->getBOffset(i, A_value, B_value);
|
||
LOG("fpgaparam.getBOffset[%d] = A_value = %d B_value = %d \n", i, A_value, B_value);
|
||
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(3));
|
||
m_capFpageregs->setAGain(i, fpgaparam.GainF[i]);
|
||
LOG("fpgaparam.GainF[%d] = %d\n", i, fpgaparam.GainF[i]);
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(3));
|
||
m_capFpageregs->setBGain(i, fpgaparam.GainB[i]);
|
||
LOG("fpgaparam.GainB[%d] = %d\n", i, fpgaparam.GainB[i]);
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(3));
|
||
|
||
// m_capFpageregs->getAGain(i,A_value,B_value);
|
||
// LOG("fpgaparam.getAGain[%d] = A_value = %d B_value = %d \n", i, A_value,B_value);
|
||
// std::this_thread::sleep_for(std::chrono::milliseconds(3));
|
||
// m_capFpageregs->getBGain(i,A_value,B_value);
|
||
// LOG("fpgaparam.getBGain[%d] = A_value = %d B_value = %d \n", i, A_value,B_value);
|
||
// std::this_thread::sleep_for(std::chrono::milliseconds(3));
|
||
}
|
||
};
|
||
int MultiFrameCapture::width()
|
||
{
|
||
int dpi = m_capFpageregs->getDpi();
|
||
int channel = 1;
|
||
#ifdef G400
|
||
int width = dpi == 0x02 ? 1296 * channel : (dpi == 0x03 ? (2592 * channel) : (864 * channel));
|
||
#else
|
||
int width = dpi == 0x02 ? 864 * channel : (dpi == 0x03 ? (1728 * channel) : (864 * channel)); // we only sup dunnancis now
|
||
#endif
|
||
return width;
|
||
}
|
||
|
||
int MultiFrameCapture::color()
|
||
{
|
||
return m_capFpageregs->getColorMode();
|
||
}
|
||
|
||
void MultiFrameCapture::snaprun()
|
||
{
|
||
auto snap_func = [this](V4L2_DATAINFO_Ex frame_info, int channels, bool last_frame, unsigned int frame_index)
|
||
{
|
||
// void *data = video->read_frame(500);
|
||
char *data = NULL;
|
||
video->HtCamReadCaptureFrame((void **)&data, 400);
|
||
frame_info.lost_frame = data ? false : true;
|
||
frame_info.last_frame = last_frame;
|
||
frame_info.frame_index = frame_index;
|
||
|
||
if (data)
|
||
{
|
||
// cv::Mat mat(frame_info.height, frame_info.width, CV_8UC1, data);
|
||
frame_info.data = (char *)data;
|
||
m_frameinfos.Put(frame_info);
|
||
}
|
||
else
|
||
{
|
||
frame_info.width = frame_info.height = 0; // 从mat信息中获取宽高信息
|
||
printf("!!!!!!!!!! error read frame losted, i = %d \n", frame_index);
|
||
}
|
||
};
|
||
while (b_snap_run)
|
||
{
|
||
std::unique_lock<std::mutex> lock(m_mtx_snap);
|
||
m_cv_snap.wait(lock);
|
||
V4L2_DATAINFO_Ex frame_info;
|
||
int channels = this->color() ? 3 : 1;
|
||
int width = this->width() * channels * 6;
|
||
frame_info.pixtype = this->color();
|
||
frame_info.dpi = m_config.params.dpi;
|
||
frame_info.width = width;
|
||
frame_info.error_code = 0;
|
||
frame_info.height = frame_height / channels;
|
||
// 从mat信息中获取宽高信息
|
||
frame_info.snaped_index = snaped_index;
|
||
void *data;
|
||
for (int i = 1; i <= frame_count; i++)
|
||
{
|
||
snap_func(frame_info, channels, (i == frame_count), i);
|
||
|
||
if (b_stop_snap)
|
||
{
|
||
int snaped_frame_count = m_capFpageregs->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++)
|
||
{
|
||
snap_func(frame_info, channels, ((i + j) == reversed_frame_count), i + j);
|
||
}
|
||
}
|
||
break; // 跳出当前读取多帧循环
|
||
}
|
||
}
|
||
|
||
// iImageremain++;
|
||
m_cv_snapdone.notify_all();
|
||
b_end_snap = true;
|
||
// printf("!!!!!!!!!!!!!!!! m_cv_snapdone notify_all \n");
|
||
}
|
||
}
|
||
|
||
void MultiFrameCapture::updatesnapstatus(int papertype)
|
||
{
|
||
b_stop_snap = false;
|
||
snaped_index = 0;
|
||
}
|
||
|
||
void MultiFrameCapture::procimage()
|
||
{
|
||
static int idx = 0;
|
||
ThreadPool prc_pool(4);
|
||
// td::queue<std::future<cv::Mat>> prc_fu;
|
||
unsigned int frames_height;
|
||
unsigned int frames_width = 0;
|
||
while (b_imgproc)
|
||
{
|
||
V4L2_DATAINFO_Ex frame = m_frameinfos.Take();
|
||
if (!frame.data)
|
||
{
|
||
HG_JpegCompressInfo info;
|
||
info.pJpegData = (unsigned char *)frame.data;
|
||
info.DataLength = frame.width * frame.height;
|
||
|
||
m_glue.m_imageready(info);
|
||
}
|
||
break;
|
||
// if (!frame.data)
|
||
// {
|
||
// prc_fu.push(prc_pool.enqueue([this, &frames_height, &frames_width](V4L2_DATAINFO_Ex frame) -> cv::Mat
|
||
// {
|
||
// CImageMerge imgmerge;
|
||
// // cv::imwrite(std::to_string(++idx) +"index"+std::to_string(frame.snaped_index)+ "org.jpg", frame.mat);
|
||
// auto img = imgmerge.MergeImage(frame.mat, frame.width, frame.height, frame.pixtype);
|
||
// // cv::imwrite(std::to_string(++idx) + "mrg.jpg", img);
|
||
|
||
// // printf(" img height = %d width = %d \n",img.rows,img.cols);
|
||
// if (m_config.params.pageSize == 17 || m_config.params.pageSize == 19)
|
||
// {
|
||
// if (m_config.params.isCorrect)
|
||
// correctColor(img, 2, m_config.params.isColor, false);
|
||
// if (m_config.params.dpi != 2)
|
||
// cv::resize(img, img, cv::Size(0, 0), m_config.params.dpi == 1 ? 1.0 : 2.0, m_config.params.dpi == 1 ? (2.0 / 3.0) : 2.0);
|
||
// if (m_config.params.isCorrect){
|
||
// myFloodFill(img,true);
|
||
// }
|
||
|
||
// }
|
||
// else if (m_config.params.isCorrect)
|
||
// correctColor(img, m_config.params.dpi, m_config.params.isColor, false);
|
||
// // cv::imwrite(std::to_string(++idx) + "correct.jpg", img);
|
||
// // printf("frame.snaped_index = %d \n frame.frame_index =%d \n frame.lost_frame = %d \n frame.last_frame = %d \n frame.pixtype = %d\n",
|
||
// // frame.snaped_index,
|
||
// // frame.frame_index,
|
||
// // frame.lost_frame,
|
||
// // frame.last_frame,
|
||
// // frame.pixtype
|
||
// // );
|
||
// // m_frames.push_back(img);
|
||
// // frames_height += img.rows;
|
||
// // frames_width = img.cols;
|
||
// // printf("frames_height = %d frames_width = %d index = %d \n",frames_height,frames_width,idx++);
|
||
// return img;
|
||
// // update_imgdatainfo(img);
|
||
// // img.release();
|
||
// },
|
||
// frame));
|
||
// }
|
||
// if (prc_fu.size() > 4)
|
||
// {
|
||
// auto img = prc_fu.front().get();
|
||
// frames_height += img.rows;
|
||
// frames_width = img.cols;
|
||
// update_imgdatainfo(img);
|
||
// prc_fu.pop();
|
||
// }
|
||
// if (frame.snap_end)
|
||
// {
|
||
// while (prc_fu.size())
|
||
// {
|
||
// auto img = prc_fu.front().get();
|
||
// frames_height += img.rows;
|
||
// frames_width = img.cols;
|
||
// update_imgdatainfo(img);
|
||
// prc_fu.pop();
|
||
// }
|
||
// if (frame.error_code)
|
||
// {
|
||
// iImageremain--;
|
||
// // m_frames.clear();
|
||
// //printf("!!!!!!!!!!!!!!!!!!!!!! frame.error_code = %d \n", frame.error_code);
|
||
// frames_height = frames_width = 0;
|
||
// reset_imagedata();
|
||
// continue;
|
||
// }
|
||
// // cv::Mat m_mat(frames_height,frames_width ,CV_8UC(m_config.params.isColor ?3:1));
|
||
// // unsigned int copy_height =0;
|
||
// // for(auto& mat : m_frames)
|
||
// // {
|
||
// // mat.copyTo(m_mat(cv::Rect(0,copy_height,mat.cols,mat.rows)));
|
||
// // copy_height+=mat.rows;
|
||
// // }
|
||
|
||
// // m_frames.clear();
|
||
// //printf("frames_height = %d frames_width = %d pimgdata_info = %d\n", frames_height, frames_width, pimgdata_info.total_dst);
|
||
// cv::Mat m_mat;
|
||
// if (frames_height > 0 && frames_width > 0)
|
||
// m_mat = cv::Mat(frames_height, frames_width, CV_8UC(m_config.params.isColor ? 3 : 1), pimgdata_info.pdata);
|
||
|
||
// float vratio = *((float *)&m_fpgaparam.VRatio);
|
||
// float hratio = *((float *)&m_fpgaparam.HRatio);
|
||
// if (!(vratio >= 0.8f && vratio <= 1.20f && hratio > 0.8f && hratio < 1.2f))
|
||
// vratio = hratio = 1.0f;
|
||
// if (m_config.params.dpi == 1)
|
||
// hratio = (200.0 / 300.0) * hratio;
|
||
|
||
// if (!m_mat.empty())
|
||
// {
|
||
// resize(m_mat, m_mat, cv::Size(0, 0), hratio, vratio);
|
||
// // printf("!!!!!!!!!!!!!!!!!!!!!! hratio = %f vratio = %f snapindex = %d \n",hratio,vratio,frame.snaped_index);
|
||
// for (int i = 0; i < m_preproclist.size(); i++)
|
||
// {
|
||
// LOG("error m_preproclist \n");
|
||
// auto halfimg = m_mat(cv::Rect(0, 0, m_mat.cols / 2, m_mat.rows));
|
||
// int ret = m_preproclist[i]->preprocess(halfimg, nullptr);
|
||
// if (ret)
|
||
// {
|
||
// m_glue.m_deviceevent((int)HG_ScannerStatus::SIZE_ERROR, "size error");
|
||
// is_size_error = true;
|
||
// }
|
||
// }
|
||
// frames_height = frames_width = 0;
|
||
// auto dst_a = m_mat(cv::Rect(0, 0, m_mat.cols / 2, m_mat.rows));
|
||
// auto dst_b = m_mat(cv::Rect(m_mat.cols / 2, 0, m_mat.cols / 2, m_mat.rows));
|
||
// cv::flip(m_mat(cv::Rect(0, 0, m_mat.cols / 2, m_mat.rows)), dst_a, 1);
|
||
// cv::flip(m_mat(cv::Rect(m_mat.cols / 2, 0, m_mat.cols / 2, m_mat.rows)), dst_b, 1);
|
||
// // printf("!!!!!!!!!!!!!!!!!!!!!! frames height = %d m_mat height = %d\n",copy_height,m_mat.rows);
|
||
// }
|
||
|
||
// JpegCompress cmp(90);
|
||
// HG_JpegCompressInfo info = cmp.GetCompressedImg(m_mat);
|
||
// if (info.pJpegData != nullptr && info.DataLength != 0 && !is_size_error)
|
||
// {
|
||
// m_glue.m_imageready(info);
|
||
// }
|
||
// iImageremain--;
|
||
// reset_imagedata();
|
||
// }
|
||
}
|
||
}
|
||
|
||
bool MultiFrameCapture::saveLutImg(int dpi, int mode, bool black)
|
||
{
|
||
// int config_dpi = dpi == 1 ? 2 : dpi;
|
||
// const int offset_indexs[] = {0, 1, 2, 5, 4, 3, 3, 4, 5, 2, 1, 0};
|
||
// int channels = mode == IMAGE_COLOR ? 3 : 1;
|
||
// int height = 60;
|
||
// int width = config_dpi == 0x02 ? 864 : (config_dpi == 0x03 ? 1728 : 864);
|
||
// int orgimgwidth = width * 2 * 3 * channels;
|
||
// int dstwidth = width * 2 * 3;
|
||
// bool isNeedSave = true;
|
||
// string log;
|
||
// void *data = video->read_frame(1000);
|
||
// if (data == NULL)
|
||
// {
|
||
// isNeedSave = false;
|
||
// log = "WARNNING WARNNING WARNNING FAILDED TO READ IMAGE DATA !!!!!!!!!!!!!!!!!!!\r\n";
|
||
// if (m_glue.m_deviceevent)
|
||
// m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, log);
|
||
// return isNeedSave;
|
||
// }
|
||
|
||
// cv::Mat src(height, orgimgwidth, CV_8UC1, data);
|
||
// CImageMerge t_marge;
|
||
// cv::Mat mrgmat = t_marge.MergeImage(src, dstwidth, height, mode);
|
||
// printf("mrgmat width = %d height = %d \n", mrgmat.cols, mrgmat.rows);
|
||
// static int inx = 0;
|
||
// //imwrite(to_string(++inx)+".jpg",mrgmat);
|
||
// // return 0;
|
||
// FPGAConfigParam param = GetFpgaparam(dpi, mode);
|
||
// if (black) // 暗场
|
||
// {
|
||
// volatile double offValues[12]{0};
|
||
// int blockcount = 12;
|
||
// int bandwidth = mrgmat.cols / blockcount;
|
||
// for (int n = 0; n < blockcount; n++)
|
||
// {
|
||
// cv::Mat img = mrgmat(cv::Rect(bandwidth * n, 10, bandwidth, mrgmat.rows - 10)).clone();
|
||
// cv::Scalar mean = cv::mean(img);
|
||
// // printf("band[%d] mean = %0.2f bandwidth = %d \n", n, mean.val[0],bandwidth);
|
||
// offValues[n] = mean.val[0];
|
||
// }
|
||
|
||
// for (int s = 0; s < 2; s++)
|
||
// {
|
||
// unsigned int offsets[6]; // = (int *)(s == 0 ? ¶m.OffsetF[0] : ¶m.OffsetB[0]);
|
||
// memcpy(offsets, (s == 0 ? ¶m.OffsetF[0] : ¶m.OffsetB[0]), sizeof(param.OffsetF));
|
||
// for (int j = 0; j < 6; j++)
|
||
// {
|
||
// int k = s * 6 + j;
|
||
// // double diff = BLACK_DIFF(offValues[k]);
|
||
// double diff = 8 - offValues[k];
|
||
// double step = radio * diff;
|
||
// // int preStep = offsetStep[k];
|
||
// // if (step * preStep < 0)
|
||
// // {
|
||
// // //step = 0 - preStep / 2;
|
||
// // step /= 2;
|
||
// // }
|
||
// // else
|
||
// // {
|
||
// // radio = 1;
|
||
// // }
|
||
|
||
// if (step < 1 && step > 0.5)
|
||
// step = 1;
|
||
// if (step < -0.5 && step > -1)
|
||
// step = -1;
|
||
// // FMT_STEP(step);
|
||
// bool isMinStep = abs(step) == 1 && step == offsetStep[k];
|
||
// bool isOutBounds = offsets[j] >= 255 && step > 0;
|
||
// isOutBounds |= offsets[j] <= 0 && step < 0;
|
||
// log += " 暗场校正 :" + std::to_string(k) + ";diff:" + std::to_string(diff) + ";light:" + std::to_string(offValues[k]) + ";offset:" + std::to_string(offsets[j]) + ";step:" + std::to_string(step) + "\r\n";
|
||
// if (isOutBounds)
|
||
// log += " 第" + std::to_string(k) + "条带暗场校正异常,暗场值无法降低 \r\n";
|
||
// else if (abs(step) > 1 || isMinStep)
|
||
// {
|
||
// offsetStep[k] = (int)(step);
|
||
// printf(" k = %d offsets[%d] = %d step = %f mean = %f\n", k, offset_indexs[k], offsets[offset_indexs[k]], step, offValues[k]);
|
||
// offsets[offset_indexs[k]] += step;
|
||
// log += "offsetStep" + std::to_string(k) + " = " + std::to_string(offsetStep[k]) + ", offset_indexs" + std::to_string(k) + " =" + std::to_string(offset_indexs[k]) + "\r\n";
|
||
|
||
// if (offsets[offset_indexs[k]] < 1)
|
||
// offsets[offset_indexs[k]] = 1;
|
||
// if (offsets[offset_indexs[k]] > 255)
|
||
// offsets[offset_indexs[k]] = 255;
|
||
// isNeedSave = false;
|
||
// }
|
||
// log += (s == 0 ? "彩色正面" : "彩色背面");
|
||
// log += "偏移值:" + std::to_string(offsets[0]) + "," + std::to_string(offsets[1]) + "," + std::to_string(offsets[2]) + "," + std::to_string(offsets[3]) + "," + std::to_string(offsets[4]) + "," + std::to_string(offsets[5]) + "\r\n";
|
||
// // log += (s == 0 ? "彩色正面暗场校正完成 \r\n" : "彩色背面暗场校正完成 \r\n");
|
||
// // ftt.append_log(log);
|
||
// if (m_glue.m_deviceevent)
|
||
// m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, log);
|
||
// log = "";
|
||
// }
|
||
// memcpy((s == 0 ? ¶m.OffsetF[0] : ¶m.OffsetB[0]), offsets, sizeof(param.OffsetF));
|
||
// // memset(¶m.OffsetF[0],0,sizeof(param.OffsetF));
|
||
// // memset(¶m.OffsetB[0],0,sizeof(param.OffsetF));
|
||
// // param.OffsetB[5] =255;
|
||
// // param.OffsetF[4] =255;
|
||
// }
|
||
|
||
// if (isNeedSave)
|
||
// {
|
||
// printf("Save LUT image path :%s \n", param.Flat_BwPath.c_str());
|
||
// log = "暗场校正完成 \r\n";
|
||
// if (m_glue.m_deviceevent)
|
||
// m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, log);
|
||
// log = "";
|
||
// imwrite(param.Flat_BwPath, mrgmat);
|
||
// }
|
||
// }
|
||
// else // 明场
|
||
// {
|
||
// if (mode == IMAGE_COLOR)
|
||
// {
|
||
// volatile 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 (char j = 0; j < 3; j++)
|
||
// {
|
||
// values[0][j] = a.val[j];
|
||
// values[1][j] = b.val[j];
|
||
// printf("values[0][%d] = %.2f values[1][%d] = %.2f\n", j,values[0][j], j,values[1][j]);
|
||
// }
|
||
|
||
// log = "开始彩色明场校正 \r\n";
|
||
// if (m_glue.m_deviceevent)
|
||
// m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, log);
|
||
// for (int s = 0; s < 2; s++)
|
||
// {
|
||
// volatile int exposures[3]; // = (int *)(s == 0 ? param.ExposureF : param.ExposureB);
|
||
// memcpy((void *)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(*((double *)values + k));
|
||
// int diff = param.MaxBright - *((double *)values + k);
|
||
// log += " 明场:" + std::to_string(k) + ";diff:" + std::to_string(diff) + "\r\n";
|
||
|
||
// double step = diff * radio;
|
||
// int preStep = *((int *)expStep + k);
|
||
// if (step * preStep < 0)
|
||
// {
|
||
// step = 0 - preStep / 2;
|
||
// }
|
||
// if (step < 1 && step > 0)
|
||
// step = 1;
|
||
// if (step < 0 && step > -1)
|
||
// step = -1;
|
||
|
||
// bool isMinStep = abs(step) <= 2 && 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 ? ¶m.ExposureF[0] : ¶m.ExposureB[0]), (void *)exposures, sizeof(param.ExposureB));
|
||
// }
|
||
// // ftt.append_log(log);
|
||
// if (m_glue.m_deviceevent)
|
||
// m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, log);
|
||
|
||
// if (isNeedSave)
|
||
// {
|
||
// log = "彩色明场校正完成\r\n";
|
||
// if (m_glue.m_deviceevent)
|
||
// m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, 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];
|
||
// printf("values[0] = %.2f values[1] = %.2f\n", values[0], values[1]);
|
||
// log = "-----开始灰色明场校正-----\r\n";
|
||
// log += " 灰色扫描灰度明场均值:" + to_string(values[0]) + "," + to_string(values[1]) + "\r\n";
|
||
// if (m_glue.m_deviceevent)
|
||
// m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, log);
|
||
// for (int s = 0; s < 2; s++)
|
||
// {
|
||
// int *exposures = (int *)(s == 0 ? param.ExposureF : param.ExposureB);
|
||
// //int diff = LIGHT_DIFF(values[s]);
|
||
// int diff = param.MaxBright - values[s];
|
||
// double step = diff * radio;
|
||
// log += " 明场:" + to_string(s) + ";diff:" + to_string(diff) + "\r\n";
|
||
// int preStep = expStep[s][0];
|
||
// if (step * preStep < 0)
|
||
// {
|
||
// step = 0 - preStep / 2;
|
||
// }
|
||
// else
|
||
// {
|
||
// radio = 1;
|
||
// }
|
||
// 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) <= 2 && 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] = {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;
|
||
// }
|
||
// }
|
||
// // ftt.append_log(log);
|
||
// if (m_glue.m_deviceevent)
|
||
// m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, log);
|
||
// if (isNeedSave)
|
||
// {
|
||
// printf("Save LUT image path :%s \n", param.Flat_WhitePath.c_str());
|
||
// log = "灰度明场校正完成\r\n";
|
||
// if (m_glue.m_deviceevent)
|
||
// m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, log);
|
||
// log = "";
|
||
// imwrite(param.Flat_WhitePath, mrgmat);
|
||
// }
|
||
// }
|
||
// }
|
||
// SaveFpgaparam(param);
|
||
// printf("exit Save_lut \n");
|
||
// return isNeedSave;
|
||
return 0;
|
||
}
|
||
|
||
void MultiFrameCapture::formatStep()
|
||
{
|
||
for (int i = 0; i < 2; i++)
|
||
{
|
||
for (int j = 0; j < 3; j++)
|
||
{
|
||
expStep[i][j] = 600;
|
||
}
|
||
}
|
||
for (int i = 0; i < 12; i++)
|
||
offsetStep[i] = 64;
|
||
}
|
||
|
||
void MultiFrameCapture::correctcolor(int correctmode)
|
||
{
|
||
StopWatch sw_correct;
|
||
std::string loginfo = "Start Correctcolor 200DPI COLOR \r\n";
|
||
if ((correctmode == 0) || (correctmode == 2))
|
||
{
|
||
loginfo = "Start Correctcolor 200DPI COLOR \r\n";
|
||
if (m_glue.m_deviceevent)
|
||
m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, loginfo);
|
||
creatcorrectconfig(0x01, IMAGE_COLOR);
|
||
loginfo = "-----------200DPI COLOR Correct Done----------- \r\n\r\n ";
|
||
if (m_glue.m_deviceevent)
|
||
m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, loginfo);
|
||
}
|
||
if ((correctmode == 0) || (correctmode == 1))
|
||
{
|
||
loginfo = "Start Correctcolor 200DPI GRAY \r\n";
|
||
if (m_glue.m_deviceevent)
|
||
m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, loginfo);
|
||
creatcorrectconfig(0x01, IMAGE_GRAY);
|
||
loginfo = "-----------200DPI Gray Correct Done----------- \r\n\r\n";
|
||
if (m_glue.m_deviceevent)
|
||
m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, loginfo);
|
||
}
|
||
if ((correctmode == 0) || (correctmode == 4))
|
||
{
|
||
loginfo = " Start Correctcolor 300DPI COLOR \r\n";
|
||
if (m_glue.m_deviceevent)
|
||
m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, loginfo);
|
||
creatcorrectconfig(0x02, IMAGE_COLOR);
|
||
loginfo = "-----------300DPI COLOR Correct Done----------- \r\n\r\n ";
|
||
if (m_glue.m_deviceevent)
|
||
m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, loginfo);
|
||
}
|
||
if ((correctmode == 0) || (correctmode == 3))
|
||
{
|
||
loginfo = "Start Correctcolor 300DPI GRAY \r\n";
|
||
if (m_glue.m_deviceevent)
|
||
m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, loginfo);
|
||
creatcorrectconfig(0x02, IMAGE_GRAY);
|
||
loginfo = "-----------300DPI Gray Correct Done----------- \r\n\r\n ";
|
||
if (m_glue.m_deviceevent)
|
||
m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, loginfo);
|
||
}
|
||
if ((correctmode == 0) || (correctmode == 6))
|
||
{
|
||
loginfo = "Start Correctcolor 600DPI COLOR \r\n";
|
||
if (m_glue.m_deviceevent)
|
||
m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, loginfo);
|
||
creatcorrectconfig(0x03, IMAGE_COLOR);
|
||
loginfo = "-----------600DPI COLOR Correct Done----------- \r\n\r\n";
|
||
if (m_glue.m_deviceevent)
|
||
m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, loginfo);
|
||
}
|
||
if ((correctmode == 0) || (correctmode == 5))
|
||
{
|
||
loginfo = " Start Correctcolor 600DPI GRAY \r\n";
|
||
if (m_glue.m_deviceevent)
|
||
m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, loginfo);
|
||
creatcorrectconfig(0x03, IMAGE_GRAY);
|
||
loginfo = "-----------600DPI Gray Correct Done----------- \r\n\r\n ";
|
||
if (m_glue.m_deviceevent)
|
||
m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, loginfo);
|
||
}
|
||
if ((correctmode < 0) || (correctmode > 6))
|
||
{
|
||
loginfo = "不支持的校正模式...\r\n";
|
||
if (m_glue.m_deviceevent)
|
||
m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, loginfo);
|
||
}
|
||
if (m_glue.m_deviceevent)
|
||
m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLAT_FINISHED, "******Correct Done times = " + to_string(sw_correct.elapsed_s()) + " ****** \r\n");
|
||
}
|
||
|
||
void MultiFrameCapture::openDevice(int dpi, int mode)
|
||
{
|
||
reset_fpga();
|
||
bool dunnancis = true;
|
||
int channelwidth = dpi == 0x02 ? 864 : (dpi == 0x03 ? 1728 : 864); // 1296 2592 864
|
||
int channels = mode == 0x01 ? 3 : 1;
|
||
int width = channelwidth * channels;
|
||
int frame_height = mode == 0x01 ? 60 * 3 : 60;
|
||
int startsample = 202; // 205
|
||
auto fpgaparam = GetFpgaparam(dpi, mode);
|
||
int t_real_dpi = dpi == 1 ? 2 : (dpi == 2 ? 2 : 3);
|
||
ModeFpga fpgamod = {
|
||
.colorMode = mode,
|
||
.dpi = t_real_dpi,
|
||
.led = 1,
|
||
.sample = startsample, // 256+39
|
||
.adcA = 0,
|
||
.adcB = 0,
|
||
.selftest = 0,
|
||
.sp = fpgaparam.Sp}; // 600DPI 0x1450 300DPI 0xe10
|
||
|
||
configFPGAParam(mode, dpi);
|
||
StopWatch swwv4l2open;
|
||
int ret = video->open_video(width, 60 * 2); // 300dpi 7344/2 600dpi 7344 //FRAME_HEIGHT * 2
|
||
//int ret = video->open(); // 300dpi 7344/2 600dpi 7344 //FRAME_HEIGHT * 2
|
||
if (ret < 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
printf("opened video with width = %d height = %d time eplased = %.2f \n", width, 60 * 2, swwv4l2open.elapsed_ms());
|
||
// m_capFpageregs->setFrameHeight(12);
|
||
m_capFpageregs->setFrameNum(1);
|
||
m_capFpageregs->setFrameHeight(frame_height);
|
||
for (int i = 0; i < 1; i++)
|
||
{
|
||
m_capFpageregs->capture(); // abort first frame
|
||
|
||
// video->read_frame(200);
|
||
char *buf = NULL;
|
||
video->HtCamReadCaptureFrame((void **)&buf, 200);
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||
printf("abort first frame \n");
|
||
}
|
||
video->close_video();
|
||
}
|
||
|
||
void MultiFrameCapture::creatcorrectconfig(int dpi, int mode)
|
||
{
|
||
openDevice(dpi, mode);
|
||
bool isDone = false;
|
||
formatStep();
|
||
int i = 0;
|
||
radio = 1;
|
||
while (!isDone) // 先暗场
|
||
{
|
||
string log = "==============================第" + to_string(i) + "次===============================\r\n";
|
||
// ftt.append_log(log);
|
||
if (m_glue.m_deviceevent)
|
||
m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, log);
|
||
configFPGAParam(mode, dpi);
|
||
// ftt.append_log(log);
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||
m_capFpageregs->enableLed(false);
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||
m_capFpageregs->capture();
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||
isDone = saveLutImg(dpi, mode, true); // 0 color_black 1 color_white 2 gray_balck 3 gray_white
|
||
i++;
|
||
}
|
||
isDone = false;
|
||
formatStep();
|
||
while (!isDone) // 后明场
|
||
{
|
||
configFPGAParam(mode, dpi);
|
||
string log = "==============================第" + to_string(i) + "次===============================\r\n";
|
||
// ftt.append_log(log);
|
||
if (m_glue.m_deviceevent)
|
||
m_glue.m_deviceevent((int)HG_ScannerStatus::AUTO_FLATTING, log);
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||
m_capFpageregs->enableLed(true);
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||
m_capFpageregs->capture();
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||
isDone = saveLutImg(dpi, mode, false);
|
||
i++;
|
||
}
|
||
printf("creatcorrectconfig %s \n", (mode == IMAGE_COLOR ? " Color" : " Gray"));
|
||
creatLUTData(dpi, mode);
|
||
video->close_video();
|
||
}
|
||
|
||
// void MultiFrameCapture::myFloodFill(cv::Mat& image, bool isTwoSide)
|
||
// {
|
||
// int w = image.cols;
|
||
// int h = image.rows;
|
||
// cv::Vec3b lt, rt, lb, rb;
|
||
// const double threshold = 10;
|
||
|
||
// if (!isTwoSide)
|
||
// {
|
||
// lt = image.channels() == 3 ? image.at<cv::Vec3b>(0, 0) : image.at<uchar>(0, 0);
|
||
// if (lt[0] < threshold && lt[1] < threshold && lt[2] < threshold)
|
||
// cv::floodFill(image, cv::Point(0, 0), cv::Scalar::all(255), 0, cv::Scalar::all(5), cv::Scalar::all(40), cv::FLOODFILL_FIXED_RANGE);
|
||
|
||
// rt = image.channels() == 3 ? image.at<cv::Vec3b>(0, w - 1) : image.at<uchar>(0, w - 1);
|
||
// if (rt[0] < threshold)
|
||
// cv::floodFill(image, cv::Point(w - 1, 0), cv::Scalar::all(255), 0, cv::Scalar::all(5), cv::Scalar::all(40), cv::FLOODFILL_FIXED_RANGE);
|
||
|
||
// lb = image.channels() == 3 ? image.at<cv::Vec3b>(h - 1, 0) : image.at<uchar>(h - 1, 0);
|
||
// if (lb[0] < threshold)
|
||
// cv::floodFill(image, cv::Point(0, h - 1), cv::Scalar::all(255), 0, cv::Scalar::all(5), cv::Scalar::all(40), cv::FLOODFILL_FIXED_RANGE);
|
||
|
||
// rb = image.channels() == 3 ? image.at<cv::Vec3b>(h - 1, w - 1) : image.at<uchar>(h - 1, w - 1);
|
||
// if (rb[0] < threshold)
|
||
// cv::floodFill(image, cv::Point(w - 1, h - 1), cv::Scalar::all(255), 0, cv::Scalar::all(5), cv::Scalar::all(40), cv::FLOODFILL_FIXED_RANGE);
|
||
// }
|
||
// else
|
||
// {
|
||
// int w_ = w / 2;
|
||
// lt = image.channels() == 3 ? image.at<cv::Vec3b>(0, 0) : image.at<uchar>(0, 0);
|
||
// if (lt[0] < threshold && lt[1] < threshold && lt[2] < threshold)
|
||
// cv::floodFill(image, cv::Point(0, 0), cv::Scalar::all(255), 0, cv::Scalar::all(5), cv::Scalar::all(40), cv::FLOODFILL_FIXED_RANGE);
|
||
|
||
// rt = image.channels() == 3 ? image.at<cv::Vec3b>(0, w_ - 1) : image.at<uchar>(0, w_ - 1);
|
||
// if (rt[0] < threshold && rt[1] < threshold && rt[2] < threshold)
|
||
// cv::floodFill(image, cv::Point(w_ - 1, 0), cv::Scalar::all(255), 0, cv::Scalar::all(5), cv::Scalar::all(40), cv::FLOODFILL_FIXED_RANGE);
|
||
|
||
// lb = image.channels() == 3 ? image.at<cv::Vec3b>(h - 1, 0) : image.at<uchar>(h - 1, 0);
|
||
// if (lb[0] < threshold && lb[1] < threshold && lb[2] < threshold)
|
||
// cv::floodFill(image, cv::Point(0, h - 1), cv::Scalar::all(255), 0, cv::Scalar::all(5), cv::Scalar::all(40), cv::FLOODFILL_FIXED_RANGE);
|
||
|
||
// rb = image.channels() == 3 ? image.at<cv::Vec3b>(h - 1, w_ - 1) : image.at<uchar>(h - 1, w_ - 1);
|
||
// if (rb[0] < threshold && rb[1] < threshold && rb[2] < threshold)
|
||
// cv::floodFill(image, cv::Point(w_ - 1, h - 1), cv::Scalar::all(255), 0, cv::Scalar::all(5), cv::Scalar::all(40), cv::FLOODFILL_FIXED_RANGE);
|
||
|
||
// lt = image.channels() == 3 ? image.at<cv::Vec3b>(0, w_) : image.at<uchar>(0, w_);
|
||
// if (lt[0] < threshold && lt[1] < threshold && lt[2] < threshold)
|
||
// cv::floodFill(image, cv::Point(w_, 0), cv::Scalar::all(255), 0, cv::Scalar::all(5), cv::Scalar::all(40), cv::FLOODFILL_FIXED_RANGE);
|
||
|
||
// rt = image.channels() == 3 ? image.at<cv::Vec3b>(0, w - 1) : image.at<uchar>(0, w - 1);
|
||
// if (rt[0] < threshold && rt[1] < threshold && rt[2] < threshold)
|
||
// cv::floodFill(image, cv::Point(w - 1, 0), cv::Scalar::all(255), 0, cv::Scalar::all(5), cv::Scalar::all(40), cv::FLOODFILL_FIXED_RANGE);
|
||
|
||
// lb = image.channels() == 3 ? image.at<cv::Vec3b>(h - 1, w_) : image.at<uchar>(h - 1, w_);
|
||
// if (lb[0] < threshold && lb[1] < threshold && lb[2] < threshold)
|
||
// cv::floodFill(image, cv::Point(w_, h - 1), cv::Scalar::all(255), 0, cv::Scalar::all(5), cv::Scalar::all(40), cv::FLOODFILL_FIXED_RANGE);
|
||
|
||
// rb = image.channels() == 3 ? image.at<cv::Vec3b>(h - 1, w - 1) : image.at<uchar>(h - 1, w - 1);
|
||
// if (rb[0] < threshold && rb[1] < threshold && rb[2] < threshold)
|
||
// cv::floodFill(image, cv::Point(w - 1, h - 1), cv::Scalar::all(255), 0, cv::Scalar::all(5), cv::Scalar::all(40), cv::FLOODFILL_FIXED_RANGE);
|
||
// }
|
||
// }
|
||
|
||
void MultiFrameCapture::init_imagedatabuffer()
|
||
{
|
||
#ifndef TEST_SIMCAP
|
||
printf("pimgdata_info.pdata = %p \n", pimgdata_info.pdata);
|
||
if (pimgdata_info.pdata)
|
||
{
|
||
free(pimgdata_info.pdata);
|
||
pimgdata_info.pdata = nullptr;
|
||
}
|
||
if (frame_count != 0)
|
||
{
|
||
int real_dpi = m_capFpageregs->getDpi();
|
||
int mode = m_capFpageregs->getColorMode();
|
||
int t_frame_count = m_capFpageregs->getFrameNum();
|
||
int width = real_dpi == 0x02 ? 5184 : (real_dpi == 0x03 ? 10368 : 3456);
|
||
if ((m_config.params.pageSize == 17 || m_config.params.pageSize == 19) && m_config.params.dpi != 2)
|
||
width = m_config.params.dpi == 3 ? 20736 : 3456; // 10368*2:3456
|
||
|
||
int per_frame_bytes = frame_height * width;
|
||
int total_buffer_need = t_frame_count * per_frame_bytes;
|
||
pimgdata_info.pdata = malloc(total_buffer_need);
|
||
if (!pimgdata_info.pdata)
|
||
printf("!!!!!!!! error malloc buffer failed! \n");
|
||
pimgdata_info.total_dst = total_buffer_need;
|
||
pimgdata_info.offset = 0;
|
||
pimgdata_info.frame_count = 0;
|
||
printf("pimgdata_info.pdata = %p malloc_size = %d per_frame_bytes = %d \n", pimgdata_info.pdata, total_buffer_need, per_frame_bytes);
|
||
}
|
||
#endif
|
||
}
|
||
|
||
// void MultiFrameCapture::update_imgdatainfo(cv::Mat itemmat)
|
||
// {
|
||
// if (pimgdata_info.pdata)
|
||
// {
|
||
// if (!itemmat.empty())
|
||
// {
|
||
// // printf("pimgdata_info.pdata = %p offset = %d item_total = %d \n", pimgdata_info.pdata, pimgdata_info.offset, itemmat.total()*itemmat.elemSize());
|
||
// memcpy(pimgdata_info.pdata + pimgdata_info.offset, (void *)itemmat.data, itemmat.total() * itemmat.elemSize());
|
||
// pimgdata_info.offset += itemmat.total() * itemmat.elemSize();
|
||
// pimgdata_info.frame_count++;
|
||
// }
|
||
// }
|
||
// }
|
||
void MultiFrameCapture::reset_imagedata()
|
||
{
|
||
if (pimgdata_info.pdata)
|
||
{
|
||
memset(pimgdata_info.pdata, 0, pimgdata_info.offset);
|
||
pimgdata_info.offset = 0;
|
||
pimgdata_info.frame_count = 0;
|
||
}
|
||
}
|