twain3/ImageProcess/ImageApplyHSVCorrect.cpp

145 lines
4.1 KiB
C++
Raw Permalink Normal View History

#include "ImageApplyHSVCorrect.h"
#include <omp.h>
CImageApplyHSVCorrect::CImageApplyHSVCorrect()
: m_table(new uint[256 * 256 * 256])
{
initLUT();
}
CImageApplyHSVCorrect::CImageApplyHSVCorrect(CorrectOption mode)
: m_table(new uint[256 * 256 * 256])
{
initLUT();
switch (mode)
{
case CImageApplyHSVCorrect::Red_Removal:
set_HSV_value(std::pair<uchar, uchar>(0, 63), std::pair<uchar, uchar>(20, 255), std::pair<uchar, uchar>(160, 255), 0x00FFFFFF);
set_HSV_value(std::pair<uchar, uchar>(191, 255), std::pair<uchar, uchar>(20, 255), std::pair<uchar, uchar>(160, 255), 0x00FFFFFF);
break;
default:
break;
}
}
CImageApplyHSVCorrect::~CImageApplyHSVCorrect()
{
delete [] m_table;
}
void CImageApplyHSVCorrect::apply(cv::Mat &pDib, int side)
{
(void)side;
if (pDib.empty() || pDib.channels() != 3) return;
uchar* src = pDib.data;
cv::Mat z = cv::Mat::zeros(pDib.size(), CV_8UC3);
uchar* dst = z.data;
int total = pDib.total();
#pragma omp parallel for
for (int i = 0; i < total; i++)
{
int offset = i * 3;
int index = *reinterpret_cast<uint*>(src + offset) & 0x00ffffff;
uint color = m_table[index];
*reinterpret_cast<uint*>(dst + offset) |= color;
}
pDib = z;
}
void CImageApplyHSVCorrect::apply(std::vector<cv::Mat> &mats, bool isTwoSide)
{
(void)isTwoSide;
int i = 0;
for (cv::Mat& var : mats) {
if (i != 0 && isTwoSide == false)
break;
if (!var.empty())
apply(var, 0);
i++;
}
}
void CImageApplyHSVCorrect::initLUT()
{
#if 0
uchar h, s, v;
#endif
for (uint b = 0; b < 256; b++)
for (uint g = 0; g < 256; g++)
for (uint r = 0; r < 256; r++)
{
#if 0
RGB_2_HSV_full(r, g, b, h, s, v);
uint index = b | (g << 8) | (r << 16);
if (h < 12 || h > 245)
m_table[index] = index & 0x00ffffff;
else
m_table[index] = (v | (v << 8) | (v << 16)) & 0x00ffffff;
#else
m_table[b | (g << 8) | (r << 16)] = b | (g << 8) | (r << 16);
#endif
}
}
void CImageApplyHSVCorrect::set_single(const uint src_b, const uint src_g, const uint src_r,
const uint dst_b, const uint dst_g, const uint dst_r)
{
m_table[src_b | (src_g << 8) | (src_r << 16)] = dst_b | (dst_g << 8) | (dst_r << 16);
}
void CImageApplyHSVCorrect::set_HSV_value(const std::pair<uchar, uchar>& range_h,
const std::pair<uchar, uchar>& range_s,
const std::pair<uchar, uchar>& range_v,
uint bgr)
{
uchar h, s, v;
for (int b = 0; b < 256; b++)
for (int g = 0; g < 256; g++)
for (int r = 0; r < 256; r++)
{
RGB_2_HSV_full(r, g, b, h, s, v);
if (contained(h, range_h) && contained(s, range_s) && contained(v, range_v))
m_table[(b | (g << 8) | (r << 16)) & 0x00ffffff] = bgr & 0x00ffffff;
}
}
void CImageApplyHSVCorrect::set_table(const uint* table)
{
memcpy(m_table, table, 256 * 256 * 256);
}
bool CImageApplyHSVCorrect::contained(uchar value, const std::pair<uchar, uchar> &range)
{
return value >= range.first && value <= range.second;
}
void CImageApplyHSVCorrect::RGB_2_HSV_full(int r, int g, int b, uchar& h, uchar& s, uchar& v)
{
int minn = cv::min(r, cv::min(g, b));
int maxx = cv::max(r, cv::max(g, b));
v = static_cast<uchar>(maxx); //V
int delta = maxx - minn;
float _h;
if (maxx == 0)
{
h = s = v = 0;
return;
}
else
s = static_cast<uchar>(delta * 255 / maxx);
if (r == maxx)
_h = static_cast<float>(g - b) / static_cast<float>(delta);
else if (g == maxx)
_h = 2 + static_cast<float>(b - r) / static_cast<float>(delta);
else
_h = 4 + static_cast<float>(r - g) / static_cast<float>(delta);
float __h = _h * 42.6666666667f;
h = (__h >= 0) ? static_cast<uchar>(__h) : static_cast<uchar>(__h + 256);
}