#include #include #include #include #include #include #include "Arith_Utils.h" #include "Arith_SysStruct.h" #ifdef __linux__ #include #define ACCESS access #elif _WIN32 #include #include #define ACCESS _access #endif 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); } // 初始化哈希表 void initHashMap(HashMap* map, int capacity) { map->entries = (HashEntry*)malloc(capacity * sizeof(HashEntry)); if (NULL == map->entries) { return; } map->capacity = capacity; map->size = 0; for (int i = 0; i < capacity; i++) { map->entries[i].key = 0; map->entries[i].count = 0; } } // 查找哈希表中的键 int findKey(HashMap* map, int key) { for (int i = 0; i < map->size; i++) { if (map->entries[i].key == key) { return i; } } return -1; } // 插入键值对到哈希表 void insert(HashMap* map, int key) { int index = findKey(map, key); if (index == -1) { if (map->size < map->capacity) { map->entries[map->size].key = key; map->entries[map->size].count = 1; map->size++; } else { printf("Hash map is full.\n"); } } else { map->entries[index].count++; } } // 释放哈希表 void freeHashMap(HashMap* map) { free(map->entries); } int findMostFrequentNonZero(int arr[], int size, int *clsMaxNum, float *MostFrequentratio) { HashMap map; initHashMap(&map, size); // 假设数组中的数字范围较小 // 记录每个非0数字出现的次数 for (int i = 0; i < size; i++) { if (arr[i] != 0) { insert(&map, arr[i]); } } // 找到出现次数最多的数字 int mostFrequentNum = 0; int maxFrequency = 0; int totalNum = 0; for (int i = 0; i < map.size; i++) { if (map.entries[i].count > maxFrequency) { mostFrequentNum = map.entries[i].key; maxFrequency = map.entries[i].count; } if (map.entries[i].count > 0) { totalNum += map.entries[i].count; } } *clsMaxNum = maxFrequency; *MostFrequentratio = maxFrequency / (totalNum + FEPSILON); freeHashMap(&map); return mostFrequentNum; } int count2To0Transitions(int arr[], int size) { int count = 0; for (int i = 0; i < size - 1; i++) { if (arr[i] == 2 && arr[i + 1] == 0) { count++; } } return count; } bool checkXToYCondition(int arr[], int size, int x, int y, int frmThresh) { bool foundTransition = false; int consecutiveOnes = 0; for (int i = 0; i < size - 1; i++) { if (arr[i] == x && arr[i + 1] == y) { foundTransition = true; consecutiveOnes = 1; // 从 1 开始计数 i++; // 跳过已经检查的 1 // 继续检查后续的 1 while (i < size - 1 && arr[i] == y) { consecutiveOnes++; i++; } // 检查连续 1 的次数是否大于 阈值 if (consecutiveOnes > frmThresh) { return true; } } } return false; } int countNumberFreq(int arr[], int size, int number) { int count = 0; for (int i = 0; i < size; i++) { if (arr[i] == 2) { count++; } } return count; } static float get_dot_prod(float* A, float* B, int size) { int i; float dot_prod = 0.f; for (i = 0; i < size; i++) { dot_prod += A[i] * B[i]; } return dot_prod; } static float get_eucl_magn(float* A, float* B, int size) { int i; double A_len = 0; double B_len = 0; float eucl_magn = 0; for (i = 0; i < size; i++) { A_len += pow(A[i], 2); B_len += pow(B[i], 2); } eucl_magn = (float)sqrt(A_len * B_len); return eucl_magn; } float Cosine_Similarity(float* A, float* B, int size) { // Vectors size can't be 0 if (size == 0) { //throw std::logic_error("Vector size can not be 0."); return 0; } float value = 0; float dot_prod = 0; // 计算欧式距离 float eucl_magn = get_eucl_magn(A, B, size); // If eucledian distance is 0 skip calculation if (eucl_magn == 0) { value = 0; } else { dot_prod = get_dot_prod(A, B, size); value = dot_prod / eucl_magn; } return value; } #ifdef _WIN32 // Windows平台 #include 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 #include 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 void Save_RunImg(GD_VIDEO_FRAME_S img, SINT32 nControlerFrmNum) { char resPath[256] = { 0 }; std::string path = GetDynamicLibraryPath(); snprintf(resPath, 256, "%s/%s", path.c_str(), "SaveImg"); if (ACCESS(resPath, 0) == 0) {// SaveImg文件存在,写数据,默认在第10帧写数据 if (10 == nControlerFrmNum) { std::string filename = std::string(path) + "/frame_" + std::to_string(nControlerFrmNum); std::ofstream outFile(filename, std::ios::binary); if (!outFile) { std::cerr << "Failed to open file for writing: " << filename << std::endl; } switch (img.enPixelFormat) { case GD_PIXEL_FORMAT_GRAY_Y8: for (unsigned int y = 0; y < img.u32Height; ++y) { outFile.write(reinterpret_cast(img.u64VirAddr[0] + y * img.u32Stride[0]), img.u32Width); } break; case GD_PIXEL_FORMAT_GRAY_Y16: for (unsigned int y = 0; y < img.u32Height; ++y) { outFile.write(reinterpret_cast(img.u64VirAddr[0] + y * img.u32Stride[0]), img.u32Width * 2); } break; case GD_PIXEL_FORMAT_NV12: // 写入Y平面 for (unsigned int y = 0; y < img.u32Height; ++y) { outFile.write(reinterpret_cast(img.u64VirAddr[0] + y * img.u32Stride[0]), img.u32Width); } // 写入UV平面 for (unsigned int y = 0; y < img.u32Height / 2; ++y) { outFile.write(reinterpret_cast(img.u64VirAddr[1] + y * img.u32Stride[1]), img.u32Stride[1]); } break; case GD_PIXEL_FORMAT_RGB_PACKED: for (unsigned int y = 0; y < img.u32Height; ++y) { outFile.write(reinterpret_cast(img.u64VirAddr[0] + y * img.u32Stride[0]), img.u32Width * 3); } break; default: std::cerr << "Unsupported pixel format: " << img.enPixelFormat << std::endl; outFile.close(); } outFile.close(); } } } FLOAT32 SERVO_CorrectAngleScale(FLOAT32 fAngle) { FLOAT32 fAngleCorrect = fAngle; //若角度小于伺服角度下限(-180°),则其实际值已经跨入0°~180°范围的右侧 if (fAngle < SERVO_ANGLE_MIN) fAngleCorrect = fAngle + SERVO_ANGLE_RANGE; //若角度大于伺服角度上限(180°),则其实际值已经跨入-180°~0°的范围左侧 if (fAngle >= SERVO_ANGLE_MAX) fAngleCorrect = fAngle - SERVO_ANGLE_RANGE; return fAngleCorrect; }