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]];
|
|||
|
}
|