#include #include #include #include #include "correct_ultis.h" #include "CImageMerge.h" #define USE_NEWFLAT using namespace cv; //设置一面的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(0, i) = cv::mean(temp_imageBW(cv::Rect(i, 0, 1, temp_imageBW.rows)))[0]; // return BWbalenceSrc; // } 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 = 1; #ifndef USE_NEWFLAT if (step == 4896 || step == 7344) channel = 408; else if (step == 14688 || step == 22032 || step == 44064) channel = 432; // 486 #else #ifdef G400 channel = 408; #else channel = 432; #endif #endif cv::Mat lut(step / channel, 256, CV_8UC(channel)); memcpy(lut.data, dataFile.data, total); return lut; } void initLut(const std::string lutpath, bool iscolor) { if (!lutpath.empty() && (access(lutpath.c_str(), F_OK) == 0)) { if (iscolor) { lutColorMat = loadLUT(lutpath); //彩色校正值 } else lutGrayMat = loadLUT(lutpath); //灰色校正值 } } void correctColor(cv::Mat &src, int dpi, int mode, bool lutgraghic) { cv::Mat lutMat; #ifdef USE_NEWFLAT FPGAConfigParam param = GetFpgaparam(dpi, mode); std::string path = lutgraghic ? param.LutPath : param.TextLutPath; #else std::string path = param.LutPath; #endif if (src.type() == CV_8UC3) { if (lutColorMat.empty()) { if (access(path.c_str(), F_OK) != -1) { lutColorMat = loadLUT(path); } else { printf("error error error %s NOT FOUND \n", path.c_str()); return; } } lutMat = lutColorMat; } else { if (lutGrayMat.empty()) { if (access(path.c_str(), F_OK) != -1) { lutGrayMat = loadLUT(path); } else { printf("error error error %s NOT FOUND", path.c_str()); return; } } lutMat = lutGrayMat; } if (lutMat.empty()) { return; } cv::Mat image_temp(src.rows, src.cols * src.channels() / lutMat.channels(), CV_8UC(lutMat.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)), lutMat(cv::Rect(0, i, 256, 1)), image_temp(cv::Rect(i, 0, 1, image_temp.rows))); } // void creatLUTData(int dpi, int mode) // { // printf("eneter creatLUTData \n"); // FPGAConfigParam param = GetFpgaparam(dpi, mode); // auto colormode = mode == 1 ? IMREAD_COLOR : IMREAD_GRAYSCALE; // std::string blackPath = param.Flat_BwPath; // std::string whitePath = param.Flat_WhitePath; // cv::Mat lut; // cv::Mat twMat = cv::imread(whitePath, colormode); // cv::Mat tbMat = cv::imread(blackPath, colormode); // cv::Mat wMat, bMat; // if (mode == 1) // { // 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; // } // #ifdef USE_NEWFLAT // //lut = calcLUT(extractRepresentRow2(bMat), extractRepresentRow2(wMat), false); // //cv::imwrite(param.LutPath, lut); // lut = calcLUT(extractRepresentRow2(bMat), extractRepresentRow2(wMat), true); // cv::imwrite(param.TextLutPath, lut); // #else // lut = create_lut(extractRepresentRow2(bMat), extractRepresentRow2(wMat), dpi, mode); // // Mat dst(bMat.cols * bMat.channels(), 256, CV_8UC1); // // memcpy(dst.data, lut.data, bMat.cols * bMat.channels() * 256); // cv::imwrite(param.LutPath, lut); // #endif // printf("exit creatLUTData \n"); // } FPGAConfigParam GetFpgaparam(int dpi, int mode) { //FPGAConfigParam param = CorrectParam().GetFpgaparam(dpi, mode); return correctparam.GetFpgaparam(dpi, mode); } void SaveFpgaparam(FPGAConfigParam ¶m) { correctparam.SaveCorrectParam(param); //CorrectParam().SaveCorrectParam(param); } // cv::Mat colMean(const cv::Mat &image) // { // cv::Mat meanMat(1, image.step, CV_8UC1); // cv::Mat tempMat(image.rows, image.step, CV_8UC1, image.data); // for (int i = 0; i < tempMat.step; i++) // meanMat.data[i] = cv::mean(tempMat(cv::Rect(i, 0, 1, tempMat.rows)))[0]; // return meanMat; // } float gamma(float value, float ex) { return 0.0;//cv::pow(value / 255.0f, 1.0f / ex) * 255.0f + 0.5f; } #define GAMMA_EX 1.7f #define BLACK_OFFSET 0 void fittingLUT(const std::vector &points, u_char min_value, u_char max_value, u_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(temp))); // } } // std::vector caculate(const std::vector &points_x, const std::vector &points_y) // { // int MaxElement = points_x.size() - 1; // //计算常数f // double f = points_y[0]; // //求解 // int n, m; // // double a[MaxElement][MaxElement+1]; // std::vector> a; // // a.resize(MaxElement); // for (int i = 0; i < MaxElement; i++) // { // std::vector 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 result; // for (int k = 0; k < n; k++) // result.push_back(a[k][n]); // result.push_back(f); // return result; // } // cv::Mat createLUT(const std::vector &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 grayPoints; // for (size_t j = 0; j < mats.size(); j++) // grayPoints.push_back(mats[j].data[i]); // fittingLUT(grayPoints, static_cast(min_val), static_cast(max_val), lut.data + i * 256); // } // if (isTextCorrect) // { // std::vector points_x = {0, 25, 205, 255}, points_y = {0, 0, 230, 255}; // std::vector coefficient = caculate(points_x, points_y); // u_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(cv::min(255, cv::max(0, temp))); // } // cv::Mat lut_lut(256, 1, CV_8UC1, buffer); // cv::LUT(lut, lut_lut, lut); // } // return lut; // } #ifdef G400 #define CHANNEL 408 #else #define CHANNEL 432 #endif // cv::Mat calcLUT(const cv::Mat &black, const cv::Mat &white, bool isTextCorrection) // { // std::vector w; // w.push_back(colMean(black)); // w.push_back(colMean(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 create_lut(const cv::Mat &black, const cv::Mat &white, int dpi, bool colormode) // { // #ifndef USE_NEWFLAT // if (black.empty() || white.empty() || black.channels() != 1 || white.channels() != 1 || black.step != white.step) // return cv::Mat(); // int channel = 1; // if (black.step == 4896 || black.step == 7344) // channel = 408; // else if (black.step == 14688 || black.step == 22032 || black.step == 44064) // channel = 432; // 486 // if (channel == 1) // return cv::Mat(); // const int rows = black.cols / channel; // const int cols = 256; // auto cc = CV_8UC(channel); // Mat lut(rows, cols, CV_8UC(channel)); // 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; // 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 // { // float val = 255.0f * (j - ptr_black[k]) / (ptr_white[k] - ptr_black[k]) * 1.275; // // ptr_buffer[j * channel + k] = (unsigned char)cv::max(0.0f, cv::min(val, 255.0f)); // } // } // } // cv::Mat saveMat(black.step, 256, CV_8UC1, lut.data); // return saveMat.clone(); // #else // return calcLUT(black, white, false); // #endif // } // cv::Mat GetMergeMat(int dstwidth, int dstheight, int type, cv::Mat &mat) // { // return CImageMerge().MergeImage(type == CV_8UC3, mat, dstwidth, dstheight); // }