#include "hgutils.h" #include #include #include #include #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(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 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 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) { Get_static_jsonconfig().savescannerinfo(params); } ScannerNativeParam getscannerinfo() { return Get_static_jsonconfig().getscannerinfo(); } void savecisparams(HGCorrectConfigs cfgs) { Get_static_jsonconfig().savecisconfig(cfgs); } HGCorrectConfigs getcisparams() { return Get_static_jsonconfig().getcorrectconfigs(); }