rk3399_arm_lvds/capimage/GrayLighting.h

109 lines
2.8 KiB
C
Raw Permalink Normal View History

2024-03-05 03:46:18 +00:00
#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]];
}