|
|
#include "Arith_Utils.h"
|
|
|
#include <cmath>
|
|
|
|
|
|
#include "Arith_SysStruct.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void AddMat(double* A, double* B, int mn, double* AaddB)
|
|
|
{
|
|
|
for (size_t i = 0; i < mn; i++)
|
|
|
{
|
|
|
AaddB[i] = A[i] + B[i];
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
void MultiMatScalar(double scalar, double* A, double* sA, int mn)
|
|
|
{
|
|
|
for (size_t i = 0; i < mn; i++)
|
|
|
{
|
|
|
sA[i] = scalar * A[i];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void TransposeMat(double* A, int w, int h, double* AT)
|
|
|
{
|
|
|
for (int i = 0; i < h; i++)
|
|
|
{
|
|
|
for (int j = 0; j < w; j++)
|
|
|
{
|
|
|
AT[j * w + i] = A[i * h + j];
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
/* 1 0 0
|
|
|
0 cos sin
|
|
|
0 -sin cos
|
|
|
*/
|
|
|
void Rx(double omega, double* Opp)
|
|
|
{
|
|
|
double coso = cos(RADIAN(omega));
|
|
|
double sino = sin(RADIAN(omega));
|
|
|
|
|
|
Opp[0] = 1;
|
|
|
Opp[1] = 0;
|
|
|
Opp[2] = 0;
|
|
|
Opp[3] = 0;
|
|
|
Opp[4] = coso;
|
|
|
Opp[5] = sino;
|
|
|
Opp[6] = 0;
|
|
|
Opp[7] = -sino;
|
|
|
Opp[8] = coso;
|
|
|
}
|
|
|
|
|
|
/* cos 0 sin
|
|
|
0 1 0
|
|
|
-sin 0 cos
|
|
|
*/
|
|
|
void Ry(double omega, double* Opp)
|
|
|
{
|
|
|
double coso = cos(RADIAN(omega));
|
|
|
double sino = sin(RADIAN(omega));
|
|
|
|
|
|
Opp[0] = coso;
|
|
|
Opp[1] = 0;
|
|
|
Opp[2] = sino;
|
|
|
Opp[3] = 0;
|
|
|
Opp[4] = 1;
|
|
|
Opp[5] = 0;
|
|
|
Opp[6] = -sino;
|
|
|
Opp[7] = 0;
|
|
|
Opp[8] = coso;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* cos sin 0
|
|
|
-sin cos 0
|
|
|
0 0 1
|
|
|
*/
|
|
|
void Rz(double omega, double* Opp)
|
|
|
{
|
|
|
double coso = cos(RADIAN(omega));
|
|
|
double sino = sin(RADIAN(omega));
|
|
|
|
|
|
Opp[0] = coso;
|
|
|
Opp[1] = sino;
|
|
|
Opp[2] = 0;
|
|
|
Opp[3] = -sino;
|
|
|
Opp[4] = coso;
|
|
|
Opp[5] = 0;
|
|
|
Opp[6] = 0;
|
|
|
Opp[7] = 0;
|
|
|
Opp[8] = 1;
|
|
|
}
|
|
|
|
|
|
// 镜面反射矩阵
|
|
|
void RMirror(PointXYZ normalVec, double* Opp)
|
|
|
{
|
|
|
// M = eye(3)-(2*N*N');
|
|
|
Opp[0] = 1 - 2 * normalVec.X * normalVec.X;
|
|
|
Opp[1] = -2 * normalVec.X * normalVec.Y;
|
|
|
Opp[2] = -2 * normalVec.X * normalVec.Z;
|
|
|
Opp[3] = -2 * normalVec.X * normalVec.Y;
|
|
|
Opp[4] = 1 - 2 * normalVec.Y * normalVec.Y;
|
|
|
Opp[5] = -2 * normalVec.Y * normalVec.Z;
|
|
|
Opp[6] = -2 * normalVec.X * normalVec.Z;
|
|
|
Opp[7] = -2 * normalVec.Y * normalVec.Z;
|
|
|
Opp[8] = 1 - 2 * normalVec.Z * normalVec.Z;
|
|
|
|
|
|
}
|
|
|
//*********************************************************************************************
|
|
|
// 矩阵乘法
|
|
|
//*********************************************************************************************
|
|
|
void MultiMat(double* A, double* B, double* AB, int m, int n, int p)
|
|
|
{
|
|
|
// A:m*n ; B:n*p ;
|
|
|
int i, j, k;
|
|
|
double Multisum;
|
|
|
|
|
|
for (i = 0; i < m; i++)
|
|
|
{
|
|
|
for (j = 0; j < p; j++)
|
|
|
{
|
|
|
Multisum = 0;
|
|
|
for (k = 0; k < n; k++)
|
|
|
Multisum += A[i * n + k] * B[k * p + j];
|
|
|
|
|
|
AB[i * p + j] = Multisum;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//*********************************************************************************************
|
|
|
//
|
|
|
//*********************************************************************************************
|
|
|
void MultiMat33(double* A, double* B, double* AB)
|
|
|
{
|
|
|
MultiMat(A, B, AB, 3, 3, 3);
|
|
|
}
|
|
|
|
|
|
//*********************************************************************************************
|
|
|
//
|
|
|
//*********************************************************************************************
|
|
|
void MultiMat333(double* A, double* B, double* C, double* ABC)
|
|
|
{
|
|
|
double BC[9];
|
|
|
MultiMat(B, C, BC, 3, 3, 3);
|
|
|
MultiMat(A, BC, ABC, 3, 3, 3);
|
|
|
}
|
|
|
|
|
|
// 对点/矢量旋转
|
|
|
PointXYZ RtPoint(double* M, PointXYZ Point)
|
|
|
{
|
|
|
// M * [X,Y,Z]'
|
|
|
double A[3];
|
|
|
double G[3];
|
|
|
A[0] = Point.X;
|
|
|
A[1] = Point.Y;
|
|
|
A[2] = Point.Z;
|
|
|
MultiMat(M, A, G, 3, 3, 1);
|
|
|
|
|
|
PointXYZ result;
|
|
|
result.X = G[0];
|
|
|
result.Y = G[1];
|
|
|
result.Z = G[2];
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 标准化矢量
|
|
|
PointXYZ NormPoint(PointXYZ Point)
|
|
|
{
|
|
|
double Len = sqrt(Point.X * Point.X + Point.Y * Point.Y + Point.Z * Point.Z);
|
|
|
Point.X /= Len;
|
|
|
Point.Y /= Len;
|
|
|
Point.Z /= Len;
|
|
|
return Point;
|
|
|
}
|
|
|
|
|
|
|
|
|
void eye3(double* M)
|
|
|
{
|
|
|
memset(M, 0, sizeof(double) * 9);
|
|
|
M[0] = 1;
|
|
|
M[4] = 1;
|
|
|
M[8] = 1;
|
|
|
}
|
|
|
|
|
|
void invMat3(double* A, double* invA)
|
|
|
{
|
|
|
double a1 = A[0];
|
|
|
double a2 = A[1];
|
|
|
double a3 = A[2];
|
|
|
double b1 = A[3];
|
|
|
double b2 = A[4];
|
|
|
double b3 = A[5];
|
|
|
double c1 = A[6];
|
|
|
double c2 = A[7];
|
|
|
double c3 = A[8];
|
|
|
|
|
|
//A*
|
|
|
double Astar[9] = { 0 };
|
|
|
Astar[0] = b2 * c3 - c2 * b3;
|
|
|
Astar[1] = c1 * b3 - b1 * c3;
|
|
|
Astar[2] = b1 * c2 - c1 * b2;
|
|
|
|
|
|
Astar[3] = c2 * a3 - a2 * c3;
|
|
|
Astar[4] = a1 * c3 - c1 * a3;
|
|
|
Astar[5] = a2 * c1 - a1 * c2;
|
|
|
|
|
|
Astar[6] = a2 * b3 - b2 * a3;
|
|
|
Astar[7] = b1 * a3 - a1 * b3;
|
|
|
Astar[8] = a1 * b2 - a2 * b1;
|
|
|
|
|
|
double detA = a1 * (b2 * c3 - c2 * b3) - a2 * (b1 * c3 - c1 * b3) + a3 * (b1 * c2 - c1 * b2);
|
|
|
|
|
|
for (size_t i = 0; i < 9; i++)
|
|
|
{
|
|
|
invA[i] = Astar[i] / detA;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
// 旋转向量转矩阵
|
|
|
void rotationVectorToMatrix(PointXYZ rotaVec_One, float rotaAgl, double* Mat)
|
|
|
{
|
|
|
//
|
|
|
PointXYZ vec_norm = NormPoint(rotaVec_One);
|
|
|
|
|
|
// K
|
|
|
double K[9] = { 0,-vec_norm.Z,vec_norm.Y,
|
|
|
vec_norm.Z,0,-vec_norm.X,
|
|
|
-vec_norm.Y,vec_norm.X,0 };
|
|
|
|
|
|
// eye(3)
|
|
|
double eye[9] = { 0 };
|
|
|
eye3(eye);
|
|
|
|
|
|
// eye + sind(r) * K + (1-cos(r)) * K * K
|
|
|
double sK[9] = { 0 };
|
|
|
MultiMatScalar(sin(RADIAN(rotaAgl)), K, sK, 9);
|
|
|
|
|
|
double KK[9] = { 0 };
|
|
|
MultiMat33(K, K, KK);
|
|
|
|
|
|
double scK[9] = { 0 };
|
|
|
MultiMatScalar(1 - cos(RADIAN(rotaAgl)), KK, scK, 9);
|
|
|
|
|
|
double tmp[9] = { 0 };
|
|
|
AddMat(eye, sK, 9, tmp);
|
|
|
|
|
|
AddMat(tmp, scK, 9, Mat);
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _WIN32 // Windows平台
|
|
|
|
|
|
#include <Windows.h>
|
|
|
|
|
|
std::string GetDynamicLibraryPath()
|
|
|
{
|
|
|
HMODULE hModule = GetModuleHandle(NULL);
|
|
|
char path[MAX_PATH];
|
|
|
GetModuleFileName(hModule, path, MAX_PATH);
|
|
|
std::string fullPath(path);
|
|
|
size_t pos = fullPath.find_last_of("\\/");
|
|
|
return fullPath.substr(0, pos);
|
|
|
}
|
|
|
|
|
|
#elif __linux__ // Linux平台
|
|
|
|
|
|
|
|
|
#include <dlfcn.h>
|
|
|
#include <unistd.h>
|
|
|
|
|
|
std::string GetDynamicLibraryPath()
|
|
|
{
|
|
|
Dl_info dlInfo;
|
|
|
dladdr((void*)GetDynamicLibraryPath, &dlInfo);
|
|
|
char* path = realpath(dlInfo.dli_fname, NULL);
|
|
|
std::string fullPath(path);
|
|
|
free(path);
|
|
|
size_t pos = fullPath.find_last_of("/");
|
|
|
return fullPath.substr(0, pos);
|
|
|
}
|
|
|
|
|
|
#else
|
|
|
|
|
|
#error Unsupported platform
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
cv::Mat getRGBAMatFromGDFrame(GD_VIDEO_FRAME_S frame, void* pArr)
|
|
|
{
|
|
|
// 针对拼接,目前支持Y8和NV12
|
|
|
cv::Mat dst(frame.u32Height, frame.u32Width, CV_8UC4);
|
|
|
|
|
|
//y8类型
|
|
|
if (frame.enPixelFormat == GD_PIXEL_FORMAT_E::GD_PIXEL_FORMAT_GRAY_Y8)
|
|
|
{
|
|
|
cv::Mat mat(frame.u32Height, frame.u32Width, CV_8UC1, pArr);
|
|
|
cv::cvtColor(mat, dst, cv::COLOR_GRAY2BGRA);
|
|
|
return dst.clone();
|
|
|
}
|
|
|
|
|
|
// nv12
|
|
|
if (frame.enPixelFormat == GD_PIXEL_FORMAT_E::GD_PIXEL_FORMAT_NV12)
|
|
|
{
|
|
|
cv::Mat mat(frame.u32Height * 1.5, frame.u32Width, CV_8UC1, pArr);
|
|
|
cv::cvtColor(mat, dst, cv::COLOR_YUV2BGRA_NV12);
|
|
|
return dst.clone();
|
|
|
}
|
|
|
|
|
|
// rgb
|
|
|
if (frame.enPixelFormat == GD_PIXEL_FORMAT_E::GD_PIXEL_FORMAT_RGB_PACKED)
|
|
|
{
|
|
|
cv::Mat mat(frame.u32Height, frame.u32Width, CV_8UC3, pArr);
|
|
|
cv::cvtColor(mat, dst, cv::COLOR_BGR2BGRA);
|
|
|
return mat.clone();
|
|
|
}
|
|
|
|
|
|
return cv::Mat();
|
|
|
}
|
|
|
|
|
|
unsigned char FourPointInterpolation(unsigned char* pSrcImage, int iWidth, int iHeight, float x, float y)
|
|
|
{
|
|
|
if (x < 0 || y < 0 || x > iWidth || y > iHeight)
|
|
|
return 0;
|
|
|
// 四个最临近象素的坐标(i1, j1), (i2, j1), (i1, j2), (i2, j2)
|
|
|
int i1, i2;
|
|
|
int j1, j2;
|
|
|
|
|
|
// 四个最临近象素值
|
|
|
unsigned char f1, f2, f3, f4;
|
|
|
|
|
|
// 计算四个最临近象素的坐标
|
|
|
i1 = fmax((int)x, 0);
|
|
|
i2 = fmin(i1 + 1, iWidth - 1);
|
|
|
j1 = fmax((int)y, 0);
|
|
|
j2 = fmin(j1 + 1, iHeight - 1);
|
|
|
|
|
|
|
|
|
float t, s; //t = x - [x], s = y- [y];
|
|
|
|
|
|
t = x - i1;
|
|
|
s = y - j1;
|
|
|
|
|
|
//四个最临近象素点的值的加权值
|
|
|
float uv0, uv1, uv2, uv3; //权重之和为1:uv0+uv1+uv2+uv3 = 1
|
|
|
uv0 = (1 - s) * (1 - t);
|
|
|
uv1 = (1 - s) * t;
|
|
|
uv2 = (1 - t) * s;
|
|
|
uv3 = s * t;
|
|
|
|
|
|
|
|
|
//根据不同情况分别处理
|
|
|
if (x - iWidth + 1 > 0)
|
|
|
{
|
|
|
// 要计算的点在图像右边缘上
|
|
|
if (y - iHeight + 1 < 0)
|
|
|
{
|
|
|
// 要计算的点正好是图像最右/左下角那一个象素,直接返回该点象素值
|
|
|
f1 = *(pSrcImage + iWidth * j1 + i1);
|
|
|
return f1;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 在图像右/左边缘上且不是最后一点,直接一次插值即可
|
|
|
f1 = *(pSrcImage + iWidth * j1 + i1);
|
|
|
f3 = *(pSrcImage + iWidth * j2 + i1);
|
|
|
|
|
|
// 返回插值结果
|
|
|
return ((unsigned char)(f1 + s * (f3 - f1)));
|
|
|
}
|
|
|
}
|
|
|
else if (y - iHeight + 1 > 0)
|
|
|
{
|
|
|
// 要计算的点在图像下边缘上且不是最后一点,直接一次插值即可
|
|
|
f1 = *(pSrcImage + iWidth * j1 + i1);
|
|
|
f2 = *(pSrcImage + iWidth * j1 + i2);
|
|
|
|
|
|
// 返回插值结果
|
|
|
return ((unsigned char)(f1 + t * (f2 - f1)));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 计算四个最临近象素值
|
|
|
f1 = *(pSrcImage + iWidth * j1 + i1);
|
|
|
f2 = *(pSrcImage + iWidth * j1 + i2);
|
|
|
f3 = *(pSrcImage + iWidth * j2 + i1);
|
|
|
f4 = *(pSrcImage + iWidth * j2 + i2);
|
|
|
|
|
|
return (unsigned char)(uv0 * f1 + uv1 * f2 + uv2 * f3 + uv3 * f4);
|
|
|
}
|
|
|
} |