#include "ImageApplyHSVCorrect.h" #include 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(0, 63), std::pair(20, 255), std::pair(160, 255), 0x00FFFFFF); set_HSV_value(std::pair(191, 255), std::pair(20, 255), std::pair(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(src + offset) & 0x00ffffff; uint color = m_table[index]; *reinterpret_cast(dst + offset) |= color; } pDib = z; } void CImageApplyHSVCorrect::apply(std::vector &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& range_h, const std::pair& range_s, const std::pair& 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 &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(maxx); //V int delta = maxx - minn; float _h; if (maxx == 0) { h = s = v = 0; return; } else s = static_cast(delta * 255 / maxx); if (r == maxx) _h = static_cast(g - b) / static_cast(delta); else if (g == maxx) _h = 2 + static_cast(b - r) / static_cast(delta); else _h = 4 + static_cast(r - g) / static_cast(delta); float __h = _h * 42.6666666667f; h = (__h >= 0) ? static_cast(__h) : static_cast(__h + 256); }