tx-gxx-linux/device/gxx-linux/capimage/hgutils.cpp

316 lines
9.6 KiB
C++

#include "hgutils.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <iostream>
#include "CImageMerge.h"
using namespace cv;
cv::Mat extractRepresentRow(const cv::Mat &src)
{
printf("extractRepresentRow2 enter \n");
Mat src_temp(src.rows, src.step, CV_8UC1, src.data);
Mat dst(1, src.cols, CV_8UC(src.channels()));
Mat dst_temp(1, src.step, CV_8UC1, dst.data);
for (int i = 0, length = src.step; i < length; i++)
{
Mat col = src_temp(Rect(i, 0, 1, src_temp.rows));
float value = 0;
for (int j = 0, rows = col.rows; j < rows; j++)
{
value += (float)col.at<unsigned char>(Point(0, j)) / rows;
}
dst_temp.data[i] = (int)value;
}
printf("extractRepresentRow2 exit \n");
return dst;
}
cv::Mat flipRightHalf(Mat &src, int papertype)
{
Mat left = src(cv::Rect(0, 0, src.cols / 2, src.rows));
Mat right = src(cv::Rect(src.cols / 2, 0, src.cols / 2, src.rows));
Mat rightFlip;
if (papertype == (int)(PaperSize::G400_A4R))
{
flip(right, rightFlip, 0);
}
else
{
flip(right, rightFlip, 1);
}
Mat dst;
hconcat(left, rightFlip, dst);
return dst;
}
float curve_coffes[2][3][3] = {
{{-6e-5, 0.9928, 0.289},
{4e-5, 1.0045, -0.0338},
{3e-5, 1.0028, -0.2547}},
{{0.00025215105482649316, 0.9162675232424231, 2.2064225897716527},
{-6.242394612635725e-05, 1.0212590446315797, -0.7470581333124157},
{-0.0002324551311266845, 1.072239346671703, -1.7099159032971474}}};
cv::Mat create_lut(const cv::Mat &black, const cv::Mat &white, bool colormode, CISVendor vendor)
{
printf("create_lut enter \n");
int channel = 4896 / 12; // 1632*3
const int rows = black.cols / channel; //408
const int cols = 256;
printf("LUT White width: %d height :%d channels:%d \n", white.cols, white.rows, white.channels());
printf("LUT black width: %d height :%d channels:%d \n", black.cols, black.rows, black.channels());
Mat lut(rows, cols, CV_8UC(channel));
float *cisCoffoes;
float *coffoes;
if (vendor == CISVendor::DUNNAN_CIS_V0)
cisCoffoes = &curve_coffes[0][0][0];
else if (vendor == CISVendor::HUALIN_CIS_V0)
cisCoffoes = &curve_coffes[1][0][0];
else
{
cisCoffoes = &curve_coffes[1][0][0];
printf("warnning!!! unknown cis type,use hualin CIS cisCoffoes params \n");
}
for (size_t i = 0; i < rows; i++)
{
Mat lut_row = lut(cv::Rect(0, i, cols, 1));
unsigned char *ptr_buffer = lut_row.data;
unsigned char *ptr_black = black.data + i * channel;
unsigned char *ptr_white = white.data + i * channel;
for (size_t j = 0; j < cols; j++)
{
for (size_t k = 0; k < channel; k++)
{
if (ptr_black[k] >= ptr_white[k])
{
ptr_buffer[j * channel + k] = 0;
printf("ptr_black[%d] >= ptr_white[%d]", k, k);
continue;
}
if (j <= ptr_black[k])
{
ptr_buffer[j * channel + k] = 0;
}
else if (j >= ptr_white[k])
{
ptr_buffer[j * channel + k] = 255;
}
else
{
if (white.channels() == 3)
{
float val = 255.0 * (j - ptr_black[k]) / (ptr_white[k] - ptr_black[k]) *1.2;
//float val = 255.0 * (j - ptr_black[k]) / (ptr_white[k] - ptr_black[k]);
// coffoes = cisCoffoes + 3 * (k % 3);
// val = coffoes[0] * val * val + coffoes[1] * val + coffoes[2];
if (val > 255)
val = 255;
if (val < 0)
val = 0;
ptr_buffer[j * channel + k] = (unsigned char)val;
}
else
{
//float val = 255 * (j - ptr_black[k]) / (ptr_white[k] - ptr_black[k]);
float val = 255 * (j - ptr_black[k]) / (ptr_white[k] - ptr_black[k]) * 1.2;
if (val > 255)
val = 255;
if (val < 0)
val = 0;
ptr_buffer[j * channel + k] = (unsigned char)val;
}
}
}
}
}
printf("create_lut exit \n");
return lut;
}
void initLut()
{
if(access(LUT_GRAY_LUT_PATH, F_OK) != -1)
lutGrayMat_old = cv::imread(LUT_GRAY_LUT_PATH, IMREAD_GRAYSCALE); //灰色校正值
if(access(LUT_COLOR_LUT_PATH, F_OK) != -1)
lutColorMat_old = cv::imread(LUT_COLOR_LUT_PATH, IMREAD_GRAYSCALE); //彩色校正值
}
void correctColor(cv::Mat src, bool enhance)
{
Mat tSrc;
Mat lutMat;
int patch = 0;
int SIZE = src.cols / 12;
//printf("lutMat.empty() src.width::%d SIZE: %d \n", src.cols, SIZE);
if (src.type() == CV_8UC3)
{
patch = (src.cols * 3) / SIZE;
if (lutColorMat_old.empty())
{
if (access(LUT_COLOR_LUT_PATH, F_OK) != -1)
{
lutColorMat_old = imread(LUT_COLOR_LUT_PATH, IMREAD_GRAYSCALE);
}
else
{
//printf("error error error %s NOT FOUND \n", LUT_COLOR_LUT_PATH);
return;
}
}
lutMat = lutColorMat_old;
}
else
{
patch = (src.cols) / SIZE;
if (lutGrayMat_old.empty())
{
if (access(LUT_GRAY_LUT_PATH, F_OK) != -1)
{
lutGrayMat_old = imread(LUT_GRAY_LUT_PATH, IMREAD_GRAYSCALE);
}
else
{
//printf("error error error %s NOT FOUND", LUT_GRAY_LUT_PATH);
return;
}
}
lutMat = lutGrayMat_old;
}
if (lutMat.empty())
{
return;
}
lutMat = cv::Mat(patch, 256, CV_8UC(SIZE), lutMat.data);
tSrc = cv::Mat(src.rows, patch, CV_8UC(SIZE), src.data);
for (int i = 0; i < patch; i++)
{
LUT(tSrc(cv::Rect(i, 0, 1, src.rows)), lutMat(cv::Rect(0, i, 256, 1)), tSrc(cv::Rect(i, 0, 1, src.rows)));
}
}
void creatLUTData(int mode, CISVendor vendor)
{
printf("eneter creatLUTData \n");
auto colormode = mode == IMAGE_COLOR ? IMREAD_COLOR : IMREAD_GRAYSCALE;
std::string blackPath = mode == IMAGE_COLOR ? LUT_COLOR_BLACK_PATH : LUT_GRAY_BLACK_PATH;
std::string whitePath = mode == IMAGE_COLOR ? LUT_COLOR_WHITE_PATH : LUT_GRAY_WHITE_PATH;
std::string lutsavePath = mode == IMAGE_COLOR ? LUT_COLOR_LUT_PATH : LUT_GRAY_LUT_PATH;
cv::Mat lut;
cv::Mat twMat = cv::imread(whitePath, colormode);
cv::Mat tbMat = cv::imread(blackPath, colormode);
cv::Mat wMat, bMat;
if (mode == IMAGE_COLOR)
{
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 = create_lut(extractRepresentRow(bMat), extractRepresentRow(wMat), mode, vendor); // add by liuyong: 刘丁维提供 2019/4/12
Mat dst(bMat.cols * bMat.channels(), 256, CV_8UC1);
memcpy(dst.data, lut.data, bMat.cols * bMat.channels() * 256);
cv::imwrite(lutsavePath, dst);
printf("exit creatLUTData \n");
}
static int num=0;
cv::Mat GetMergeMat(void *data, int width, int height, int type)
{
if (!data)
return cv::Mat();
cv::Mat mat;
cv::Mat saveMat;
std::vector<cv::Mat> ch_mats(3);
int dstwidth, dstheight;
dstwidth = width * 3;
dstheight = height / 3-1;
if (type == CV_8UC3)
{
mat = cv::Mat(height / 3 -1 , width * 9, CV_8UC1, data);
saveMat = cv::Mat(dstheight, dstwidth, CV_8UC3);
}
else
{ //gray
saveMat = cv::Mat(height, width * 3, CV_8UC1, data);
}
static int savenum;
if (type == CV_8UC3)
{
for (int i = 0; i < 3; i++)
{ // B G R
cv::Mat mattemp = mat(cv::Rect(dstwidth * i, 0, dstwidth, dstheight));
//ch_mats.push_back(mattemp);
ch_mats[i]=mattemp;
}
swap(ch_mats[1], ch_mats[2]);
cv::merge(ch_mats, saveMat);
}
return saveMat.clone();
}
//3399 旧版本 华凌cis拼接算法
cv::Mat GetMergeMat(cv::Mat& mat, int width, int height, int type)
{
if (mat.empty())
return cv::Mat();
cv::Mat saveMat;
std::vector<cv::Mat> ch_mats(3);
int dstwidth, dstheight;
dstwidth = width * 3;
dstheight = height / 3-1;
if (type == CV_8UC3)
{
saveMat = cv::Mat(dstheight, dstwidth, CV_8UC3);
for (int i = 0; i < 3; i++)
{ // B G R
cv::Mat mattemp = mat(cv::Rect(dstwidth * i, 0, dstwidth, dstheight));
//ch_mats.push_back(mattemp);
ch_mats[i]=mattemp;
}
swap(ch_mats[1], ch_mats[2]);
cv::merge(ch_mats, saveMat);
return saveMat;
}
return mat;
}
//3399 敦南cis 300 600 拼接算法
cv::Mat GetMergeMat(int dstwidth ,int dstheight,int type,cv::Mat& mat,unsigned int fpgaversion)
{
return CImageMerge().MergeImage(type==CV_8UC3,mat,dstwidth,dstheight,fpgaversion);
}
void savescannerinfo(ScannerNativeParam params)
{
jsonconfig().savescannerinfo(params);
}
ScannerNativeParam getscannerinfo()
{
return jsonconfig().getscannerinfo();
}
void savecisparams(HGCorrectConfigs cfgs)
{
jsonconfig().savecisconfig(cfgs);
}
HGCorrectConfigs getcisparams()
{
return jsonconfig().getcorrectconfigs();
}