#include "ImageApplyFadeBackGroundColor.h" CImageApplyFadeBackGroudColor::CImageApplyFadeBackGroudColor(int threshold, int offset, int range) : m_threshold(threshold) , m_offset(offset) , m_range(range) { memset(m_table1, 255, 768); memset(m_table1, 0, m_threshold * 3); memset(m_table2, 255, 256 * 3); for (size_t i = 0; i < 256; i++) m_table2[i] = i; } CImageApplyFadeBackGroudColor::~CImageApplyFadeBackGroudColor() { } void CImageApplyFadeBackGroudColor::apply(cv::Mat& pDib, int side) { if (pDib.channels() != 3) return; #if 0 cv::Mat mask; cv::cvtColor(pDib, mask, cv::COLOR_BGR2GRAY); cv::threshold(mask, mask, m_threshold, 255, cv::THRESH_BINARY); //cv::imwrite("mask.jpg", mask); cv::Mat bgr[3]; cv::split(pDib, bgr); int histSize = 255; float range[] = { 0, 255 }; const float* histRange = { range }; cv::Mat hist_bgr[3]; cv::Scalar mean_bgr; for (size_t i = 0; i < 3; i++) { cv::calcHist(&bgr[i], 1, 0, mask, hist_bgr[i], 1, &histSize, &histRange); double maxVal = 0; cv::Point maxLoc; cv::minMaxLoc(hist_bgr[i], NULL, &maxVal, NULL, &maxLoc); mean_bgr[i] = maxLoc.y; } cv::add(pDib, cv::Scalar::all(255 + m_offset) - mean_bgr, pDib, mask); #else fadeBackground(pDib.data, pDib.cols, pDib.rows, pDib.step, m_threshold, m_offset, m_range); #endif } /// /// 除文稿底色算法,仅支持24位图像 /// /// 图像数据头指针 /// 每行数据大小 /// 图像高度 /// 阈值,参考值为100 /// 文稿底色增亮偏移量,默认为0。值越大,背景越白,反之越暗 void CImageApplyFadeBackGroudColor::fadeBackground(unsigned char* data, int width, int height, int bytesPerLine, int threshold, int offset, int range) { memset(m_table1, 255, 768); memset(m_table1, 0, threshold * 3); memset(m_table2, 255, 256 * 3); for (uint i = 0; i < 256; i++) m_table2[i] = i; int hist_bgr[3][256] = { 0 }; unsigned char* mask = new unsigned char[width * height]; unsigned char* ptr_data = data; unsigned char* ptr_mask = mask; unsigned char b = 0; for (uint i = 0; i < height; i++, ptr_data += bytesPerLine, ptr_mask += width) for (uint j = 0, x = 0; j < width; j++, x += 3) { b = m_table1[ptr_data[x] + ptr_data[x + 1] + ptr_data[x + 2]]; ptr_mask[j] = b; for (uint k = 0; k < 3; k++) hist_bgr[k][ptr_data[x + k] & b]++; } int max_vals[3] = { 0 }; int max_indexes[3] = { 0 }; for (uint i = 1; i < 256; i++) for (uint j = 0; j < 3; j++) if (hist_bgr[j][i] > max_vals[j]) { max_vals[j] = hist_bgr[j][i]; max_indexes[j] = i; } uchar table_rgb[3][256] = { 0 }; for (uint i = 0; i < 3; i++) { int start = cv::max(max_indexes[i] - range, 0); int end = cv::min(max_indexes[i] + range, 255); memset(table_rgb[i] + start, 255, cv::min(end - start + 1, 256 - start)); } ptr_data = data; ptr_mask = mask; for (uint i = 0; i < height; i++, ptr_data += bytesPerLine, ptr_mask += width) for (uint j = 0, x = 0; j < width; j++, x += 3) ptr_mask[j] &= table_rgb[0][ptr_data[x]] & table_rgb[1][ptr_data[x + 1]] & table_rgb[2][ptr_data[x + 2]]; unsigned char offset_rgb[3]; for (uint i = 0; i < 3; i++) offset_rgb[i] = 255 + offset - max_indexes[i]; #if 1 ptr_data = data; ptr_mask = mask; for (uint i = 0; i < height; i++, ptr_data += bytesPerLine, ptr_mask += width) for (uint j = 0, x = 0; j < width; j++, x += 3) for (uint k = 0; k < 3; k++) ptr_data[x + k] = m_table2[(int)ptr_data[x + k] + (offset_rgb[k] & ptr_mask[j])]; #else for (uint c = 0; c < 3; c++) { ptr_data = data + c; ptr_mask = mask; for (uint y = 0; y < height; y++) { int ptr_x = 0; for (uint x = 0; x < width; x++) { ptr_data[ptr_x] = m_table2[(int)ptr_data[ptr_x] + (offset_rgb[c] & ptr_mask[x])]; ptr_x += 3; } ptr_data += bytesPerLine; ptr_mask += width; } } #endif delete[] mask; } void CImageApplyFadeBackGroudColor::apply(std::vector& mats, bool isTwoSide) { (void)isTwoSide; int i = 0; for (cv::Mat& var : mats) if (!var.empty()) { apply(var, i); i++; } }