2022-07-29 08:41:34 +00:00
|
|
|
#include "ImageApplyHSVCorrect.h"
|
|
|
|
#include <omp.h>
|
|
|
|
|
|
|
|
CImageApplyHSVCorrect::CImageApplyHSVCorrect(CorrectOption mode, bool cvtColor, uint bgr)
|
|
|
|
: 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>(30, 255), std::pair<uchar, uchar>(120, 255), bgr, cvtColor);
|
|
|
|
set_HSV_value(std::pair<uchar, uchar>(200, 255), std::pair<uchar, uchar>(30, 255), std::pair<uchar, uchar>(120, 255), bgr, cvtColor);
|
|
|
|
break;
|
|
|
|
case CImageApplyHSVCorrect::LowSaturation_Removal:
|
|
|
|
set_HSV_value(std::pair<uchar, uchar>(0, 255), std::pair<uchar, uchar>(0, 30), std::pair<uchar, uchar>(0, 255), bgr, cvtColor);
|
|
|
|
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;
|
|
|
|
#if 0
|
|
|
|
uchar* src = pDib.data;
|
|
|
|
cv::Mat z = cv::Mat::zeros(pDib.size(), CV_8UC3);
|
|
|
|
uchar* dst = z.data;
|
|
|
|
|
|
|
|
int bytesPerLine = pDib.cols * pDib.channels();
|
|
|
|
for (size_t i = 0, rows = pDib.rows; i < rows; i++)
|
|
|
|
{
|
|
|
|
uchar* ptr = pDib.ptr(i);
|
|
|
|
for (size_t j = 0, cols = pDib.cols; j < cols; j++)
|
|
|
|
{
|
|
|
|
int offset = i * 3;
|
|
|
|
int index = *reinterpret_cast<uint*>(ptr + offset) & 0x00ffffff;
|
|
|
|
uint color = m_table[index];
|
|
|
|
*reinterpret_cast<uint*>(dst + offset) |= color;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pDib = z;
|
|
|
|
#else
|
|
|
|
cv::Mat bgra;
|
|
|
|
cv::cvtColor(pDib, bgra, cv::COLOR_BGR2BGRA);
|
|
|
|
|
|
|
|
long total = bgra.total();
|
|
|
|
uint* ptr = bgra.ptr<uint>();
|
|
|
|
for (long i = 0; i < total; i++)
|
|
|
|
ptr[i] = m_table[ptr[i] & 0x00FFFFFF];
|
|
|
|
|
|
|
|
cv::cvtColor(bgra, pDib, cv::COLOR_BGRA2BGR);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
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, bool cvtGray)
|
|
|
|
{
|
|
|
|
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))
|
|
|
|
{
|
|
|
|
if (cvtGray)
|
|
|
|
{
|
|
|
|
int a = (b + g + r) / 3 * 0x00010101;
|
|
|
|
m_table[(b | (g << 8) | (r << 16)) & 0x00ffffff] = (b + g + r) / 3 * 0x00010101;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
m_table[(b | (g << 8) | (r << 16)) & 0x00ffffff] = bgr & 0x00ffffff;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CImageApplyHSVCorrect::set_table(const uint* table)
|
|
|
|
{
|
|
|
|
memcpy(m_table, table, 256 * 256 * 256 * sizeof(uint));
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|