code_device/hgdriver/ImageProcess/ImageApplyHSVCorrect.cpp

182 lines
6.4 KiB
C++
Raw Normal View History

2022-07-29 08:41:34 +00:00
#include "ImageApplyHSVCorrect.h"
#include <omp.h>
CImageApplyHSVCorrect::CImageApplyHSVCorrect(CorrectOption mode, bool cvtColor, uint bgr, uint alpha)
2022-07-29 08:41:34 +00:00
: m_table(new uint[256 * 256 * 256])
{
initLUT();
uint temp;
2022-07-29 08:41:34 +00:00
switch (mode)
{
case CImageApplyHSVCorrect::Red_Removal:
set_HSV_value(std::pair<uchar, uchar>(0, 10), std::pair<uchar, uchar>(30, 255), std::pair<uchar, uchar>(120, 255), bgr, cvtColor);
2022-07-29 08:41:34 +00:00
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:
if (alpha < 0)
temp = 35;
else
temp = alpha;
set_HSV_value(std::pair<uchar, uchar>(0, 255), std::pair<uchar, uchar>(0, temp), std::pair<uchar, uchar>(0, 255), bgr, cvtColor);
break;
case CImageApplyHSVCorrect::FXB_Color_Cast:
set_HSV_value(std::pair<uchar, uchar>(45, 105), std::pair<uchar, uchar>(0, 255), std::pair<uchar, uchar>(0, 255), 0x00FFFFFF, true);
set_HSV_value(std::pair<uchar, uchar>(180, 235), std::pair<uchar, uchar>(0, 255), std::pair<uchar, uchar>(0, 255), 0x00FFFFFF, true);
set_HSV_value(std::pair<uchar, uchar>(0, 30), std::pair<uchar, uchar>(0, 50), std::pair<uchar, uchar>(0, 255), 0x00FFFFFF, true);
break;
case CImageApplyHSVCorrect::LM_Color_Cast:
set_HSV_value(std::pair<uchar, uchar>(45, 105), std::pair<uchar, uchar>(0, 255), std::pair<uchar, uchar>(0, 255), 0x00FFFFFF, true);
set_HSV_value(std::pair<uchar, uchar>(180, 235), std::pair<uchar, uchar>(0, 100), std::pair<uchar, uchar>(0, 255), 0x00FFFFFF, true);
set_HSV_value(std::pair<uchar, uchar>(0, 30), std::pair<uchar, uchar>(0, 60), std::pair<uchar, uchar>(0, 255), 0x00FFFFFF, true);
break;
case CImageApplyHSVCorrect::RESERVE_RED:
set_HSV_value(std::pair<uchar, uchar>(45, 220), std::pair<uchar, uchar>(0, 255), std::pair<uchar, uchar>(0, 255), 0x00FFFFFF, true);
2022-07-29 08:41:34 +00:00
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 = delta;
2022-07-29 08:41:34 +00:00
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);
}