zynq_7010/MultiFrameCapture.cpp

1307 lines
55 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

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

#include "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 ? &param.OffsetF[0] : &param.OffsetB[0]);
// memcpy(offsets, (s == 0 ? &param.OffsetF[0] : &param.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 ? &param.OffsetF[0] : &param.OffsetB[0]), offsets, sizeof(param.OffsetF));
// // memset(&param.OffsetF[0],0,sizeof(param.OffsetF));
// // memset(&param.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 ? &param.ExposureF[0] : &param.ExposureB[0]), sizeof(param.ExposureB));
// for (int x = 0; x < 3; x++)
// {
// int k = (3 * s + x);
// //int diff = LIGHT_DIFF(*((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 ? &param.ExposureF[0] : &param.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;
}
}