twain3.0/huagao/ImageProcess/ImageApplyFadeBackGroundCol...

151 lines
4.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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.step, pDib.rows, m_threshold, m_offset, m_range);
#endif
}
void CImageApplyFadeBackGroudColor::fadeBackground(unsigned char* data, int bytesPerLine, int height, int threshold, int offset, int range)
{
int hist_bgr[3][256] = { 0 };
int width = bytesPerLine / 3;
unsigned char* mask = new unsigned char[width * height];
unsigned char* ptr_data = data;
unsigned char* ptr_mask = mask;
//创建掩模mask并且统计三通道的直方图
for (size_t i = 0; i < height; i++)
{
int x = 0;
unsigned char b = 0;
for (size_t j = 0; j < width; j++)
{
b = m_table1[ptr_data[x] + ptr_data[x + 1] + ptr_data[x + 2]];
ptr_mask[j] = b;
for (size_t k = 0; k < 3; k++)
hist_bgr[k][ptr_data[x + k] & b]++;
x += 3;
}
ptr_data += bytesPerLine;
ptr_mask += width;
}
//统计背景色
int max_vals[3] = { 0 };
int max_indexes[3] = { 0 };
for (size_t i = 1; i < 256; i++)
for (size_t j = 0; j < 3; j++)
if (hist_bgr[j][i] > max_vals[j])
{
max_vals[j] = hist_bgr[j][i];
max_indexes[j] = i;
}
//创建背景色误查值表在误差±range范围内的颜色被同样视为背景色
for (size_t i = 0; i < 3; i++)
{
memset(m_table_rgb[i], 0, 256);
int start = cv::max(max_indexes[i] - range, 0);
int end = cv::min(max_indexes[i] + range, 255);
memset(m_table_rgb[i] + start, 255, end - start + 1);
}
//根据背景色误差查值表,更新掩模,排除背景色以外的内容
ptr_data = data;
ptr_mask = mask;
for (size_t i = 0; i < height; i++)
{
int x = 0;
for (size_t j = 0; j < width; j++)
{
ptr_mask[j] &= m_table_rgb[0][ptr_data[x]] & m_table_rgb[1][ptr_data[x + 1]] & m_table_rgb[2][ptr_data[x + 2]];
x += 3;
}
ptr_data += bytesPerLine;
ptr_mask += width;
}
//根据掩模,除背景色
unsigned char offset_rgb[3];
for (size_t i = 0; i < 3; i++)
offset_rgb[i] = 255 + offset - max_indexes[i];
ptr_data = data;
ptr_mask = mask;
for (size_t i = 0; i < height; i++)
{
int x = 0;
for (size_t j = 0; j < width; j++)
{
for (size_t k = 0; k < 3; k++)
ptr_data[x + k] = m_table2[(int)ptr_data[x + k] + (offset_rgb[k] & ptr_mask[j])];
x += 3;
}
ptr_data += bytesPerLine;
ptr_mask += width;
}
delete[] mask;
}
void CImageApplyFadeBackGroudColor::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
{
(void)isTwoSide;
int i = 0;
for (cv::Mat& var : mats)
if (!var.empty())
{
apply(var, i);
i++;
}
}