109 lines
2.8 KiB
C++
109 lines
2.8 KiB
C++
#pragma once
|
||
#include <memory>
|
||
#include <vector>
|
||
#include <opencv2/opencv.hpp>
|
||
|
||
std::vector<double> caculate_abcd(std::vector<std::pair<double, double>> point)
|
||
{
|
||
int MaxElement = point.size() - 1;
|
||
// 计算常数f
|
||
double f = point[0].second;
|
||
// 求解
|
||
int n, m;
|
||
|
||
std::vector<std::vector<double>> a;
|
||
|
||
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] = pow(point[i + 1].first, MaxElement - j);
|
||
a[i][MaxElement] = point[i + 1].second - 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 < fabs(a[i][j]))
|
||
{
|
||
imax = fabs(a[i][j]);
|
||
max = a[i][j]; // 得到各行中所在列最大元素
|
||
m = i;
|
||
}
|
||
}
|
||
if (fabs(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;
|
||
}
|
||
|
||
double caculate_value(const std::vector<double> &abcd, double x)
|
||
{
|
||
return abcd[0] * x * x * x + abcd[1] * x * x + abcd[2] * x + abcd[3];
|
||
}
|
||
|
||
void brightness(cv::Mat &lut, int alpha = 170)
|
||
{
|
||
std::vector<std::pair<double, double>> pos;
|
||
pos.push_back(std::pair<double, double>(0, 0));
|
||
pos.push_back(std::pair<double, double>(64, 64));
|
||
pos.push_back(std::pair<double, double>(alpha, 255));
|
||
pos.push_back(std::pair<double, double>(255, 255));
|
||
std::vector<double> abcd = caculate_abcd(pos);
|
||
|
||
uchar table[256];
|
||
for (int i = 0; i < 256; i++)
|
||
table[i] = static_cast<uchar>(caculate_value(abcd, i));
|
||
|
||
uchar *ptr = lut.data;
|
||
for (int i = 0, length = lut.total() * lut.channels(); i < length; i++)
|
||
ptr[i] = table[ptr[i]];
|
||
} |