#include "ImageApplyHSVCorrect.h" #include CImageApplyHSVCorrect::CImageApplyHSVCorrect(CorrectOption mode, bool cvtColor, uint bgr, uint alpha) : m_table(new uint[256 * 256 * 256]) { initLUT(); uint temp; switch (mode) { case CImageApplyHSVCorrect::Red_Removal: set_HSV_value(std::pair(0, 63), std::pair(30, 255), std::pair(120, 255), bgr, cvtColor); set_HSV_value(std::pair(200, 255), std::pair(30, 255), std::pair(120, 255), bgr, cvtColor); break; case CImageApplyHSVCorrect::LowSaturation_Removal: if (alpha < 0) temp = 35; else temp = alpha; set_HSV_value(std::pair(0, 255), std::pair(0, temp), std::pair(0, 255), bgr, cvtColor); break; case CImageApplyHSVCorrect::FXB_Colour_Cast: set_HSV_value(std::pair(45, 105), std::pair(0, 255), std::pair(0, 255), 0x00FFFFFF, true); set_HSV_value(std::pair(180, 235), std::pair(0, 255), std::pair(0, 255), 0x00FFFFFF, true); set_HSV_value(std::pair(0, 30), std::pair(0, 50), std::pair(0, 255), 0x00FFFFFF, true); 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(ptr + offset) & 0x00ffffff; uint color = m_table[index]; *reinterpret_cast(dst + offset) |= color; } } pDib = z; #else cv::Mat bgra; cv::cvtColor(pDib, bgra, cv::COLOR_BGR2BGRA); long total = bgra.total(); uint* ptr = bgra.ptr(); 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& 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, 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& 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 = delta; 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); }