调整7010设备协议

This commit is contained in:
13038267101 2023-09-22 14:17:06 +08:00
parent 5f03c3f529
commit bc6243c4a0
7 changed files with 575 additions and 88 deletions

View File

@ -10,6 +10,7 @@
#include <vector>
#include <map>
#include "sane/sane_option_definitions.h"
#include <opencv2/opencv.hpp>
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 硬件配置项定义
//
@ -702,6 +703,26 @@ namespace setting_hardware
//硬件协议定义 -OVER
namespace setting3288dsp
{
union FLAT_INFO
{
struct
{
unsigned int dpi : 5;
unsigned int colormode : 1;
unsigned int is_whiteimage : 1;
unsigned int status : 8;
unsigned int reversed : 1;
unsigned int datalen : 16;
}params;
unsigned int value;
};
struct FLAT_INFO_IMAGE
{
FLAT_INFO info;
cv::Mat flat_lut;
};
struct HG_JpegCompressInfo
{
unsigned int data_type;
@ -914,7 +935,8 @@ namespace setting3288dsp
GETMOTORPARAM = 0x202,
GETMOTORPARMLEN = 0x203,
SETMOTORPARAM = 0x204,
SETMOTORPARAMLEN = 0x205
SETMOTORPARAMLEN = 0x205,
DEVICES_7010 = 0x7010
};
typedef enum tagUsbKeyWords UsbKeyWords, * PUsbKeyWords;
//G300 G400 纸张类型协议 注只支持3288 300 400

View File

@ -3025,6 +3025,14 @@ hg_imgproc::IMGPRCPARAM hg_scanner::get_image_process_object(int model)
param.double_side = img_conf_.is_duplex;
param.dpi = img_conf_.resolution_dst;
param.cis_image = is_cis_image;
param.width = 0; //目前只有7010使用到了
param.height = 0 ;
if(firmware_sup_device_7010)
{
param.width = mat_width;
param.height = mat_height;
}
param.device_7010 = firmware_sup_device_7010;
//img_conf_.brightness = (float)bright_;
//img_conf_.contrast = (float)contrast_;
@ -4856,7 +4864,8 @@ void hg_scanner::image_process(std::shared_ptr<tiny_buffer>& buffer, uint32_t id
void* buf = NULL;
hg_imgproc::load_buffer(ImagePrc_pHandle_, buffer);
hg_imgproc::decode(ImagePrc_pHandle_, pid_, &img_conf_, &param);
hg_imgproc::decode(ImagePrc_pHandle_, pid_, &img_conf_, &param, correction_image_map_);
(this->*dump_img_)(ImagePrc_pHandle_, "decode");
if (is_dpi_color_check)

View File

@ -384,6 +384,9 @@ protected:
bool firmware_sup_morr_; //固件支持 摩尔纹 139 239-3C0518
bool firmware_sup_color_fill_; //固件支持 色彩填充 139 239 439 -3C
bool firmware_sup_history_cnt; //固件支持 清除历史张数 3288 G300 220303
bool firmware_sup_device_7010; //G300 设备但是7010 2023/9/21
int mat_width;
int mat_height;
SCANCONF img_conf_; //此参数外部不做任何改变请在writedown_image_configuration做修改
std::string img_type_;
@ -399,6 +402,8 @@ protected:
int stop_fatal_;
BlockingQueue<std::shared_ptr<tiny_buffer>> imgs_;
std::map<int, setting3288dsp::FLAT_INFO_IMAGE>correction_image_map_;
uint32_t fetching_id_; // for sane read image ext info. added on 2023-01-13
void change_setting_language(bool init);

View File

@ -81,27 +81,43 @@ hg_scanner_300::hg_scanner_300(const char* dev_name,int pid, usb_io* io) :
hg_scanner(G100Serial, dev_name, io,pid)
,papersize(pid)
,is_devs_sleep_(false)
,pdata(NULL)
,index_ (0)
, first_frame_total(0)
, last_frame_total(0)
{
dsp_config.value = 0;
dsp_config.params_3288.enableLed = 1; //默认值
dsp_config.params_3288.isCorrect = 1;
initdevice();
int ret = get_device_type(firmware_sup_device_7010);
if (firmware_sup_device_7010 && ret == SCANNER_ERR_OK)
{
get_correction_image(0, 1, 1);
get_correction_image(1, 1, 0);
get_correction_image(2, 2, 1);
get_correction_image(3, 2, 0);
get_correction_image(4, 3, 1);
get_correction_image(5, 3, 0);
}
else
{
initdevice();
std::string fv(get_firmware_version()),
sn(get_serial_num());
if (fv.empty() || sn.empty())
return;
std::string fv(get_firmware_version()),
sn(get_serial_num());
if (fv.empty() || sn.empty())
return;
string dev = fv.substr(0, 2);
string ver = fv.substr(2, 3);
string date = fv.substr(5, 5);
string year = fv.substr(4, 2);
string devType;
string year_date = fv.substr(4, 6);
string dev = fv.substr(0, 2);
string ver = fv.substr(2, 3);
string date = fv.substr(5, 5);
string year = fv.substr(4, 2);
string devType;
string year_date = fv.substr(4, 6);
firmware_sup_morr_ = year_date.compare("230724") >= 0 ? true : false;
}
firmware_sup_morr_ = year_date.compare("230724") >= 0 ? true : false;
#ifndef MAPPING_FUNCTION_IN_BASE
init_setting_map(setting_map_, ARRAY_SIZE(setting_map_));//优先初始化
@ -253,6 +269,17 @@ void hg_scanner_300::thread_handle_usb_read(void)
}
if (ret == SCANNER_ERR_OK && usb.u32_Count > 0)
{
if (firmware_sup_device_7010)
{
ret = get_img_data_7010();
if (ret != SCANNER_ERR_OK)
{
status_ = ret;
break;
}
continue;
}
int totalNum = usb.u32_Count & 0x3fffffff; // 2022-08-04: 兼容Android默认图片大小均在1GB以内
VLOG_MINI_2(LOG_LEVEL_WARNING, "Get Scaner Image Size:%d bytes,Image Num[%d]\n", totalNum,img_num);
img_num++;
@ -553,92 +580,70 @@ int hg_scanner_300::get_img_data(std::shared_ptr<tiny_buffer> &imagedata)
return status_ = ret;
}
int hg_scanner_300::get_img_data_7010(std::shared_ptr<tiny_buffer>& imagedata)
static int k = 0;
int hg_scanner_300::get_img_data_7010()
{
int total = imagedata->size(),
ret = SCANNER_ERR_OK,
index = 0,
block = total;
int ret = SCANNER_ERR_OK;
USBCB usb{ setting3288dsp::GET_IMAGE, 0, total };
USBCB usb{ setting3288dsp::GET_IMAGE, 0, 0 };
{
std::lock_guard<std::mutex> lock(io_lock_);
ret = writeusb(usb);
io_->set_timeout(800);
setting3288dsp::HG_JpegCompressInfo info;
int len = sizeof(int) * 7;
StopWatch sw;
sw.reset();
int len = sizeof(int) * 8;
ret = io_->read_bulk(&info, &len);
std::vector<unsigned char> jpgdata;
jpgdata.resize(info.DataLength);
ret = io_->read_bulk(&jpgdata[0], (int*)&info.DataLength);
int val = info.DataLength;
int width = info.width;
int hegiht = info.height;
int frame_total = info.index_frame;
//cv::Mat mat1 = cv::Mat(hegiht, width, CV_8UC1, jpgdata.data(), cv::Mat::AUTO_STEP);
//static int cnt = 0;
if (info.first_frame)
{
pdata = (char*)malloc(width * hegiht * frame_total);
first_frame_total = info.index_frame;
jpgdata_.clear();
jpgdata_.resize(width * hegiht * first_frame_total);
index_ = 0;
}
cv::ImreadModes rmc = cv::IMREAD_GRAYSCALE;
cv::Mat mat(cv::imdecode(jpgdata, rmc));
//cv::imwrite("C://Users//modehua//Desktop//image//opencv"+to_string(cnt)+".jpg", mat);
//cnt++;
if (!pdata)
{
return SCANNER_ERR_INSUFFICIENT_MEMORY;
}
memcpy(pdata + index_, (void*)mat.data, mat.total() * mat.elemSize());
index_ += mat.total() * mat.elemSize();
ret = io_->read_bulk(&jpgdata_[index_], &val);
index_ += val;
if (info.last_frame)
{
cv::Mat mat = cv::Mat(hegiht * frame_total, width, CV_8UC1, pdata, cv::Mat::AUTO_STEP);
//cv::imwrite("C://Users//modehua//Desktop//image//2_opencv.jpg", mat);
if (mat.empty())
{
return SCANNER_ERR_INSUFFICIENT_MEMORY;
}
int width = mat.cols;
int height = mat.rows;
cv::Mat m_dst = mat;
if (image_prc_param_.bits.color_mode == 2)
{
width = mat.cols / 3;
height = mat.rows;
m_dst = cv::Mat(height, width, CV_8UC3);
std::vector<cv::Mat> m_items;
//return 0;
last_frame_total = info.index_frame;
for (size_t i = 0; i < 3; i++)
{
cv::Mat t_item(mat(cv::Rect(width * i, 0, width, height)));
m_items.push_back(t_item);
}
cv::merge(m_items, m_dst);
}
int frame_ind = first_frame_total - last_frame_total;
cv::imwrite("C://Users//modehua//Desktop//image//1_opencv.jpg", m_dst);
std::shared_ptr<tiny_buffer> image_data_(aquire_memory(width * hegiht * frame_total));
mat_width = width;
mat_height = (hegiht * first_frame_total) - (hegiht * frame_ind);
std::shared_ptr<tiny_buffer> image_data_(aquire_memory(mat_width * mat_height));
unsigned int size = width * hegiht * frame_total;// bmpdata.size();
void* l = image_data_->data(0, &size);
memcpy(l, m_dst.data, width * hegiht * frame_total);
unsigned int size1 = mat_height;
void* l = image_data_->data(0, &size1);
memcpy(l, jpgdata_.data(), mat_width * mat_height);
//ret = save_usb_data(image_data_);
//cv::Mat mat = cv::Mat(hegiht * first_frame_total, width, CV_8UC1, jpgdata_.data(), cv::Mat::AUTO_STEP);
//cv::imwrite("C://image//get_img_data_7010" + to_string(k) + ".jpg", mat);
k++;
ret = save_usb_data(image_data_);
index_ = 0;
if (pdata)
{
free(pdata);
}
std::vector<unsigned char>().swap(jpgdata_); //回收空间 clear只能清空元素
}
return SCANNER_ERR_OK;
float v = sw.elapsed_ms();
return ret;
}
}
int hg_scanner_300::writedown_device_configuration(bool type,setting_hardware::HGSCANCONF_3288 *d)
@ -922,6 +927,103 @@ void hg_scanner_300::printf_devconfig(setting_hardware::HGSCANCONF_3288 *d)
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO,"dsp_config.params_3288.enableSizeDetect:%d\r\n",d->params_3288.enableSizeDetect);
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO,"dsp_config.params_3288.value:%d\r\n",d->value);
}
int hg_scanner_300::get_device_type(bool &type)
{
int ret = SCANNER_ERR_OK;
USBCB cmd = { setting3288dsp::DEVICES_7010,0,0, };
{
std::lock_guard<std::mutex> lock(io_lock_);
ret = writeusb(cmd);
if (ret == SCANNER_ERR_OK)
ret = readusb(cmd);
if (ret)
return ret;
type = cmd.u32_Data;
}
return ret;
}
int hg_scanner_300::get_correction_image(int inx , int dpi, int mode)
{
int ret = SCANNER_ERR_OK;
setting3288dsp::FLAT_INFO_IMAGE image_info;
image_info.info.params.dpi = dpi;
image_info.info.params.colormode = mode;
cv::Mat white_mat;
cv::Mat black_mat;;
for (size_t i = 0; i < 2; i++) //黑白一起保存下来
{
vector<unsigned char> imagedata;
image_info.info.params.is_whiteimage = i;
int val = image_info.info.value;
USBCB cmd = { setting3288dsp::GET_FLAT_DATA,val,0, };
{
std::lock_guard<std::mutex> lock(io_lock_);
ret = writeusb(cmd);
if (ret == SCANNER_ERR_OK)
ret = readusb(cmd);
if (ret)
return ret;
image_info.info.value = cmd.u32_Data;
if (image_info.info.params.status != 100)
{
VLOG_MINI_1(LOG_LEVEL_WARNING, "get_correction_image status:%d\n", image_info.info.params.status);
return SCANNER_ERR_NO_DATA;
}
int len = image_info.info.params.datalen;
imagedata.resize(len);
if (ret == SCANNER_ERR_OK)
ret = io_->read_bulk(&imagedata[0], &len);
if (imagedata.empty())
{
return SCANNER_ERR_NO_DATA;
}
cv::ImreadModes rmc = image_info.info.params.colormode ? cv::IMREAD_COLOR : cv::IMREAD_GRAYSCALE;
cv::Mat mat = cv::imdecode(imagedata, rmc);//color BGR
//if (mat.channels() == 3)
//cv::cvtColor(mat, mat, CV_BGR2RGB);
if (mat.empty())
{
VLOG_MINI_1(LOG_LEVEL_WARNING, "get_correction_image image is NULL:%d\n", image_info.info.params.status);
return SCANNER_ERR_NO_DATA; //只要有一张图没有 直接退了
}
if (i)
white_mat = mat;
else
black_mat = mat;
}
}
//cv::imwrite("C://image//correction_image_white_mat" + to_string(inx) + ".bmp", white_mat);
//cv::imwrite("C://image//correction_image_black_mat" + to_string(inx) + ".bmp", black_mat);
ret = hg_imgproc::correction_image(ImagePrc_pHandle_, image_info.flat_lut, black_mat, white_mat);
for (size_t j = 0; j < correction_image_map_.size(); j++) //以防重复添加
{
if (correction_image_map_[j].info.params.dpi == dpi
&& correction_image_map_[j].info.params.colormode == mode)
{
return ret;
}
}
correction_image_map_[inx] = image_info;
return ret;
}
std::string hg_scanner_300::get_firmware_version()
{
char buf[20] = { 0 };

View File

@ -60,17 +60,32 @@ private:
int pop_image(void);
int get_scanner_status(USBCB &usb);
int get_img_data(std::shared_ptr<tiny_buffer> &imagedata);
int get_img_data_7010(std::shared_ptr<tiny_buffer>& imagedata);
int get_img_data_7010();
int writedown_device_configuration(bool type =false,setting_hardware::HGSCANCONF_3288 *d = NULL);
void writedown_image_configuration(void);
void printf_devconfig(setting_hardware::HGSCANCONF_3288 *d = NULL);
int get_device_type(bool &type);
setting3288dsp::HG_JpegCompressInfo frame_info_;
///////////////////////7010专有协议获取校正数据//////////////////////
//inx:序号//
//dpi:1--->200 2--->300 3--->600//
//mode:0 灰度 1彩色
int get_correction_image(int inx ,int dpi,int mode);
private:
std::vector<int> savestatus_;
setting_hardware::HGSCANCONF_3288 dsp_config;
Device::PaperSize papersize;
bool is_devs_sleep_;
int first_frame_total; //设置的帧数
int last_frame_total; //实际采集的帧数
std::vector<unsigned char> jpgdata_;
int index_;
char* pdata;
public:
//////////////固定的硬件信息设置或获取//////////////
virtual std::string get_firmware_version(void)override;

View File

@ -226,7 +226,7 @@ namespace hg_imgproc
,Dynamicopen_HGImageprc_pHandle_(NULL),isx86_Advan_(isx86_Advan)
{
if(!isx86_Advan_ || hg_log::ini_get("opencv", "speed-first") == "1")
cv::setUseOptimized(isx86_Advan_); //寮€鍏砪pu楂樼骇鎸囦护闆?
cv::setUseOptimized(isx86_Advan_);
}
~imgproc()
{
@ -446,7 +446,7 @@ namespace hg_imgproc
return SCANNER_ERR_OK;
}
int decode(int pid, LPSCANCONF img_param, LPIMGPRCPARAM param)
int decode(int pid, LPSCANCONF img_param, LPIMGPRCPARAM param, std::map<int, setting3288dsp::FLAT_INFO_IMAGE>& correction_image_map_)
{
if (!buffer_)
return SCANNER_ERR_NO_DATA;
@ -492,11 +492,61 @@ namespace hg_imgproc
rmc = cv::IMREAD_COLOR;
}
cv::Mat mat;
if (true)
bool f = true;
if (!param_.device_7010)/////只有7010需要从设备获取校正数据
mat = cv::imdecode(*buf, rmc);
else
mat = cv::Mat(512 * 5, 15552 / 3, CV_8UC1, buf->data(), cv::Mat::AUTO_STEP).clone();
//cv::imwrite("C:\\Users\\modehua\\Desktop\\image\\imdecode.jpg",mat);
{
static int img_idx = 0;
cv::Mat ds(param_.height, param_.width, CV_8UC1, buf->data(), cv::Mat::AUTO_STEP);
//cv::imwrite("C:\\image\\imdecode"+std::to_string(img_idx++) + ".jpg", ds);
cv::Mat m_dst(ds(cv::Rect(0, 2, ds.cols, ds.rows - 2))); //删除前几行 一定按照实际测试来,因为最上面会有白边影响校正裁切等
cv::Mat d;
if (param_.channels == 3)
{
int mat_width = m_dst.cols / 3;
int mat_height = m_dst.rows;
d = cv::Mat(mat_width, mat_height, CV_8UC3);
std::vector<cv::Mat> m_items;
std::vector <int> list = { 0,2,1 }; //调整RGB顺序 opencv顺序是BRG
for (size_t i = 0; i < 3; i++)
{
cv::Mat t_item(m_dst(cv::Rect(mat_width * list[i], 0, mat_width, mat_height)));
m_items.push_back(t_item);
}
cv::merge(m_items, d);
mat = d.clone();
}
else
mat = m_dst.clone();
cv::imwrite("C:\\image\\imdecode" + std::to_string(img_idx++) + ".jpg", mat);
int dpi = param_.dpi == 600 ? 3 : (param_.dpi < 599 && param_.dpi >= 300) ? 2 : 1;
int mode = param_.color_mode == COLOR_MODE_24_BITS ? 1 : 0;
for (size_t i = 0; i < correction_image_map_.size(); i++)
{
if (correction_image_map_[i].info.params.colormode == mode && correction_image_map_[i].info.params.dpi == dpi)
{
if (correction_image_map_[i].info.params.status != 100)
{
break;
}
correctColor(mat, correction_image_map_[i].flat_lut);//校正
}
}
//cv::imwrite("C:\\image\\imdecode" + std::to_string(img_idx++) + ".jpg", mat);
if (param_.dpi < 299)/////7010不支持 200dpi 所以需要手动拉伸宽度
{
float xy = param_.dpi / 300.0;
cv::resize(mat, mat, cv::Size(), xy, 1);
}
}
//cv::imwrite("C:\\image\\imdecode4.png", mat);
//cv::imwrite("C:\\Users\\modehua\\Desktop\\image\\imdecode2.jpg",mat);
if (mat.empty())
{
@ -523,7 +573,7 @@ namespace hg_imgproc
catch (const std::exception& e)
{
LOG_INFO(LOG_LEVEL_FATAL, e.what());
throw(e); // 缁х画鎶涘埌涓婂眰澶勭悊銆?
throw(e);
}
}
@ -535,7 +585,7 @@ namespace hg_imgproc
if (pid_ == 0x100 || pid_ == 0x200 || pid_ == 0x300 || pid_ == 0x400 || pid == 0x402 || pid == 0x302)
{
//////闄ょ┛瀛旂畻娉曠Щ鑷宠В鍘嬪浘鍍忎箣鍚?
double left = img_conf_.fillholeratio_left / 100.0;
double right = img_conf_.fillholeratio_right / 100.0;
double top = img_conf_.fillholeratio_up / 100.0;
@ -601,7 +651,7 @@ namespace hg_imgproc
std::vector<cv::Mat> mats(mats_);
mats_.clear();
int colormode = 1; //默锟斤拷1
int colormode = 1;
if (img_conf_.filter == 3)
colormode = img_conf_.pixtype;
@ -1348,6 +1398,13 @@ namespace hg_imgproc
return ret;
//cv::imwrite("CISTestImageProcess.jpg",mats[i]);
}
int correction_image(cv::Mat &flat_lut, cv::Mat black_mat, cv::Mat white_mat)
{
flat_lut = creatLUTData(black_mat, white_mat);//计算LUT 查值表
return 0;
}
HGImage opencv_to_hgbase_image(const cv::Mat& mats)
{
HGImage image;
@ -1535,6 +1592,272 @@ namespace hg_imgproc
LOG_INFO(LOG_LEVEL_ALL, "No image output in image_process!\n");
}
}
float gamma(float value, float ex)
{
return cv::pow(value / 255.0f, 1.0f / ex) * 255.0f + 0.5f;
}
std::vector<double> caculate(const std::vector<double>& points_x, const std::vector<double>& points_y)
{
int MaxElement = points_x.size() - 1;
//计算常数f
double f = points_y[0];
//求解
int n, m;
// double a[MaxElement][MaxElement+1];
std::vector<std::vector<double>> a;
// a.resize(MaxElement);
for (int i = 0; i < MaxElement; i++)
{
std::vector<double> b;
b.resize(MaxElement + 1);
a.push_back(b);
}
for (int i = 0; i < MaxElement; i++)
{
for (int j = 0; j < MaxElement; j++)
a[i][j] = cv::pow(points_x[i + 1], MaxElement - j);
a[i][MaxElement] = points_y[i + 1] - f;
}
int i, j;
n = MaxElement;
for (j = 0; j < n; j++)
{
double max = 0;
double imax = 0;
for (i = j; i < n; i++)
{
if (imax < cv::abs(a[i][j]))
{
imax = cv::abs(a[i][j]);
max = a[i][j]; //得到各行中所在列最大元素
m = i;
}
}
if (cv::abs(a[j][j]) != max)
{
double b = 0;
for (int k = j; k < n + 1; k++)
{
b = a[j][k];
a[j][k] = a[m][k];
a[m][k] = b;
}
}
for (int r = j; r < n + 1; r++)
{
a[j][r] = a[j][r] / max; //让该行的所在列除以所在列的第一个元素目的是让首元素为1
}
for (i = j + 1; i < n; i++)
{
double c = a[i][j];
if (c == 0.0)
continue;
for (int s = j; s < n + 1; s++)
{
a[i][s] = a[i][s] - a[j][s] * c; //前后行数相减使下一行或者上一行的首元素为0
}
}
}
for (i = n - 2; i >= 0; i--)
{
for (j = i + 1; j < n; j++)
{
a[i][n] = a[i][n] - a[j][n] * a[i][j];
}
}
std::vector<double> result;
for (int k = 0; k < n; k++)
result.push_back(a[k][n]);
result.push_back(f);
return result;
}
//设置一面的offset值
void setOffset(int* config, int step)
{
for (int i = 0; i < 6; i++)
{
int* offset = config + i;
*offset += step;
if (*offset < 0)
*offset = 1;
if (*offset > 255)
*offset = 255;
}
}
cv::Mat extractRepresentRow2(const cv::Mat& src)
{
cv::Mat BWbalenceSrc(1, src.cols * src.channels(), CV_8UC1);
cv::Mat temp_imageBW(src.rows, src.cols * src.channels(), CV_8UC1, src.data);
for (size_t i = 0; i < BWbalenceSrc.cols; i++)
BWbalenceSrc.at<unsigned char>(0, i) = cv::mean(temp_imageBW(cv::Rect(i, 0, 1, temp_imageBW.rows)))[0];
return BWbalenceSrc;
}
#define GAMMA_EX 1.7f
#define BLACK_OFFSET 0
void fittingLUT(const std::vector<unsigned char>& points, unsigned char min_value, unsigned char max_value, unsigned char* data)
{
float step = max_value - min_value + 1;
memset(data, min_value, 127);
memset(data + 127, max_value, 129);
int b = points[0];
int w = points[1];
int tb = min_value;
int tw = max_value;
step = (cv::max)((float)(tw - tb + 1) / (float)(w - b + 1), 0.0f);
float temp;
for (int j = 0, length = (255 - b + 1); j < length; j++)
{
temp = gamma(tb + step * j, GAMMA_EX) - BLACK_OFFSET;
data[j + b] = (cv::min)(255, (cv::max)(0, static_cast<int>(temp)));
}
}
cv::Mat createLUT(const std::vector<cv::Mat>& mats, bool isTextCorrect)
{
int rows = mats[0].cols;
cv::Mat lut(rows, 256, CV_8UC1);
double max_val, min_val;
cv::minMaxIdx(mats[0], &min_val, nullptr);
cv::minMaxIdx(mats[1], nullptr, &max_val);
for (size_t i = 0; i < rows; i++)
{
std::vector<unsigned char> grayPoints;
for (size_t j = 0; j < mats.size(); j++)
grayPoints.push_back(mats[j].data[i]);
fittingLUT(grayPoints, static_cast<unsigned char>(min_val), static_cast<unsigned char>(max_val), lut.data + i * 256);
}
if (isTextCorrect)
{
std::vector<double> points_x = { 0, 25, 205, 255 }, points_y = { 0, 0, 230, 255 };
std::vector<double> coefficient = caculate(points_x, points_y);
unsigned char buffer[256];
for (int i = 0; i < 256; i++)
{
int temp = coefficient[0] * i * i * i + coefficient[1] * i * i + coefficient[2] * i + coefficient[3];
buffer[i] = static_cast<unsigned char>((cv::min)(255, (cv::max)(0, temp)));
}
cv::Mat lut_lut(256, 1, CV_8UC1, buffer);
cv::LUT(lut, lut_lut, lut);
}
return lut;
}
#define CHANNEL 432
cv::Mat calcLUT(const cv::Mat& black, const cv::Mat& white, bool isTextCorrection)
{
std::vector<cv::Mat> w;
w.push_back(black);
w.push_back(white);
cv::Mat lut = createLUT(w, isTextCorrection);
for (size_t i = 0, block = lut.rows / CHANNEL; i < block; i++)
{
cv::Mat lutROI = lut(cv::Rect(0, i * CHANNEL, 256, CHANNEL));
cv::Mat tran;
cv::transpose(lutROI, tran);
memcpy(lutROI.data, tran.data, tran.total());
}
return lut;
}
cv::Mat loadLUT(const std::string& file)
{
cv::Mat dataFile = cv::imread(file, cv::IMREAD_ANYCOLOR);
long total = dataFile.total();
int step = total / 256;
int channel = 432;
cv::Mat lut(step / channel, 256, CV_8UC(channel));
memcpy(lut.data, dataFile.data, total);
return lut;
}
void correctColor(cv::Mat& src, cv::Mat lut)
{
cv::Mat image_temp(src.rows, src.cols * src.channels() / lut.channels(), CV_8UC(lut.channels()), src.data);
for (size_t i = 0; i < image_temp.cols; i++)
cv::LUT(image_temp(cv::Rect(i, 0, 1, image_temp.rows)), lut(cv::Rect(0, i, 256, 1)), image_temp(cv::Rect(i, 0, 1, image_temp.rows)));
}
cv::Mat creatLUTData(cv::Mat black, cv::Mat white)
{
printf("eneter creatLUTData \n");
cv::Mat lut;
cv::Mat twMat = white;// cv::imread(whitePath, colormode);
cv::Mat tbMat = black;// cv::imread(blackPath, colormode);
cv::Mat wMat, bMat;
if (black.channels() == 3 && white.channels() == 3)
{
wMat = cv::Mat(twMat.rows, twMat.cols * 3, CV_8UC1, twMat.data);
bMat = cv::Mat(twMat.rows, twMat.cols * 3, CV_8UC1, tbMat.data);
}
else
{
wMat = twMat;
bMat = tbMat;
}
lut = calcLUT(bMat, wMat, true);
long total = lut.total();
int step = total / 256;
int channel = 432;
cv::Mat ret = cv::Mat::zeros(step / channel, 256, CV_8UC(channel));
memcpy(ret.data, lut.data, total);
return ret;
}
cv::Mat create_lut(const cv::Mat& black, const cv::Mat& white, int dpi, bool colormode)
{
return calcLUT(black, white, false);
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// api ...
@ -1552,9 +1875,9 @@ namespace hg_imgproc
{
return ((imgproc*)himg)->load_file(path_file);
}
int decode(HIMGPRC himg, int pid, LPSCANCONF img_param, LPIMGPRCPARAM param)
int decode(HIMGPRC himg, int pid, LPSCANCONF img_param, LPIMGPRCPARAM param, std::map<int, setting3288dsp::FLAT_INFO_IMAGE>& correction_image_map_)
{
return ((imgproc*)himg)->decode(pid, img_param, param);
return ((imgproc*)himg)->decode(pid, img_param, param, correction_image_map_);
}
int init_auto_txt_hanld(HIMGPRC himg)
{
@ -1689,6 +2012,10 @@ namespace hg_imgproc
{
return ((imgproc*)himg)->final();
}
int correction_image(HIMGPRC himg, cv::Mat& flat_lut, cv::Mat black_mat, cv::Mat white_mat)
{
return ((imgproc*)himg)->correction_image(flat_lut, black_mat, white_mat);
}
int get_final_data(HIMGPRC himg, LPIMGHEAD pimh, void** buf, int index)
{
return ((imgproc*)himg)->get_final_data(pimh, buf, index);

View File

@ -150,6 +150,10 @@ namespace hg_imgproc
bool double_side;
bool black_white;
bool cis_image; //设置原图
int width; // in pixel
int height; // in pixel
unsigned total_bytes;// total bytes
bool device_7010;
}IMGPRCPARAM, *LPIMGPRCPARAM;
typedef struct _img_header
{
@ -168,7 +172,7 @@ namespace hg_imgproc
int load_file(HIMGPRC himg, const char* path_file);
//图像数据转换
int decode(HIMGPRC himg,int pid, LPSCANCONF img_param, LPIMGPRCPARAM param);
int decode(HIMGPRC himg,int pid, LPSCANCONF img_param, LPIMGPRCPARAM param, std::map<int, setting3288dsp::FLAT_INFO_IMAGE>& correction_image_map_);
int correct_text(HIMGPRC himg);
int init_auto_txt_hanld(HIMGPRC himg);
@ -205,6 +209,9 @@ namespace hg_imgproc
int color_cast_correction(HIMGPRC himg);
int final(HIMGPRC himg);
int correction_image(HIMGPRC himg, cv::Mat& flat_lut, cv::Mat black_mat, cv::Mat white_mat);
// pimh must not to be NULL, and pimh->total_bytes indicates the length of 'buf'
//
// if 'buf' was NULL, then return SCANNER_ERR_INSUFFICIENT_MEMORY