更新偏色校正算法,402安卓支持偏色校正
This commit is contained in:
parent
f808870f42
commit
6e9a585f6e
|
@ -3,54 +3,66 @@
|
|||
#include <iostream>
|
||||
|
||||
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define SIZE_OF_TABLE 256 * 256 * 256
|
||||
constexpr auto SIZE_OF_TABLE = 256;
|
||||
|
||||
CImageApplyColorCastCorrect::CImageApplyColorCastCorrect()
|
||||
: m_table(new uint[SIZE_OF_TABLE])
|
||||
{
|
||||
std::vector<double> points_x, points_y;
|
||||
points_x = { 0, 80, 175, 255 };
|
||||
points_y = { 12, 85, 175, 270 };
|
||||
createTable(points_x, points_y);
|
||||
}
|
||||
|
||||
CImageApplyColorCastCorrect::CImageApplyColorCastCorrect(const std::vector<double>& points_x, const std::vector<double>& points_y)
|
||||
: m_table(new uint[256 * 256 * 256])
|
||||
: m_table(new uchar[SIZE_OF_TABLE])
|
||||
{
|
||||
createTable(points_x, points_y);
|
||||
}
|
||||
|
||||
CImageApplyColorCastCorrect::CImageApplyColorCastCorrect(const std::string& fileName)
|
||||
: m_table(new uint[256 * 256 * 256])
|
||||
: m_table(new uchar[SIZE_OF_TABLE])
|
||||
{
|
||||
std::fstream file(fileName, std::ios::in | std::ios::binary);
|
||||
if (file)
|
||||
file.read(reinterpret_cast<char*>(m_table), SIZE_OF_TABLE * sizeof(uint));
|
||||
file.read(reinterpret_cast<char*>(m_table), SIZE_OF_TABLE);
|
||||
file.close();
|
||||
}
|
||||
|
||||
CImageApplyColorCastCorrect::CImageApplyColorCastCorrect(const uchar* table_h)
|
||||
: m_table(new uchar[SIZE_OF_TABLE])
|
||||
{
|
||||
memcpy(m_table, table_h, SIZE_OF_TABLE);
|
||||
}
|
||||
|
||||
CImageApplyColorCastCorrect::CImageApplyColorCastCorrect(const int type)
|
||||
: m_table(new uchar[SIZE_OF_TABLE])
|
||||
{
|
||||
if(type == 1)
|
||||
memcpy(m_table,CIS_DN_PATCH1,SIZE_OF_TABLE);
|
||||
else
|
||||
memcpy(m_table,CIS_DN_PATCH2,SIZE_OF_TABLE);
|
||||
}
|
||||
|
||||
CImageApplyColorCastCorrect::~CImageApplyColorCastCorrect(void)
|
||||
{
|
||||
delete[] m_table;
|
||||
}
|
||||
|
||||
void CImageApplyColorCastCorrect::setlutdata(const int type)
|
||||
{
|
||||
if(type == 1) memcpy(m_table,CIS_DN_PATCH1,SIZE_OF_TABLE);
|
||||
else memcpy(m_table,CIS_DN_PATCH2,SIZE_OF_TABLE);
|
||||
}
|
||||
|
||||
void CImageApplyColorCastCorrect::apply(cv::Mat& pDib, int side)
|
||||
{
|
||||
if (pDib.channels() != 3)
|
||||
return;
|
||||
|
||||
cv::Mat bgra;
|
||||
cv::cvtColor(pDib, bgra, cv::COLOR_BGR2BGRA);
|
||||
uint* ptr = bgra.ptr<uint>();
|
||||
int rows = bgra.rows, cols = bgra.cols;
|
||||
for (int i = 0; i < rows; i++)
|
||||
{
|
||||
ptr = reinterpret_cast<uint*>(bgra.ptr(i));
|
||||
for (int j = 0; j < cols; j++)
|
||||
ptr[j] = m_table[ptr[j] & 0x00ffffff];
|
||||
}
|
||||
cv::cvtColor(bgra, pDib, cv::COLOR_BGRA2BGR);
|
||||
bgra.release();
|
||||
cv::Mat hsv;
|
||||
cv::cvtColor(pDib, hsv, cv::COLOR_BGR2HSV_FULL);
|
||||
|
||||
cv::Mat hsv_mv[3];
|
||||
cv::split(hsv, hsv_mv);
|
||||
|
||||
cv::Mat lut(256, 1, CV_8UC1, m_table);
|
||||
cv::LUT(hsv_mv[0], lut, hsv_mv[0]);
|
||||
cv::merge(hsv_mv, 3, pDib);
|
||||
|
||||
cv::cvtColor(pDib, pDib, cv::COLOR_HSV2BGR_FULL);
|
||||
}
|
||||
|
||||
void CImageApplyColorCastCorrect::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
||||
|
@ -70,115 +82,45 @@ void CImageApplyColorCastCorrect::exportTableData(const std::string& fileName)
|
|||
{
|
||||
std::fstream file(fileName, std::ios::out | std::ios::binary);
|
||||
if (file)
|
||||
file.write(reinterpret_cast<char*>(m_table), SIZE_OF_TABLE * sizeof(uint));
|
||||
file.write(reinterpret_cast<char*>(m_table), SIZE_OF_TABLE);
|
||||
file.close();
|
||||
}
|
||||
|
||||
std::vector<double> CImageApplyColorCastCorrect::caculate(const std::vector<double>& points_x, const std::vector<double>& points_y)
|
||||
{
|
||||
int MaxElement = points_x.size() - 1;
|
||||
//计算常数f
|
||||
double f = points_y[0];
|
||||
//求解
|
||||
int n, m;
|
||||
//double a[MaxElement][MaxElement+1];
|
||||
std::vector<std::vector<double>> a;
|
||||
//a.resize(MaxElement);
|
||||
for (int i = 0; i < MaxElement; i++)
|
||||
{
|
||||
std::vector<double> b;
|
||||
b.resize(MaxElement + 1);
|
||||
a.push_back(b);
|
||||
}
|
||||
|
||||
for (int i = 0; i < MaxElement; i++)
|
||||
{
|
||||
for (int j = 0; j < MaxElement; j++)
|
||||
a[i][j] = cv::pow(points_x[i + 1], MaxElement - j);
|
||||
a[i][MaxElement] = points_y[i + 1] - f;
|
||||
}
|
||||
|
||||
int i, j;
|
||||
n = MaxElement;
|
||||
|
||||
for (j = 0; j < n; j++)
|
||||
{
|
||||
double max = 0;
|
||||
double imax = 0;
|
||||
for (i = j; i < n; i++)
|
||||
if (imax < cv::abs(a[i][j]))
|
||||
{
|
||||
imax = cv::abs(a[i][j]);
|
||||
max = a[i][j];//得到各行中所在列最大元素
|
||||
m = i;
|
||||
}
|
||||
|
||||
if (cv::abs(a[j][j]) != max)
|
||||
{
|
||||
double b = 0;
|
||||
for (int k = j; k < n + 1; k++)
|
||||
{
|
||||
b = a[j][k];
|
||||
a[j][k] = a[m][k];
|
||||
a[m][k] = b;
|
||||
}
|
||||
}
|
||||
|
||||
for (int r = j; r < n + 1; r++)
|
||||
a[j][r] = a[j][r] / max;//让该行的所在列除以所在列的第一个元素,目的是让首元素为1
|
||||
|
||||
for (i = j + 1; i < n; i++)
|
||||
{
|
||||
double c = a[i][j];
|
||||
if (c == 0.0) continue;
|
||||
for (int s = j; s < n + 1; s++)
|
||||
a[i][s] = a[i][s] - a[j][s] * c;//前后行数相减,使下一行或者上一行的首元素为0
|
||||
}
|
||||
}
|
||||
|
||||
for (i = n - 2; i >= 0; i--)
|
||||
for (j = i + 1; j < n; j++)
|
||||
a[i][n] = a[i][n] - a[j][n] * a[i][j];
|
||||
|
||||
std::vector<double> result;
|
||||
for (int k = 0; k < n; k++)
|
||||
result.push_back(a[k][n]);
|
||||
result.push_back(f);
|
||||
return result;
|
||||
}
|
||||
|
||||
void CImageApplyColorCastCorrect::createTable(const std::vector<double>& points_x, const std::vector<double>& points_y)
|
||||
{
|
||||
cv::Mat mat_rgbTable(256 * 256, 256, CV_8UC3);
|
||||
uchar* ptr_mat_rgbTable = mat_rgbTable.data;
|
||||
for (size_t r = 0; r < 256; r++)
|
||||
for (size_t g = 0; g < 256; g++)
|
||||
for (size_t b = 0; b < 256; b++, ptr_mat_rgbTable += 3)
|
||||
{
|
||||
ptr_mat_rgbTable[0] = b;
|
||||
ptr_mat_rgbTable[1] = g;
|
||||
ptr_mat_rgbTable[2] = r;
|
||||
}
|
||||
int table_temp[256]{};
|
||||
|
||||
cv::cvtColor(mat_rgbTable, mat_rgbTable, cv::COLOR_BGR2HSV_FULL);
|
||||
for (size_t i = 0; i < points_x.size(); i++)
|
||||
{
|
||||
int current_index = static_cast<int>(points_x[i]);
|
||||
if (current_index == 255)
|
||||
current_index = 0;
|
||||
int next_index = static_cast<int>(points_x[(i + 1) % points_x.size()]);
|
||||
|
||||
uchar table_data[256];
|
||||
cv::Mat tableLUT(256, 1, CV_8UC1, table_data);
|
||||
std::vector<double> coefficient;
|
||||
double low = points_y[i];
|
||||
double up = points_y[(i + 1) % points_y.size()];
|
||||
if (low == 255)
|
||||
low = 0;
|
||||
if (up < low)
|
||||
up += 255;
|
||||
|
||||
coefficient = caculate(points_x, points_y);
|
||||
for (int j = 0; j < 256; j++)
|
||||
table_data[j] = static_cast<int>(max(0, coefficient[0] * j * j * j + coefficient[1] * j * j + coefficient[2] * j + coefficient[3]));
|
||||
if (next_index < current_index)
|
||||
next_index += 256;
|
||||
|
||||
cv::Mat hsv_ms[3];
|
||||
cv::split(mat_rgbTable, hsv_ms);
|
||||
cv::LUT(hsv_ms[0], tableLUT, hsv_ms[0]);
|
||||
cv::merge(hsv_ms, 3, mat_rgbTable);
|
||||
int length = next_index - current_index + 1;
|
||||
double step = (up - low) / length;
|
||||
|
||||
cv::cvtColor(mat_rgbTable, mat_rgbTable, cv::COLOR_HSV2BGR_FULL);
|
||||
for (int j = 0; j < length; j++)
|
||||
{
|
||||
int temp = (j + current_index) % 256;
|
||||
table_temp[temp] = step * j + low;
|
||||
}
|
||||
|
||||
cv::Mat mat_bgr32(256, 256 * 256, CV_8UC4);
|
||||
cv::cvtColor(mat_rgbTable, mat_bgr32, cv::COLOR_BGR2BGRA);
|
||||
|
||||
memcpy(m_table, mat_bgr32.data, mat_bgr32.total() * sizeof(uint));
|
||||
for (size_t j = 0; j < 256; j++)
|
||||
if (table_temp[j] > 255)
|
||||
m_table[j] = table_temp[j] - 255;
|
||||
else
|
||||
m_table[j] = table_temp[j];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
/*
|
||||
* ====================================================
|
||||
|
||||
* 功能:色偏校正
|
||||
* 作者:刘丁维
|
||||
* 生成时间:2022/12/01
|
||||
* 最近修改时间:v1.0 2022/12/01
|
||||
* v1.1 2022/12/01 增加从文件中读取查值表数据接口;增加导出查值表数据接口
|
||||
* 版本号:v1.1
|
||||
* 功能:色偏校正
|
||||
* 作者:刘丁维
|
||||
* 生成时间:2022/12/01
|
||||
* 最近修改时间:v1.0 2022/12/01
|
||||
* v1.1 2022/12/01 增加从文件中读取查值表数据接口;增加导出查值表数据接口
|
||||
* v1.1.1 2023/03/24 增加预设方案
|
||||
* v1.2 2023/04/04 提高曲线拐点数,增加预设方案CIS_DN_PATCH3
|
||||
* v1.3 2023/04/17 增加新查值表导入方式。
|
||||
* v2.0 2023/05/15 重构查值表算法。
|
||||
* 版本号:v2.0
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
|
@ -19,24 +23,72 @@ class GIMGPROC_LIBRARY_API CImageApplyColorCastCorrect : public CImageApply
|
|||
{
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// 默认使用 points_x = { 0, 80, 175, 255 } points_y = { 12, 85, 175, 270 }曲线创建查值表
|
||||
/// </summary>
|
||||
CImageApplyColorCastCorrect();
|
||||
static const uchar CIS_DN_PATCH2[256] = //摩尔纹慢速扫描色偏参数
|
||||
{
|
||||
0x10, 0x11, 0x13, 0x14, 0x16, 0x17, 0x1B, 0x1B, 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F,
|
||||
0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x24, 0x24, 0x24, 0x25, 0x25, 0x25,
|
||||
0x26, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x2A, 0x2A, 0x2A, 0x2B, 0x2B,
|
||||
0x2B, 0x2C, 0x2C, 0x2C, 0x2D, 0x2D, 0x2D, 0x2E, 0x2E, 0x2E, 0x2F, 0x2F, 0x2F, 0x30, 0x30, 0x30,
|
||||
0x31, 0x31, 0x31, 0x32, 0x33, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E, 0x40, 0x42, 0x44, 0x46, 0x48,
|
||||
0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5A, 0x5C, 0x5E, 0x62, 0x63, 0x65, 0x66, 0x68,
|
||||
0x69, 0x6B, 0x6C, 0x6E, 0x6F, 0x71, 0x72, 0x74, 0x75, 0x77, 0x78, 0x7A, 0x7B, 0x7D, 0x7E, 0x82,
|
||||
0x82, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x88, 0x89, 0x89,
|
||||
0x8A, 0x8A, 0x8B, 0x8B, 0x8C, 0x8C, 0x8D, 0x8D, 0x8E, 0x8E, 0x8F, 0x90, 0x90, 0x90, 0x91, 0x91,
|
||||
0x92, 0x92, 0x93, 0x93, 0x94, 0x94, 0x95, 0x96, 0x97, 0x99, 0x9B, 0x9D, 0x9F, 0xA1, 0xA3, 0xA4,
|
||||
0xA6, 0xA8, 0xAA, 0xAC, 0xAE, 0xB2, 0xB3, 0xB4, 0xB6, 0xB7, 0xB8, 0xBA, 0xBB, 0xBC, 0xBE, 0xBF,
|
||||
0xC1, 0xC2, 0xC3, 0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCD, 0xCE, 0xD0, 0xD1, 0xD2, 0xD4, 0xD5,
|
||||
0xD6, 0xD8, 0xD9, 0xDA, 0xDC, 0xDF, 0xDF, 0xE0, 0xE0, 0xE1, 0xE1, 0xE2, 0xE3, 0xE3, 0xE4, 0xE4,
|
||||
0xE5, 0xE6, 0xE6, 0xE7, 0xE7, 0xE8, 0xE9, 0xE9, 0xEA, 0xEA, 0xEB, 0xEC, 0xEC, 0xED, 0xED, 0xEE,
|
||||
0xEF, 0xEF, 0xF0, 0xF0, 0xF1, 0xF1, 0xF2, 0xF3, 0xF3, 0xF4, 0xF4, 0xF5, 0xF6, 0xF6, 0xF7, 0xF7,
|
||||
0xF8, 0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0x02, 0x05, 0x08, 0x0A, 0x0D
|
||||
};
|
||||
|
||||
const uchar CIS_DN_PATCH1[256] = //正常扫描色偏参数
|
||||
{
|
||||
0x10, 0x11, 0x13, 0x14, 0x16, 0x17, 0x1B, 0x1B, 0x1B, 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F,
|
||||
0x1F, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25, 0x25,
|
||||
0x26, 0x26, 0x26, 0x27, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x2A, 0x2A, 0x2A, 0x2B, 0x2B, 0x2B,
|
||||
0x2C, 0x2C, 0x2C, 0x2D, 0x2D, 0x2D, 0x2E, 0x2E, 0x2E, 0x2F, 0x2F, 0x2F, 0x30, 0x30, 0x30, 0x31,
|
||||
0x31, 0x31, 0x32, 0x32, 0x33, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E, 0x40, 0x42, 0x44, 0x46, 0x48,
|
||||
0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5A, 0x5C, 0x5E, 0x62, 0x63, 0x65, 0x66, 0x68,
|
||||
0x6A, 0x6B, 0x6D, 0x6E, 0x70, 0x72, 0x73, 0x75, 0x76, 0x78, 0x7A, 0x7B, 0x7D, 0x7E, 0x82, 0x82,
|
||||
0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x88, 0x89, 0x89, 0x89,
|
||||
0x8A, 0x8A, 0x8B, 0x8B, 0x8C, 0x8C, 0x8D, 0x8D, 0x8E, 0x8E, 0x8F, 0x90, 0x90, 0x90, 0x91, 0x91,
|
||||
0x92, 0x92, 0x93, 0x93, 0x94, 0x94, 0x95, 0x96, 0x98, 0x9A, 0x9C, 0x9E, 0xA0, 0xA2, 0xA4, 0xA6,
|
||||
0xA8, 0xAA, 0xAC, 0xAE, 0xB2, 0xB3, 0xB4, 0xB6, 0xB7, 0xB8, 0xBA, 0xBB, 0xBC, 0xBE, 0xBF, 0xC1,
|
||||
0xC2, 0xC3, 0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCD, 0xCE, 0xD0, 0xD1, 0xD2, 0xD4, 0xD5, 0xD6,
|
||||
0xD8, 0xD9, 0xDA, 0xDC, 0xDF, 0xDF, 0xE0, 0xE0, 0xE1, 0xE1, 0xE2, 0xE3, 0xE3, 0xE4, 0xE4, 0xE5,
|
||||
0xE5, 0xE6, 0xE7, 0xE7, 0xE8, 0xE8, 0xE9, 0xE9, 0xEA, 0xEB, 0xEB, 0xEC, 0xEC, 0xED, 0xED, 0xEE,
|
||||
0xEF, 0xEF, 0xF0, 0xF0, 0xF1, 0xF1, 0xF2, 0xF3, 0xF3, 0xF4, 0xF4, 0xF5, 0xF5, 0xF6, 0xF7, 0xF7,
|
||||
0xF8, 0xF8, 0xF9, 0xF9, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0x02, 0x05, 0x08, 0x0A
|
||||
};
|
||||
/// <summary>
|
||||
/// 用户自定义查值表
|
||||
/// 用户自定义查值表
|
||||
/// </summary>
|
||||
/// <param name="points_x">HSV色彩空间H通道曲线变换节点坐标X轴</param>
|
||||
/// <param name="points_y">HSV色彩空间H通道曲线变换节点坐标Y轴</param>
|
||||
/// <param name="points_x">HSV色彩空间H通道曲线变换节点坐标X轴</param>
|
||||
/// <param name="points_y">HSV色彩空间H通道曲线变换节点坐标Y轴</param>
|
||||
CImageApplyColorCastCorrect(const std::vector<double>& points_x, const std::vector<double>& points_y);
|
||||
|
||||
/// <summary>
|
||||
/// 从文件中加载现有查值表数据
|
||||
/// 从文件中加载现有查值表数据
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
CImageApplyColorCastCorrect(const std::string& fileName);
|
||||
|
||||
/// <summary>
|
||||
/// 针对HSV中H通道的LUT校正数据
|
||||
/// </summary>
|
||||
/// <param name="table_h"></param>
|
||||
CImageApplyColorCastCorrect(const uchar* table_h);
|
||||
|
||||
/// <summary>
|
||||
/// 选择设置HSV中H通道的LUT校正数据
|
||||
/// </summary>
|
||||
/// <param name="table_h"></param>
|
||||
CImageApplyColorCastCorrect(const int type);
|
||||
|
||||
void setlutdata(const int type);
|
||||
|
||||
virtual ~CImageApplyColorCastCorrect(void);
|
||||
|
||||
virtual void apply(cv::Mat& pDib, int side);
|
||||
|
@ -44,18 +96,16 @@ public:
|
|||
virtual void apply(std::vector<cv::Mat>& mats, bool isTwoSide);
|
||||
|
||||
/// <summary>
|
||||
/// 导出当前查值表数据
|
||||
/// 导出当前查值表数据
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
void exportTableData(const std::string& fileName);
|
||||
|
||||
private:
|
||||
|
||||
std::vector<double> caculate(const std::vector<double>& points_x, const std::vector<double>& points_y);
|
||||
|
||||
void createTable(const std::vector<double>& points_x, const std::vector<double>& points_y);
|
||||
private:
|
||||
uint* m_table;
|
||||
uchar* m_table;
|
||||
};
|
||||
|
||||
#endif
|
File diff suppressed because one or more lines are too long
|
@ -1334,7 +1334,7 @@ namespace hg_imgproc
|
|||
int ret = SCANNER_ERR_OK;
|
||||
std::vector<cv::Mat> mats(mats_);
|
||||
mats_.clear();
|
||||
CImageApplyColorCastCorrect ColorCastCorrect;
|
||||
CImageApplyColorCastCorrect ColorCastCorrect(1);
|
||||
|
||||
//cv::imwrite(to_string(i) + "cis_test_image.jpg", mats[i]);
|
||||
|
||||
|
|
Loading…
Reference in New Issue