1800 lines
56 KiB
C++
1800 lines
56 KiB
C++
// gasFillingPortPosition_test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
|
||
//
|
||
|
||
#include <iostream>
|
||
#include <fstream>
|
||
#include <vector>
|
||
#include <stdio.h>
|
||
#include <VZNL_Types.h>
|
||
#include "direct.h"
|
||
#include <string>
|
||
#include "rodAndBarDetection_Export.h"
|
||
#include <opencv2/opencv.hpp>
|
||
#include <Windows.h>
|
||
#include <limits>
|
||
#include <SG_baseAlgo_Export.h>
|
||
|
||
#include <cmath>
|
||
typedef struct
|
||
{
|
||
int r;
|
||
int g;
|
||
int b;
|
||
}SG_color;
|
||
|
||
typedef struct
|
||
{
|
||
int nPointIdx;
|
||
double x;
|
||
double y;
|
||
double z;
|
||
float r;
|
||
float g;
|
||
float b;
|
||
} SPointXYZRGB;
|
||
|
||
bool fileExists(const char* path) {
|
||
FILE* f = fopen(path, "r");
|
||
if (f != NULL) {
|
||
fclose(f);
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
// 点乘 dot
|
||
double _dotMultiply(const SVzNL3DPoint& a, const SVzNL3DPoint& b)
|
||
{
|
||
return (a.x * b.x + a.y * b.y + a.z * b.z);
|
||
}
|
||
|
||
// 模长
|
||
double _length(const SVzNL3DPoint& a)
|
||
{
|
||
return sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
|
||
}
|
||
|
||
// 计算两个向量夹角(返回 角度)
|
||
float _computeVecAngle(const SVzNL3DPoint& a, const SVzNL3DPoint& b)
|
||
{
|
||
float l = _length(a) * _length(b);
|
||
if (l < 1e-6f)
|
||
return 0.0f; // 避免除零
|
||
|
||
float cosTheta = _dotMultiply(a, b) / l;
|
||
cosTheta = cosTheta > 1.0 ? 1.0 : cosTheta;
|
||
cosTheta = cosTheta < -1.0 ? -1.0 : cosTheta;
|
||
float rad = acosf(cosTheta);
|
||
float degree = rad * 180.0f / (float)M_PI;
|
||
return degree;
|
||
}
|
||
|
||
void _outputCalibPara(char* fileName, SSG_planeCalibPara calibPara)
|
||
{
|
||
std::ofstream sw(fileName);
|
||
char dataStr[250];
|
||
//调平矩阵
|
||
sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.planeCalib[0], calibPara.planeCalib[1], calibPara.planeCalib[2]);
|
||
sw << dataStr << std::endl;
|
||
sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.planeCalib[3], calibPara.planeCalib[4], calibPara.planeCalib[5]);
|
||
sw << dataStr << std::endl;
|
||
sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.planeCalib[6], calibPara.planeCalib[7], calibPara.planeCalib[8]);
|
||
sw << dataStr << std::endl;
|
||
//地面高度
|
||
sprintf_s(dataStr, 250, "%g", calibPara.planeHeight);
|
||
sw << dataStr << std::endl;
|
||
//反向旋转矩阵
|
||
sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.invRMatrix[0], calibPara.invRMatrix[1], calibPara.invRMatrix[2]);
|
||
sw << dataStr << std::endl;
|
||
sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.invRMatrix[3], calibPara.invRMatrix[4], calibPara.invRMatrix[5]);
|
||
sw << dataStr << std::endl;
|
||
sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.invRMatrix[6], calibPara.invRMatrix[7], calibPara.invRMatrix[8]);
|
||
sw << dataStr << std::endl;
|
||
|
||
sw.close();
|
||
}
|
||
|
||
SSG_planeCalibPara _readCalibPara(char* fileName)
|
||
{
|
||
//设置初始结果
|
||
double initCalib[9] = {
|
||
1.0, 0.0, 0.0,
|
||
0.0, 1.0, 0.0,
|
||
0.0, 0.0, 1.0 };
|
||
SSG_planeCalibPara planePara;
|
||
for (int i = 0; i < 9; i++)
|
||
planePara.planeCalib[i] = initCalib[i];
|
||
planePara.planeHeight = -1.0;
|
||
for (int i = 0; i < 9; i++)
|
||
planePara.invRMatrix[i] = initCalib[i];
|
||
|
||
std::ifstream inputFile(fileName);
|
||
std::string linedata;
|
||
|
||
if (inputFile.is_open() == false)
|
||
return planePara;
|
||
|
||
//调平矩阵
|
||
std::getline(inputFile, linedata);
|
||
sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.planeCalib[0], &planePara.planeCalib[1], &planePara.planeCalib[2]);
|
||
std::getline(inputFile, linedata);
|
||
sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.planeCalib[3], &planePara.planeCalib[4], &planePara.planeCalib[5]);
|
||
std::getline(inputFile, linedata);
|
||
sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.planeCalib[6], &planePara.planeCalib[7], &planePara.planeCalib[8]);
|
||
//地面高度
|
||
std::getline(inputFile, linedata);
|
||
sscanf_s(linedata.c_str(), "%lf", &planePara.planeHeight);
|
||
//反向旋转矩阵
|
||
std::getline(inputFile, linedata);
|
||
sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.invRMatrix[0], &planePara.invRMatrix[1], &planePara.invRMatrix[2]);
|
||
std::getline(inputFile, linedata);
|
||
sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.invRMatrix[3], &planePara.invRMatrix[4], &planePara.invRMatrix[5]);
|
||
std::getline(inputFile, linedata);
|
||
sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.invRMatrix[6], &planePara.invRMatrix[7], &planePara.invRMatrix[8]);
|
||
|
||
inputFile.close();
|
||
return planePara;
|
||
}
|
||
|
||
void wdReadLaserScanPointFromFile_XYZ_vector(const char* fileName, std::vector<std::vector< SVzNL3DPosition>>& scanData)
|
||
{
|
||
std::ifstream inputFile(fileName);
|
||
std::string linedata;
|
||
|
||
if (inputFile.is_open() == false)
|
||
return;
|
||
|
||
std::vector< SVzNL3DPosition> a_line;
|
||
int ptIdx = 0;
|
||
while (getline(inputFile, linedata))
|
||
{
|
||
if (0 == strncmp("Line_", linedata.c_str(), 5))
|
||
{
|
||
int ptSize = (int)a_line.size();
|
||
if (ptSize > 0)
|
||
{
|
||
scanData.push_back(a_line);
|
||
}
|
||
a_line.clear();
|
||
ptIdx = 0;
|
||
}
|
||
else if (0 == strncmp("{", linedata.c_str(), 1))
|
||
{
|
||
float X, Y, Z;
|
||
int imageY = 0;
|
||
float leftX, leftY;
|
||
float rightX, rightY;
|
||
sscanf_s(linedata.c_str(), "{%f,%f,%f}-{%f,%f}-{%f,%f}", &X, &Y, &Z, &leftX, &leftY, &rightX, &rightY);
|
||
SVzNL3DPosition a_pt;
|
||
a_pt.pt3D.x = X;
|
||
a_pt.pt3D.y = Y;
|
||
a_pt.pt3D.z = Z;
|
||
a_pt.nPointIdx = ptIdx;
|
||
ptIdx++;
|
||
a_line.push_back(a_pt);
|
||
}
|
||
}
|
||
//last line
|
||
int ptSize = (int)a_line.size();
|
||
if (ptSize > 0)
|
||
{
|
||
scanData.push_back(a_line);
|
||
a_line.clear();
|
||
}
|
||
|
||
inputFile.close();
|
||
return;
|
||
}
|
||
|
||
void wd_gridScan_GetROIData(std::vector<std::vector< SVzNL3DPosition>>& scanData, SVzNLRangeD roi_y, std::vector<std::vector< SVzNL3DPosition>>& roiData)
|
||
{
|
||
int lineNum = (int)scanData.size();
|
||
int linePtNum = (int)scanData[0].size();
|
||
int globalPtStart = INT_MAX;
|
||
int globalPtEnd = 0;
|
||
int lineStart = INT_MAX;
|
||
int lineEnd = 0;
|
||
for (int line = 0; line < lineNum; line++)
|
||
{
|
||
std::vector< SVzNL3DPosition >& lineData = scanData[line];
|
||
int ptSize = (int)lineData.size();
|
||
int vldNum = 0;
|
||
int ptStart = INT_MAX;
|
||
int ptEnd = 0;
|
||
for (int i = 0; i < ptSize; i++)
|
||
{
|
||
if (lineData[i].pt3D.z > 1e-4)
|
||
{
|
||
if ((lineData[i].pt3D.y < roi_y.min) || (lineData[i].pt3D.y > roi_y.max))
|
||
lineData[i].pt3D = { 0.0, 0.0, 0.0 };
|
||
}
|
||
|
||
if (lineData[i].pt3D.z > 1e-4)
|
||
{
|
||
if (ptStart > i)
|
||
ptStart = i;
|
||
ptEnd = i;
|
||
vldNum++;
|
||
}
|
||
}
|
||
if (vldNum > 0)
|
||
{
|
||
if (globalPtStart > ptStart)
|
||
globalPtStart = ptStart;
|
||
if (globalPtEnd < ptEnd)
|
||
globalPtEnd = ptEnd;
|
||
|
||
if (lineStart > line)
|
||
lineStart = line;
|
||
lineEnd = line;
|
||
}
|
||
}
|
||
int vldLineNum = lineEnd - lineStart + 1;
|
||
int vldPtNum = globalPtEnd - globalPtStart + 1;
|
||
|
||
roiData.resize(vldLineNum);
|
||
for (int line = 0; line < vldLineNum; line++)
|
||
{
|
||
roiData[line].resize(vldPtNum);
|
||
for (int i = 0; i < vldPtNum; i++)
|
||
roiData[line][i] = scanData[line + lineStart][i + globalPtStart];
|
||
}
|
||
return;
|
||
}
|
||
|
||
void _outputScanDataFile(char* fileName, std::vector<std::vector< SVzNL3DPosition>>& scanData,
|
||
float lineV, int maxTimeStamp, int clockPerSecond)
|
||
{
|
||
std::ofstream sw(fileName);
|
||
|
||
int lineNum = (int)scanData.size();
|
||
sw << "LineNum:" << lineNum << std::endl;
|
||
sw << "DataType: 0" << std::endl;
|
||
sw << "ScanSpeed:" << lineV << std::endl;
|
||
sw << "PointAdjust: 1" << std::endl;
|
||
sw << "MaxTimeStamp:" << maxTimeStamp << "_" << clockPerSecond << std::endl;
|
||
for (int line = 0; line < lineNum; line++)
|
||
{
|
||
int nPositionCnt = (int)scanData[line].size();
|
||
sw << "Line_" << line << "_0_" << nPositionCnt << std::endl;
|
||
for (int i = 0; i < nPositionCnt; i++)
|
||
{
|
||
SVzNL3DPosition& pt3D = scanData[line][i];
|
||
float x = (float)pt3D.pt3D.x;
|
||
float y = (float)pt3D.pt3D.y;
|
||
float z = (float)pt3D.pt3D.z;
|
||
sw << "{ " << x << "," << y << "," << z << " }-";
|
||
sw << "{0,0}-{0,0}" << std::endl;
|
||
}
|
||
}
|
||
sw.close();
|
||
}
|
||
|
||
void _readRodParas(char* fileName, std::vector<SSX_rodParam>& rodParas)
|
||
{
|
||
std::ifstream inputFile(fileName);
|
||
std::string linedata;
|
||
|
||
if (inputFile.is_open() == false)
|
||
return;
|
||
|
||
std::vector<int> indices;
|
||
int maxIdx = 0;
|
||
std::vector< SSX_rodParam> paras;
|
||
while (getline(inputFile, linedata))
|
||
{
|
||
int idx;
|
||
float len, dia;
|
||
sscanf_s(linedata.c_str(), "%d_L_%f_D_%f", &idx, &len, &dia);
|
||
SSX_rodParam a_para = { dia , len };
|
||
indices.push_back(idx);
|
||
paras.push_back(a_para);
|
||
maxIdx = maxIdx < idx ? idx : maxIdx;
|
||
}
|
||
if (maxIdx == 0)
|
||
return;
|
||
rodParas.resize(maxIdx + 1);
|
||
for (int i = 0; i < (int)indices.size(); i++)
|
||
{
|
||
int idx = indices[i];
|
||
rodParas[idx] = paras[i];
|
||
}
|
||
return;
|
||
}
|
||
|
||
void _outputChanneltInfo(char* fileName, std::vector<SSX_rodPoseInfo>& screwInfo)
|
||
{
|
||
std::ofstream sw(fileName);
|
||
|
||
char dataStr[250];
|
||
int objNum = (int)screwInfo.size();
|
||
for (int i = 0; i < objNum; i++)
|
||
{
|
||
sprintf_s(dataStr, 250, "螺杆_%d: center_( %g, %g, %g ), dir_( %g, %g, %g )",
|
||
i + 1, screwInfo[i].center.x, screwInfo[i].center.y, screwInfo[i].center.z,
|
||
screwInfo[i].axialDir.x, screwInfo[i].axialDir.y, screwInfo[i].axialDir.z);
|
||
sw << dataStr << std::endl;
|
||
}
|
||
sw.close();
|
||
}
|
||
|
||
void _outputPlatePiseInfo(char* fileName, SSX_platePoseInfo& centerInfo)
|
||
{
|
||
std::ofstream sw(fileName);
|
||
char dataStr[250];
|
||
sprintf_s(dataStr, 250, "定位盘: \n");
|
||
sw << dataStr << std::endl;
|
||
sprintf_s(dataStr, 250, " holeLT_(% g, % g, % g)\n", centerInfo.holeLT.x, centerInfo.holeLT.y, centerInfo.holeLT.z);
|
||
sw << dataStr << std::endl;
|
||
sprintf_s(dataStr, 250, " holeRB_(% g, % g, % g)\n", centerInfo.holeRB.x, centerInfo.holeRB.y, centerInfo.holeRB.z);
|
||
sw << dataStr << std::endl;
|
||
sprintf_s(dataStr, 250, " center_(% g, % g, % g)\n", centerInfo.center.x, centerInfo.center.y, centerInfo.center.z);
|
||
sw << dataStr << std::endl;
|
||
sprintf_s(dataStr, 250, " normalDir_(% g, % g, % g)\n", centerInfo.normalDir.x, centerInfo.normalDir.y, centerInfo.normalDir.z);
|
||
sw << dataStr << std::endl;
|
||
sprintf_s(dataStr, 250, " xDir_(% g, % g, % g)\n", centerInfo.xDir.x, centerInfo.xDir.y, centerInfo.xDir.z);
|
||
sw << dataStr << std::endl;
|
||
sprintf_s(dataStr, 250, " yDir_(% g, % g, % g)\n", centerInfo.yDir.x, centerInfo.yDir.y, centerInfo.yDir.z);
|
||
sw << dataStr << std::endl;
|
||
sw.close();
|
||
}
|
||
|
||
void _outputRodtInfo(char* fileName, std::vector<SSX_rodPositionInfo>& rodInfo)
|
||
{
|
||
std::ofstream sw(fileName);
|
||
|
||
char dataStr[250];
|
||
int objNum = (int)rodInfo.size();
|
||
for (int i = 0; i < objNum; i++)
|
||
{
|
||
sprintf_s(dataStr, 250, "螺杆_%d: center_( %g, %g, %g ), dir_axia( %g, %g, %g ), dir_normal_( %g, %g, %g )",
|
||
i + 1, rodInfo[i].center.x, rodInfo[i].center.y, rodInfo[i].center.z,
|
||
rodInfo[i].axialDir.x, rodInfo[i].axialDir.y, rodInfo[i].axialDir.z,
|
||
rodInfo[i].normalDir.x, rodInfo[i].normalDir.y, rodInfo[i].normalDir.z);
|
||
sw << dataStr << std::endl;
|
||
}
|
||
sw.close();
|
||
}
|
||
|
||
void _outputWeldSeamInfo(char* fileName, std::vector<SSX_weldSeamInfo>& weldSeamInfo)
|
||
{
|
||
std::ofstream sw(fileName);
|
||
|
||
char dataStr[250];
|
||
int objNum = (int)weldSeamInfo.size();
|
||
for (int i = 0; i < objNum; i++)
|
||
{
|
||
sprintf_s(dataStr, 250, "螺杆_%d: center_( %g, %g, %g ), dir_normal_( %g, %g, %g ), x_dir_(",
|
||
i + 1, weldSeamInfo[i].center.x, weldSeamInfo[i].center.y, weldSeamInfo[i].center.z,
|
||
weldSeamInfo[i].normalDir.x, weldSeamInfo[i].normalDir.y, weldSeamInfo[i].normalDir.z);
|
||
sw << dataStr << std::endl;
|
||
}
|
||
sw.close();
|
||
}
|
||
|
||
void _outputRGBDScan_RGBD(
|
||
char* fileName,
|
||
std::vector<std::vector<SVzNL3DPosition>>& scanLines,
|
||
std::vector<SSX_rodPoseInfo>& screwInfo
|
||
)
|
||
{
|
||
int lineNum = (int)scanLines.size();
|
||
std::ofstream sw(fileName);
|
||
int realLines = lineNum;
|
||
int objNum = (int)screwInfo.size();
|
||
if (objNum > 0)
|
||
realLines += 1;
|
||
|
||
sw << "LineNum:" << realLines << std::endl;
|
||
sw << "DataType: 0" << std::endl;
|
||
sw << "ScanSpeed: 0" << std::endl;
|
||
sw << "PointAdjust: 1" << std::endl;
|
||
sw << "MaxTimeStamp: 0_0" << std::endl;
|
||
|
||
int maxLineIndex = 0;
|
||
int max_stamp = 0;
|
||
|
||
SG_color rgb = { 0, 0, 0 };
|
||
|
||
SG_color objColor[8] = {
|
||
{245,222,179},//淡黄色
|
||
{210,105, 30},//巧克力色
|
||
{240,230,140},//黄褐色
|
||
{135,206,235},//天蓝色
|
||
{250,235,215},//古董白
|
||
{189,252,201},//薄荷色
|
||
{221,160,221},//梅红色
|
||
{188,143,143},//玫瑰红色
|
||
};
|
||
int size = 1;
|
||
int lineIdx = 0;
|
||
for (int line = 0; line < lineNum; line++)
|
||
{
|
||
int linePtNum = (int)scanLines[line].size();
|
||
if (linePtNum == 0)
|
||
continue;
|
||
|
||
sw << "Line_" << lineIdx << "_0_" << linePtNum << std::endl;
|
||
lineIdx++;
|
||
for (int i = 0; i < linePtNum; i++)
|
||
{
|
||
SVzNL3DPosition* pt3D = &scanLines[line][i];
|
||
if (pt3D->nPointIdx == 1)
|
||
{
|
||
rgb = objColor[pt3D->nPointIdx];
|
||
size = 3;
|
||
}
|
||
else if (pt3D->nPointIdx == 2)
|
||
{
|
||
rgb = { 250, 0, 0 };
|
||
size = 3;
|
||
}
|
||
else if (pt3D->nPointIdx == 4)
|
||
{
|
||
rgb = { 250, 250, 0 };
|
||
size = 6;
|
||
}
|
||
else //if (pt3D->nPointIdx == 0)
|
||
{
|
||
rgb = { 200, 200, 200 };
|
||
size = 1;
|
||
}
|
||
float x = (float)pt3D->pt3D.x;
|
||
float y = (float)pt3D->pt3D.y;
|
||
float z = (float)pt3D->pt3D.z;
|
||
sw << "{" << x << "," << y << "," << z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
|
||
}
|
||
}
|
||
|
||
if (objNum > 0)
|
||
{
|
||
sw << "Line_" << lineIdx << "_0_" << objNum << std::endl;
|
||
rgb = { 250, 0, 0 };
|
||
size = 8;
|
||
for (int i = 0; i < objNum; i++)
|
||
{
|
||
float x = (float)screwInfo[i].center.x;
|
||
float y = (float)screwInfo[i].center.y;
|
||
float z = (float)screwInfo[i].center.z;
|
||
sw << "{" << x << "," << y << "," << z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
|
||
}
|
||
//多输出一个,修正显示工具bug
|
||
float x = (float)screwInfo[0].center.x;
|
||
float y = (float)screwInfo[0].center.y;
|
||
float z = (float)screwInfo[0].center.z;
|
||
sw << "{" << x << "," << y << "," << z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
|
||
|
||
//输出法向
|
||
rgb = { 250, 255, 0 };
|
||
size = 1;
|
||
double len1 = 30;
|
||
double len2 = 300;
|
||
lineIdx = 0;
|
||
for (int i = 0; i < objNum; i++)
|
||
{
|
||
SVzNL3DPoint pt0 = { screwInfo[i].center.x - len1 * screwInfo[i].axialDir.x,
|
||
screwInfo[i].center.y - len1 * screwInfo[i].axialDir.y,
|
||
screwInfo[i].center.z - len1 * screwInfo[i].axialDir.z };
|
||
SVzNL3DPoint pt1 = { screwInfo[i].center.x + len2 * screwInfo[i].axialDir.x,
|
||
screwInfo[i].center.y + len2 * screwInfo[i].axialDir.y,
|
||
screwInfo[i].center.z + len2 * screwInfo[i].axialDir.z };
|
||
//显示法向量
|
||
sw << "Poly_" << lineIdx << "_2" << std::endl;
|
||
sw << "{" << (float)pt0.x << "," << (float)pt0.y << "," << (float)pt0.z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||
sw << "{" << pt1.x << "," << pt1.y << "," << pt1.z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||
lineIdx++;
|
||
}
|
||
}
|
||
sw.close();
|
||
}
|
||
|
||
void _outputRGBDScan_RGBD_centerPose(
|
||
char* fileName,
|
||
std::vector<std::vector<SVzNL3DPosition>>& scanLines,
|
||
SSX_platePoseInfo& poseInfo
|
||
)
|
||
{
|
||
int lineNum = (int)scanLines.size();
|
||
std::ofstream sw(fileName);
|
||
int realLines = lineNum;
|
||
realLines += 1;
|
||
|
||
sw << "LineNum:" << realLines << std::endl;
|
||
sw << "DataType: 0" << std::endl;
|
||
sw << "ScanSpeed: 0" << std::endl;
|
||
sw << "PointAdjust: 1" << std::endl;
|
||
sw << "MaxTimeStamp: 0_0" << std::endl;
|
||
|
||
int maxLineIndex = 0;
|
||
int max_stamp = 0;
|
||
|
||
SG_color rgb = { 0, 0, 0 };
|
||
|
||
SG_color objColor[8] = {
|
||
{245,222,179},//淡黄色
|
||
{210,105, 30},//巧克力色
|
||
{240,230,140},//黄褐色
|
||
{135,206,235},//天蓝色
|
||
{250,235,215},//古董白
|
||
{189,252,201},//薄荷色
|
||
{221,160,221},//梅红色
|
||
{188,143,143},//玫瑰红色
|
||
};
|
||
int size = 1;
|
||
int lineIdx = 0;
|
||
for (int line = 0; line < lineNum; line++)
|
||
{
|
||
int linePtNum = (int)scanLines[line].size();
|
||
if (linePtNum == 0)
|
||
continue;
|
||
|
||
sw << "Line_" << lineIdx << "_0_" << linePtNum << std::endl;
|
||
lineIdx++;
|
||
for (int i = 0; i < linePtNum; i++)
|
||
{
|
||
SVzNL3DPosition* pt3D = &scanLines[line][i];
|
||
|
||
if (pt3D->nPointIdx == 2)
|
||
{
|
||
rgb = { 135,206,235 };
|
||
size = 5;
|
||
}
|
||
else if (pt3D->nPointIdx == 3)
|
||
{
|
||
rgb = { 250, 0, 0 };
|
||
size = 5;
|
||
}
|
||
else //if (pt3D->nPointIdx == 0)
|
||
{
|
||
rgb = { 200, 200, 200 };
|
||
size = 1;
|
||
}
|
||
float x = (float)pt3D->pt3D.x;
|
||
float y = (float)pt3D->pt3D.y;
|
||
float z = (float)pt3D->pt3D.z;
|
||
sw << "{" << x << "," << y << "," << z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
|
||
}
|
||
}
|
||
|
||
{
|
||
sw << "Line_" << lineIdx << "_0_3" << std::endl;
|
||
rgb = { 250, 0, 0 };
|
||
size = 8;
|
||
float x = (float)poseInfo.center.x;
|
||
float y = (float)poseInfo.center.y;
|
||
float z = (float)poseInfo.center.z;
|
||
sw << "{" << x << "," << y << "," << z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
|
||
|
||
x = (float)poseInfo.holeLT.x;
|
||
y = (float)poseInfo.holeLT.y;
|
||
z = (float)poseInfo.holeLT.z;
|
||
sw << "{" << x << "," << y << "," << z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
|
||
|
||
x = (float)poseInfo.holeRB.x;
|
||
y = (float)poseInfo.holeRB.y;
|
||
z = (float)poseInfo.holeRB.z;
|
||
sw << "{" << x << "," << y << "," << z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
|
||
|
||
//输出法向
|
||
size = 1;
|
||
double len = 110;
|
||
lineIdx = 0;
|
||
{
|
||
SVzNL3DPoint pt0 = { poseInfo.center.x, // - len * poseInfo.normalDir.x,
|
||
poseInfo.center.y, // - len * poseInfo.normalDir.y,
|
||
poseInfo.center.z }; // - len * poseInfo.normalDir.z };
|
||
SVzNL3DPoint pt1 = { poseInfo.center.x + len * poseInfo.normalDir.x,
|
||
poseInfo.center.y + len * poseInfo.normalDir.y,
|
||
poseInfo.center.z + len * poseInfo.normalDir.z };
|
||
|
||
SVzNL3DPoint basePt = poseInfo.center;
|
||
SVzNL3DPoint pt2 = { poseInfo.center.x + len * poseInfo.xDir.x,
|
||
poseInfo.center.y + len * poseInfo.xDir.y,
|
||
poseInfo.center.z + len * poseInfo.xDir.z };
|
||
SVzNL3DPoint pt3 = { poseInfo.center.x + len * poseInfo.yDir.x,
|
||
poseInfo.center.y + len * poseInfo.yDir.y,
|
||
poseInfo.center.z + len * poseInfo.yDir.z };
|
||
//显示法向量
|
||
sw << "Poly_" << lineIdx << "_2" << std::endl;
|
||
sw << "{" << (float)pt0.x << "," << (float)pt0.y << "," << (float)pt0.z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||
sw << "{" << pt1.x << "," << pt1.y << "," << pt1.z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||
lineIdx++;
|
||
|
||
rgb = { 0, 250, 0 };
|
||
sw << "Poly_" << lineIdx << "_2" << std::endl;
|
||
sw << "{" << (float)basePt.x << "," << (float)basePt.y << "," << (float)basePt.z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||
sw << "{" << pt2.x << "," << pt2.y << "," << pt2.z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||
lineIdx++;
|
||
|
||
rgb = { 0, 0, 250 };
|
||
sw << "Poly_" << lineIdx << "_2" << std::endl;
|
||
sw << "{" << (float)basePt.x << "," << (float)basePt.y << "," << (float)basePt.z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||
sw << "{" << pt3.x << "," << pt3.y << "," << pt3.z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||
lineIdx++;
|
||
|
||
rgb = { 0, 250, 0 };
|
||
basePt = { poseInfo.holeLT.x - len * poseInfo.xDir.x,
|
||
poseInfo.holeLT.y - len * poseInfo.xDir.y,
|
||
poseInfo.holeLT.z - len * poseInfo.xDir.z };
|
||
pt2 = { poseInfo.holeLT.x + len * poseInfo.xDir.x,
|
||
poseInfo.holeLT.y + len * poseInfo.xDir.y,
|
||
poseInfo.holeLT.z + len * poseInfo.xDir.z };
|
||
sw << "Poly_" << lineIdx << "_2" << std::endl;
|
||
sw << "{" << (float)basePt.x << "," << (float)basePt.y << "," << (float)basePt.z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||
sw << "{" << pt2.x << "," << pt2.y << "," << pt2.z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||
lineIdx++;
|
||
|
||
basePt = { poseInfo.holeRB.x - len * poseInfo.xDir.x,
|
||
poseInfo.holeRB.y - len * poseInfo.xDir.y,
|
||
poseInfo.holeRB.z - len * poseInfo.xDir.z };
|
||
pt2 = { poseInfo.holeRB.x + len * poseInfo.xDir.x,
|
||
poseInfo.holeRB.y + len * poseInfo.xDir.y,
|
||
poseInfo.holeRB.z + len * poseInfo.xDir.z };
|
||
sw << "Poly_" << lineIdx << "_2" << std::endl;
|
||
sw << "{" << (float)basePt.x << "," << (float)basePt.y << "," << (float)basePt.z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||
sw << "{" << pt2.x << "," << pt2.y << "," << pt2.z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||
lineIdx++;
|
||
}
|
||
}
|
||
sw.close();
|
||
}
|
||
|
||
void _outputRGBDScan_RGBD_rodInfo(
|
||
char* fileName,
|
||
std::vector<std::vector<SVzNL3DPosition>>& scanLines,
|
||
std::vector<SSX_rodPositionInfo>& rodInfo
|
||
)
|
||
{
|
||
int lineNum = (int)scanLines.size();
|
||
std::ofstream sw(fileName);
|
||
int realLines = lineNum;
|
||
int objNum = (int)rodInfo.size();
|
||
if (objNum > 0)
|
||
realLines += 1;
|
||
|
||
sw << "LineNum:" << realLines << std::endl;
|
||
sw << "DataType: 0" << std::endl;
|
||
sw << "ScanSpeed: 0" << std::endl;
|
||
sw << "PointAdjust: 1" << std::endl;
|
||
sw << "MaxTimeStamp: 0_0" << std::endl;
|
||
|
||
int maxLineIndex = 0;
|
||
int max_stamp = 0;
|
||
|
||
SG_color rgb = { 0, 0, 0 };
|
||
|
||
SG_color objColor[8] = {
|
||
{245,222,179},//淡黄色
|
||
{210,105, 30},//巧克力色
|
||
{240,230,140},//黄褐色
|
||
{135,206,235},//天蓝色
|
||
{250,235,215},//古董白
|
||
{189,252,201},//薄荷色
|
||
{221,160,221},//梅红色
|
||
{188,143,143},//玫瑰红色
|
||
};
|
||
int size = 1;
|
||
int lineIdx = 0;
|
||
for (int line = 0; line < lineNum; line++)
|
||
{
|
||
int linePtNum = (int)scanLines[line].size();
|
||
if (linePtNum == 0)
|
||
continue;
|
||
|
||
sw << "Line_" << lineIdx << "_0_" << linePtNum << std::endl;
|
||
lineIdx++;
|
||
for (int i = 0; i < linePtNum; i++)
|
||
{
|
||
SVzNL3DPosition* pt3D = &scanLines[line][i];
|
||
if (pt3D->nPointIdx > 0)
|
||
{
|
||
int centerFlag = pt3D->nPointIdx >> 4;
|
||
if (centerFlag > 0)
|
||
{
|
||
rgb = { 180, 0, 0 };
|
||
size = 2;
|
||
}
|
||
else
|
||
{
|
||
rgb = objColor[pt3D->nPointIdx % 8];
|
||
size = 2;
|
||
}
|
||
|
||
|
||
}
|
||
else //if (pt3D->nPointIdx == 0)
|
||
{
|
||
rgb = { 200, 200, 200 };
|
||
size = 1;
|
||
}
|
||
float x = (float)pt3D->pt3D.x;
|
||
float y = (float)pt3D->pt3D.y;
|
||
float z = (float)pt3D->pt3D.z;
|
||
sw << "{" << x << "," << y << "," << z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
|
||
}
|
||
}
|
||
|
||
if (objNum > 0)
|
||
{
|
||
sw << "Line_" << lineIdx << "_0_" << objNum << std::endl;
|
||
size = 12;
|
||
for (int i = 0; i < objNum; i++)
|
||
{
|
||
if(i == 0)
|
||
rgb = { 250, 255, 0 };
|
||
else
|
||
rgb = { 250, 0, 0 };
|
||
float x = (float)rodInfo[i].center.x;
|
||
float y = (float)rodInfo[i].center.y;
|
||
float z = (float)rodInfo[i].center.z;
|
||
sw << "{" << x << "," << y << "," << z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
|
||
}
|
||
//输出法向
|
||
size = 8;
|
||
double len = 60;
|
||
lineIdx = 0;
|
||
for (int i = 0; i < objNum; i++)
|
||
{
|
||
if (i == 0)
|
||
rgb = { 250, 255, 0 };
|
||
else
|
||
rgb = { 250, 0, 0 };
|
||
SVzNL3DPoint pt0 = { rodInfo[i].center.x, rodInfo[i].center.y, rodInfo[i].center.z };
|
||
SVzNL3DPoint pt1 = { rodInfo[i].center.x + len * rodInfo[i].axialDir.x,
|
||
rodInfo[i].center.y + len * rodInfo[i].axialDir.y,
|
||
rodInfo[i].center.z + len * rodInfo[i].axialDir.z };
|
||
SVzNL3DPoint pt2 = { rodInfo[i].center.x + len * rodInfo[i].normalDir.x,
|
||
rodInfo[i].center.y + len * rodInfo[i].normalDir.y,
|
||
rodInfo[i].center.z + len * rodInfo[i].normalDir.z };
|
||
//显示轴向量
|
||
sw << "Poly_" << lineIdx << "_2" << std::endl;
|
||
sw << "{" << (float)rodInfo[i].startPt.x << "," << (float)rodInfo[i].startPt.y << "," << (float)rodInfo[i].startPt.z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||
sw << "{" << (float)rodInfo[i].endPt.x << "," << (float)rodInfo[i].endPt.y << "," << (float)rodInfo[i].endPt.z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||
lineIdx++;
|
||
//显示法向量
|
||
sw << "Poly_" << lineIdx << "_2" << std::endl;
|
||
sw << "{" << (float)pt0.x << "," << (float)pt0.y << "," << (float)pt0.z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||
sw << "{" << (float)pt2.x << "," << (float)pt2.y << "," << (float)pt2.z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||
lineIdx++;
|
||
}
|
||
lineIdx++;
|
||
}
|
||
sw.close();
|
||
}
|
||
|
||
void _outputRGBDScan_RGBD_weldSeam(
|
||
char* fileName,
|
||
std::vector<std::vector<SVzNL3DPosition>>& scanLines,
|
||
std::vector<SSX_weldSeamInfo>& weldSeamInfo
|
||
)
|
||
{
|
||
int lineNum = (int)scanLines.size();
|
||
std::ofstream sw(fileName);
|
||
int realLines = lineNum;
|
||
int objNum = (int)weldSeamInfo.size();
|
||
if (objNum > 0)
|
||
realLines += 1;
|
||
|
||
sw << "LineNum:" << realLines << std::endl;
|
||
sw << "DataType: 0" << std::endl;
|
||
sw << "ScanSpeed: 0" << std::endl;
|
||
sw << "PointAdjust: 1" << std::endl;
|
||
sw << "MaxTimeStamp: 0_0" << std::endl;
|
||
|
||
int maxLineIndex = 0;
|
||
int max_stamp = 0;
|
||
|
||
SG_color rgb = { 0, 0, 0 };
|
||
|
||
SG_color objColor[8] = {
|
||
{245,222,179},//淡黄色
|
||
{210,105, 30},//巧克力色
|
||
{240,230,140},//黄褐色
|
||
{135,206,235},//天蓝色
|
||
{250,235,215},//古董白
|
||
{189,252,201},//薄荷色
|
||
{221,160,221},//梅红色
|
||
{188,143,143},//玫瑰红色
|
||
};
|
||
int size = 1;
|
||
int lineIdx = 0;
|
||
for (int line = 0; line < lineNum; line++)
|
||
{
|
||
int linePtNum = (int)scanLines[line].size();
|
||
if (linePtNum == 0)
|
||
continue;
|
||
|
||
sw << "Line_" << lineIdx << "_0_" << linePtNum << std::endl;
|
||
lineIdx++;
|
||
for (int i = 0; i < linePtNum; i++)
|
||
{
|
||
SVzNL3DPosition* pt3D = &scanLines[line][i];
|
||
if (pt3D->nPointIdx > 0)
|
||
{
|
||
int centerFlag = pt3D->nPointIdx >> 4;
|
||
if (centerFlag > 0)
|
||
{
|
||
if (centerFlag <= 2)
|
||
{
|
||
rgb = { 180, 0, 0 };
|
||
size = 2;
|
||
}
|
||
else if(centerFlag == 4)
|
||
{
|
||
rgb = { 0, 250, 0 };
|
||
size = 4;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
rgb = objColor[pt3D->nPointIdx % 8];
|
||
size = 2;
|
||
}
|
||
}
|
||
else //if (pt3D->nPointIdx == 0)
|
||
{
|
||
rgb = { 200, 200, 200 };
|
||
size = 1;
|
||
}
|
||
float x = (float)pt3D->pt3D.x;
|
||
float y = (float)pt3D->pt3D.y;
|
||
float z = (float)pt3D->pt3D.z;
|
||
sw << "{" << x << "," << y << "," << z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
|
||
}
|
||
}
|
||
|
||
if (objNum > 0)
|
||
{
|
||
std::vector<SVzNL3DPoint> weldPoints;
|
||
for (int i = 0; i < objNum; i++)
|
||
{
|
||
if (weldSeamInfo[i].weldType == KeWD_WELD_POINT)
|
||
weldPoints.push_back(weldSeamInfo[i].center);
|
||
else
|
||
{
|
||
weldPoints.push_back(weldSeamInfo[i].startPt);
|
||
weldPoints.push_back(weldSeamInfo[i].center);
|
||
weldPoints.push_back(weldSeamInfo[i].endPt);
|
||
}
|
||
}
|
||
|
||
sw << "Line_" << lineIdx << "_0_" << (int)weldPoints.size() << std::endl;
|
||
size = 15;
|
||
for (int i = 0; i < (int)weldPoints.size(); i++)
|
||
{
|
||
rgb = { 250, 0, 0 };
|
||
float x = (float)weldPoints[i].x;
|
||
float y = (float)weldPoints[i].y;
|
||
float z = (float)weldPoints[i].z;
|
||
sw << "{" << x << "," << y << "," << z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
|
||
}
|
||
//输出法向
|
||
size = 4;
|
||
double len1 = 20;
|
||
double len2 = 20;
|
||
lineIdx = 0;
|
||
for (int i = 0; i < objNum; i++)
|
||
{
|
||
SVzNL3DPoint pt0, pt1;
|
||
if (weldSeamInfo[i].weldType == KeWD_WELD_POINT)
|
||
{
|
||
pt0 = weldSeamInfo[i].center;
|
||
pt1 = { weldSeamInfo[i].center.x + len1 * weldSeamInfo[i].axialDir.x,
|
||
weldSeamInfo[i].center.y + len1 * weldSeamInfo[i].axialDir.y,
|
||
weldSeamInfo[i].center.z + len1 * weldSeamInfo[i].axialDir.z };
|
||
}
|
||
else
|
||
{
|
||
pt0 = weldSeamInfo[i].startPt;
|
||
pt1 = weldSeamInfo[i].endPt;
|
||
}
|
||
|
||
SVzNL3DPoint pt2 = { weldSeamInfo[i].center.x, weldSeamInfo[i].center.y, weldSeamInfo[i].center.z };
|
||
SVzNL3DPoint pt3 = { weldSeamInfo[i].center.x + len2 * weldSeamInfo[i].normalDir.x,
|
||
weldSeamInfo[i].center.y + len2 * weldSeamInfo[i].normalDir.y,
|
||
weldSeamInfo[i].center.z + len2 * weldSeamInfo[i].normalDir.z };
|
||
//显示轴向量
|
||
rgb = { 0, 0, 250 };
|
||
sw << "Poly_" << lineIdx << "_2" << std::endl;
|
||
sw << "{" << (float)pt0.x << "," << (float)pt0.y << "," << (float)pt0.z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||
sw << "{" << (float)pt1.x << "," << (float)pt1.y << "," << (float)pt1.z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||
lineIdx++;
|
||
//显示法向量
|
||
rgb = { 250, 0, 0 };
|
||
sw << "Poly_" << lineIdx << "_2" << std::endl;
|
||
sw << "{" << (float)pt2.x << "," << (float)pt2.y << "," << (float)pt2.z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||
sw << "{" << (float)pt3.x << "," << (float)pt3.y << "," << (float)pt3.z << "}-";
|
||
sw << "{0,0}-{0,0}-";
|
||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||
lineIdx++;
|
||
}
|
||
lineIdx++;
|
||
}
|
||
sw.close();
|
||
}
|
||
|
||
#define SCREW_TEST_GROUP 12
|
||
void screwTest(void)
|
||
{
|
||
const char* dataPath[SCREW_TEST_GROUP] = {
|
||
"F:/ShangGu/项目/冠钦项目/配天螺杆测量/数据/模拟数据/", //0
|
||
"F:/ShangGu/项目/冠钦项目/配天螺杆测量/配天现场点云/螺杆点云2/上方两根/", //1
|
||
"F:/ShangGu/项目/冠钦项目/配天螺杆测量/配天现场点云/螺杆点云3/", //2
|
||
"F:/ShangGu/项目/冠钦项目/配天螺杆测量/配天现场点云/螺杆点云4/位置1/", //3
|
||
"F:/ShangGu/项目/冠钦项目/配天螺杆测量/配天现场点云/螺杆点云4/位置2/", //4
|
||
"F:/ShangGu/项目/冠钦项目/配天螺杆测量/配天现场点云/螺杆点云4/位置2未动螺杆拧进去100mm左右/", //5
|
||
"F:/ShangGu/项目/冠钦项目/配天螺杆测量/配天现场点云/螺杆点云4/位置2向前100mm螺杆拧进去100mm左右/", //6
|
||
"F:/ShangGu/项目/冠钦项目/配天螺杆测量/配天现场点云/螺杆点云20260621/另一根螺杆/", //7
|
||
"F:/ShangGu/项目/冠钦项目/配天螺杆测量/配天现场点云/螺杆点云20260621/拍照点1/", //8
|
||
"F:/ShangGu/项目/冠钦项目/配天螺杆测量/配天现场点云/螺杆点云20260621/拍照点1xyz移动10mm/", //9
|
||
"F:/ShangGu/项目/冠钦项目/配天螺杆测量/配天现场点云/异常点云0615/", //10
|
||
"F:/ShangGu/项目/冠钦项目/配天螺杆测量/配天现场点云/异常点云0618/", //11
|
||
|
||
};
|
||
|
||
SVzNLRange fileIdx[SCREW_TEST_GROUP] = {
|
||
{1,4},{1,30},{1,11},
|
||
{1,20}, {1,20}, {1,5}, {1,21},
|
||
{1,10}, {1,10}, {1,10},
|
||
{1,9},{1,30}
|
||
};
|
||
|
||
const char* ver = wd_rodAndBarDetectionVersion();
|
||
printf("ver:%s\n", ver);
|
||
|
||
for (int grp = 11; grp <= 11; grp++)
|
||
{
|
||
for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++)
|
||
{
|
||
//fidx =2;
|
||
char _scan_file[256];
|
||
|
||
if(0 == grp)
|
||
sprintf_s(_scan_file, "%sLaserData_%d.txt", dataPath[grp], fidx);
|
||
else if( (grp>= 7)&&(grp <= 9))
|
||
sprintf_s(_scan_file, "%sLaserline_%d.txt", dataPath[grp], fidx);
|
||
else if(10 == grp)
|
||
sprintf_s(_scan_file, "%s%d_LaserData.txt", dataPath[grp], fidx);
|
||
else
|
||
sprintf_s(_scan_file, "%s%d_LaserData_Jl26C299.txt", dataPath[grp], fidx);
|
||
|
||
|
||
std::vector<std::vector< SVzNL3DPosition>> scanLines;
|
||
wdReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines);
|
||
|
||
//转成plyTxt格式
|
||
//sprintf_s(_scan_file, "%s%d_ply_Hi229229.txt", dataPath[grp], fidx);
|
||
//wdSavePlyTxt(_scan_file, scanLines);
|
||
|
||
long t1 = (long)GetTickCount64();//统计时间
|
||
|
||
double rodDiameter;
|
||
if (grp == 0)
|
||
rodDiameter = 10.0;
|
||
else
|
||
rodDiameter = 32.0; //现场螺杆直径28mm
|
||
|
||
//double rodDiameter = 10.0;
|
||
|
||
SSG_cornerParam cornerParam;
|
||
cornerParam.cornerTh = 30; //45度角
|
||
cornerParam.scale = rodDiameter / 4; // algoParam.bagParam.bagH / 8; // 15; // algoParam.bagParam.bagH / 8;
|
||
cornerParam.minEndingGap = 20; // algoParam.bagParam.bagW / 4;
|
||
cornerParam.minEndingGap_z = 5.0;
|
||
cornerParam.jumpCornerTh_1 = 15; //水平角度,小于此角度视为水平
|
||
cornerParam.jumpCornerTh_2 = 60;
|
||
|
||
SSG_outlierFilterParam filterParam;
|
||
filterParam.continuityTh = 20.0; //噪声滤除。当相邻点的z跳变大于此门限时,检查是否为噪声。若长度小于outlierLen, 视为噪声
|
||
filterParam.outlierTh = 5;
|
||
|
||
SSG_treeGrowParam growParam;
|
||
growParam.maxLineSkipNum = 30;
|
||
growParam.yDeviation_max = 5.0;
|
||
growParam.maxSkipDistance = 30.0;
|
||
growParam.zDeviation_max = 50;//
|
||
growParam.minLTypeTreeLen = 50; //mm, 螺杆长度
|
||
growParam.minVTypeTreeLen = 50; //mm
|
||
|
||
bool isHorizonScan = true; //true:激光线平行槽道;false:激光线垂直槽道
|
||
int errCode = 0;
|
||
std::vector<SSX_rodPoseInfo> screwInfo;
|
||
sx_hexHeadScrewMeasure_PCA(
|
||
scanLines,
|
||
//isHorizonScan, //true:激光线平行槽道;false:激光线垂直槽道
|
||
cornerParam,
|
||
filterParam,
|
||
growParam,
|
||
rodDiameter,
|
||
screwInfo,
|
||
&errCode);
|
||
|
||
long t2 = (long)GetTickCount64();
|
||
|
||
//输出测试结果
|
||
char _out_file[256];
|
||
sprintf_s(_out_file, "%sresult\\%d_result.txt", dataPath[grp], fidx);
|
||
_outputRGBDScan_RGBD(_out_file, scanLines, screwInfo);
|
||
sprintf_s(_out_file, "%sresult\\%d_screw_info.txt", dataPath[grp], fidx);
|
||
_outputChanneltInfo(_out_file, screwInfo);
|
||
|
||
if (screwInfo.size() > 0)
|
||
{
|
||
SVzNL3DPoint zAxis = { 0, 0, 1.0 };
|
||
float angle = _computeVecAngle(screwInfo[0].axialDir, zAxis);
|
||
printf("%s: %d(ms), errCode=%d, {%f, %f, %f}, 与Z轴夹角=%f \n", _scan_file, (int)(t2 - t1), errCode,
|
||
(float)screwInfo[0].center.x, (float)screwInfo[0].center.y, (float)screwInfo[0].center.z, angle);
|
||
}
|
||
else
|
||
printf("%s: %d(ms), errCode=%d\n", _scan_file, (int)(t2 - t1), errCode);
|
||
}
|
||
}
|
||
}
|
||
|
||
#define LOCATING_PALTE_TEST_GROUP 1
|
||
void locatingPlateTest(void)
|
||
{
|
||
const char* dataPath[LOCATING_PALTE_TEST_GROUP] = {
|
||
"F:/ShangGu/项目/冠钦项目/配天螺杆测量/配天现场点云/定位盘点云/", //0
|
||
};
|
||
|
||
SVzNLRange fileIdx[LOCATING_PALTE_TEST_GROUP] = {
|
||
{1,17},
|
||
};
|
||
|
||
const char* ver = wd_rodAndBarDetectionVersion();
|
||
printf("ver:%s\n", ver);
|
||
|
||
for (int grp = 0; grp < LOCATING_PALTE_TEST_GROUP; grp++)
|
||
{
|
||
for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++)
|
||
{
|
||
//fidx =2;
|
||
char _scan_file[256];
|
||
sprintf_s(_scan_file, "%sLaserData_%d.txt", dataPath[grp], fidx);
|
||
|
||
std::vector<std::vector< SVzNL3DPosition>> scanLines;
|
||
wdReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines);
|
||
|
||
//转成plyTxt格式
|
||
//sprintf_s(_scan_file, "%s%d_ply_Hi229229.txt", dataPath[grp], fidx);
|
||
//wdSavePlyTxt(_scan_file, scanLines);
|
||
|
||
long t1 = (long)GetTickCount64();//统计时间
|
||
|
||
double rodDiameter = 10.0;
|
||
|
||
SSG_cornerParam cornerParam;
|
||
cornerParam.cornerTh = 60; //45度角
|
||
cornerParam.scale = rodDiameter / 4; // algoParam.bagParam.bagH / 8; // 15; // algoParam.bagParam.bagH / 8;
|
||
cornerParam.minEndingGap = 20; // algoParam.bagParam.bagW / 4;
|
||
cornerParam.minEndingGap_z = 5.0;
|
||
cornerParam.jumpCornerTh_1 = 15; //水平角度,小于此角度视为水平
|
||
cornerParam.jumpCornerTh_2 = 60;
|
||
|
||
int errCode = 0;
|
||
SSX_platePoseInfo centerPose = sx_getLocationPlatePose(
|
||
scanLines,
|
||
cornerParam,
|
||
& errCode);
|
||
|
||
long t2 = (long)GetTickCount64();
|
||
printf("%s: %d(ms)!\n", _scan_file, (int)(t2 - t1));
|
||
//输出测试结果
|
||
sprintf_s(_scan_file, "%sresult\\%d_result.txt", dataPath[grp], fidx);
|
||
_outputRGBDScan_RGBD_centerPose(_scan_file, scanLines, centerPose);
|
||
sprintf_s(_scan_file, "%sresult\\%d_screw_info.txt", dataPath[grp], fidx);
|
||
_outputPlatePiseInfo(_scan_file, centerPose);
|
||
}
|
||
}
|
||
}
|
||
|
||
#define NEW_LOCATING_PALTE_TEST_GROUP 2
|
||
void newLocatingPlateTest(void)
|
||
{
|
||
const char* dataPath[NEW_LOCATING_PALTE_TEST_GROUP] = {
|
||
"F:/ShangGu/项目/冠钦项目/配天螺杆测量/配天现场点云/定位盘点云20260521/", //0
|
||
"F:/ShangGu/项目/冠钦项目/配天螺杆测量/配天现场点云/定位盘点云20260603/", //1
|
||
};
|
||
|
||
SVzNLRange fileIdx[NEW_LOCATING_PALTE_TEST_GROUP] = {
|
||
{12,13}, {1,52}
|
||
};
|
||
|
||
const char* ver = wd_rodAndBarDetectionVersion();
|
||
printf("ver:%s\n", ver);
|
||
|
||
for (int grp = 1; grp < NEW_LOCATING_PALTE_TEST_GROUP; grp++)
|
||
{
|
||
for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++)
|
||
{
|
||
//fidx =16;
|
||
char _scan_file[256];
|
||
sprintf_s(_scan_file, "%sLaserData_%d.txt", dataPath[grp], fidx);
|
||
|
||
std::vector<std::vector< SVzNL3DPosition>> scanLines;
|
||
wdReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines);
|
||
|
||
//转成plyTxt格式
|
||
//sprintf_s(_scan_file, "%s%d_ply_Hi229229.txt", dataPath[grp], fidx);
|
||
//wdSavePlyTxt(_scan_file, scanLines);
|
||
|
||
long t1 = (long)GetTickCount64();//统计时间
|
||
|
||
SSG_cornerParam cornerParam;
|
||
cornerParam.cornerTh = 45; //45度角
|
||
cornerParam.scale = 5.0; // algoParam.bagParam.bagH / 8; // 15; // algoParam.bagParam.bagH / 8;
|
||
cornerParam.minEndingGap = 20; // algoParam.bagParam.bagW / 4;
|
||
cornerParam.minEndingGap_z = 5.0;
|
||
cornerParam.jumpCornerTh_1 = 15; //水平角度,小于此角度视为水平
|
||
cornerParam.jumpCornerTh_2 = 60;
|
||
|
||
int errCode = 0;
|
||
SSX_platePoseInfo centerPose = sx_getLocationPlatePose_new(
|
||
scanLines,
|
||
cornerParam,
|
||
&errCode);
|
||
|
||
long t2 = (long)GetTickCount64();
|
||
printf("%s: %d(ms),errCode=%d\n", _scan_file, (int)(t2 - t1), errCode);
|
||
//输出测试结果
|
||
sprintf_s(_scan_file, "%sresult\\%d_result.txt", dataPath[grp], fidx);
|
||
_outputRGBDScan_RGBD_centerPose(_scan_file, scanLines, centerPose);
|
||
sprintf_s(_scan_file, "%sresult\\%d_screw_info.txt", dataPath[grp], fidx);
|
||
_outputPlatePiseInfo(_scan_file, centerPose);
|
||
}
|
||
}
|
||
}
|
||
|
||
;
|
||
void _removeNullData(std::vector<std::vector< SVzNL3DPosition>>& scanLines, double _F, std::vector<std::vector< SVzNLPointXYZRGBA>>& scanData)
|
||
{
|
||
std::vector< SVzNLPointXYZRGBA> validPoints;
|
||
for (int line = 0; line < (int)scanLines.size(); line++)
|
||
{
|
||
for (int j = 0; j < (int)scanLines[line].size(); j++)
|
||
{
|
||
if (scanLines[line][j].pt3D.z > 1e-4)
|
||
{
|
||
SVzNLPointXYZRGBA a_pt;
|
||
double v = _F * scanLines[line][j].pt3D.y / scanLines[line][j].pt3D.z + 2000;
|
||
a_pt.nRGB = (int)(v + 0.5);
|
||
a_pt.x = scanLines[line][j].pt3D.x;
|
||
a_pt.y = scanLines[line][j].pt3D.y;
|
||
a_pt.z = scanLines[line][j].pt3D.z;
|
||
validPoints.push_back(a_pt);
|
||
}
|
||
}
|
||
}
|
||
|
||
std::vector< SVzNLPointXYZRGBA> a_line;
|
||
SVzNLPointXYZRGBA pre_pt;
|
||
pre_pt.x = 0;
|
||
pre_pt.y = 0;
|
||
pre_pt.z = 0;
|
||
pre_pt.nRGB = -1;
|
||
for (int i = 0; i < validPoints.size(); i++)
|
||
{
|
||
if (validPoints[i].nRGB < (pre_pt.nRGB - 10))
|
||
{
|
||
if (a_line.size() > 0)
|
||
scanData.push_back(a_line);
|
||
a_line.clear();
|
||
}
|
||
a_line.push_back(validPoints[i]);
|
||
pre_pt = validPoints[i];
|
||
}
|
||
if(a_line.size() > 0)
|
||
scanData.push_back(a_line);
|
||
return;
|
||
}
|
||
void _convertToGridData_XYZRGB(std::vector<std::vector< SVzNLPointXYZRGBA>>& scanData, double _F, std::vector<std::vector< SVzNL3DPosition>>& gridData)
|
||
{
|
||
int lineNum = (int)scanData.size();
|
||
int min_y = 100000000;
|
||
int max_y = -10000000;
|
||
int validStartLine = -1;
|
||
int validEndLine = -1;
|
||
for (int line = 0; line < lineNum; line++)
|
||
{
|
||
if (scanData[line].size() > 0)
|
||
{
|
||
if (validStartLine < 0)
|
||
{
|
||
validStartLine = line;
|
||
validEndLine = line;
|
||
}
|
||
else
|
||
validEndLine = line;
|
||
}
|
||
|
||
for (int i = 0; i < (int)scanData[line].size(); i++)
|
||
{
|
||
SVzNLPointXYZRGBA& a_pt = scanData[line][i];
|
||
if (a_pt.z > 1e-4)
|
||
{
|
||
double v = _F * a_pt.y / a_pt.z + 2000;
|
||
a_pt.nRGB = (int)(v + 0.5);
|
||
max_y = max_y < (int)a_pt.nRGB ? (int)a_pt.nRGB : max_y;
|
||
min_y = min_y > (int)a_pt.nRGB ? (int)a_pt.nRGB : min_y;
|
||
}
|
||
}
|
||
}
|
||
if (min_y == 100000000)
|
||
return;
|
||
|
||
int vldLineNum = validEndLine - validStartLine + 1;
|
||
gridData.resize(vldLineNum);
|
||
int pt_counter = max_y - min_y + 1;
|
||
for (int i = 0; i < vldLineNum; i++)
|
||
{
|
||
gridData[i].resize(pt_counter);
|
||
for (int j = 0; j < pt_counter; j++)
|
||
{
|
||
gridData[i][j].nPointIdx = j;
|
||
gridData[i][j].pt3D.x = 0;
|
||
gridData[i][j].pt3D.y = 0;
|
||
gridData[i][j].pt3D.z = 0;
|
||
}
|
||
}
|
||
for (int line = validStartLine; line <= validEndLine; line++)
|
||
{
|
||
int gridLine = line - validStartLine;
|
||
for (int i = 0; i < (int)scanData[line].size(); i++)
|
||
{
|
||
SVzNLPointXYZRGBA& a_pt = scanData[line][i];
|
||
if (a_pt.z > 1e-4)
|
||
{
|
||
int pt_id = a_pt.nRGB - min_y;
|
||
gridData[gridLine][pt_id].pt3D.x = a_pt.x;
|
||
gridData[gridLine][pt_id].pt3D.y = a_pt.y;
|
||
gridData[gridLine][pt_id].pt3D.z = a_pt.z;
|
||
}
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
#define ROD_POSITION_TEST_GROUP 6
|
||
#define TEST_CONVERT_TO_GRID 0
|
||
#define TEST_COMPUTE_CALIB_PARA 0
|
||
#define TEST_COMPUTE_ROD_POSITION 1
|
||
void rodPositionTest(void)
|
||
{
|
||
#if TEST_CONVERT_TO_GRID
|
||
//将数据转换成栅格格式格式
|
||
char _scan_dir[256];
|
||
int lineNum = 0;
|
||
float lineV = 0.0f;
|
||
int dataCalib = 0;
|
||
int maxTimeStamp = 0;
|
||
int clockPerSecond = 0;
|
||
sprintf_s(_scan_dir, "F:/ShangGu/项目/冠钦项目/矩森棒材抓取/空料框及内剩一根棒材/");
|
||
char _scan_src_file[256];
|
||
double _F = 1219.15; //f
|
||
for (int i = 1; i <= 3; i++)
|
||
{
|
||
//read ply txt
|
||
sprintf_s(_scan_src_file, "%sLaserDataRAW_%d.txt", _scan_dir, i);
|
||
|
||
std::vector<std::vector< SVzNL3DPosition>> scanLines;
|
||
wdReadLaserScanPointFromFile_XYZ_vector(_scan_src_file, scanLines);
|
||
|
||
std::vector<std::vector< SVzNLPointXYZRGBA>> scanData;
|
||
_removeNullData(scanLines, _F, scanData);
|
||
|
||
std::vector<std::vector< SVzNL3DPosition>> gridData;
|
||
_convertToGridData_XYZRGB(scanData, _F, gridData);
|
||
char _out_file[256];
|
||
sprintf_s(_out_file, "%sLaserData_%d.txt", _scan_dir, i);
|
||
_outputScanDataFile(_out_file, gridData, 0.0f, 0, 0);
|
||
|
||
printf("%s: convert done!\n", _scan_src_file);
|
||
}
|
||
printf("all converted done!\n", _scan_src_file);
|
||
#endif
|
||
#if TEST_COMPUTE_CALIB_PARA
|
||
const char* calibDataPath = "F:/ShangGu/项目/冠钦项目/矩森棒材抓取/异常点云/";
|
||
char _calib_datafile[256];
|
||
sprintf_s(_calib_datafile, "%sGroundData_1.txt", calibDataPath);
|
||
int lineNum = 0;
|
||
float lineV = 0.0f;
|
||
int dataCalib = 0;
|
||
int maxTimeStamp = 0;
|
||
int clockPerSecond = 0;
|
||
std::vector<std::vector< SVzNL3DPosition>> scanData;
|
||
wdReadLaserScanPointFromFile_XYZ_vector(_calib_datafile, scanData);
|
||
|
||
lineNum = (int)scanData.size();
|
||
if (scanData.size() > 0)
|
||
{
|
||
SSG_planeCalibPara calibPara = sx_rodPosition_getBaseCalibPara(scanData);
|
||
//结果进行验证
|
||
for (int i = 0; i < lineNum; i++)
|
||
{
|
||
if (i == 14)
|
||
int kkk = 1;
|
||
//行处理
|
||
//调平,去除地面
|
||
sx_rodPosition_lineDataR(scanData[i], calibPara.planeCalib, -1);
|
||
}
|
||
//
|
||
char calibFile[250];
|
||
sprintf_s(calibFile, "%sground_calib_para.txt", calibDataPath);
|
||
_outputCalibPara(calibFile, calibPara);
|
||
char _out_file[256];
|
||
sprintf_s(_out_file, "%sGroundData_1_calib_verify.txt", calibDataPath);
|
||
|
||
_outputScanDataFile(_out_file, scanData, lineV, maxTimeStamp, clockPerSecond);
|
||
#if 0
|
||
for (int fidx = fileIdx[cvtGrp].nMin; fidx <= fileIdx[cvtGrp].nMax; fidx++)
|
||
{
|
||
//fidx =4;
|
||
char _scan_file[256];
|
||
sprintf_s(_scan_file, "%sLaserData_%d.txt", dataPath[cvtGrp], fidx);
|
||
std::vector<std::vector< SVzNL3DPosition>> scanLines;
|
||
vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines);
|
||
if (scanLines.size() == 0)
|
||
continue;
|
||
lineNum = (int)scanLines.size();
|
||
for (int i = 0; i < lineNum; i++)
|
||
{
|
||
//调平,去除地面
|
||
wd_lineDataR(scanLines[i], calibPara.planeCalib, -1);
|
||
}
|
||
sprintf_s(_scan_file, "%sLaserData_%d_calib_verify.txt", dataPath[cvtGrp], fidx);
|
||
int headNullLines = 0;
|
||
_outputScanDataFile_vector(_scan_file, scanLines, false, &headNullLines);
|
||
}
|
||
#endif
|
||
printf("%s: calib done!\n", _calib_datafile);
|
||
}
|
||
#endif
|
||
|
||
#if TEST_COMPUTE_ROD_POSITION
|
||
const char* dataPath[ROD_POSITION_TEST_GROUP] = {
|
||
"F:/ShangGu/项目/冠钦项目/矩森棒材抓取/测试数据/", //0
|
||
"F:/ShangGu/项目/冠钦项目/矩森棒材抓取/空料框及内剩一根棒材/", //1
|
||
"F:/ShangGu/项目/冠钦项目/矩森棒材抓取/其它尺寸棒材点云/", //2
|
||
|
||
"F:/ShangGu/项目/冠钦项目/胶布圆棒抓取/模拟测试数据/", //3
|
||
"F:/ShangGu/项目/冠钦项目/胶布圆棒抓取/模拟测试数据2/", //4
|
||
|
||
"F:/ShangGu/项目/冠钦项目/矩森棒材抓取/异常点云/", //5
|
||
};
|
||
|
||
SVzNLRange fileIdx[ROD_POSITION_TEST_GROUP] = {
|
||
{1,8}, {1,3}, {1,31},
|
||
{1,5},{1,11},{1,26}
|
||
};
|
||
|
||
const char* ver = wd_rodAndBarDetectionVersion();
|
||
printf("ver:%s\n", ver);
|
||
|
||
for (int grp = 5; grp <= 5; grp++)
|
||
{
|
||
SSG_planeCalibPara poseCalibPara;
|
||
//初始化成单位阵
|
||
poseCalibPara.planeCalib[0] = 1.0;
|
||
poseCalibPara.planeCalib[1] = 0.0;
|
||
poseCalibPara.planeCalib[2] = 0.0;
|
||
poseCalibPara.planeCalib[3] = 0.0;
|
||
poseCalibPara.planeCalib[4] = 1.0;
|
||
poseCalibPara.planeCalib[5] = 0.0;
|
||
poseCalibPara.planeCalib[6] = 0.0;
|
||
poseCalibPara.planeCalib[7] = 0.0;
|
||
poseCalibPara.planeCalib[8] = 1.0;
|
||
poseCalibPara.planeHeight = -1.0;
|
||
for (int i = 0; i < 9; i++)
|
||
poseCalibPara.invRMatrix[i] = poseCalibPara.planeCalib[i];
|
||
|
||
char calibFile[250];
|
||
sprintf_s(calibFile, "%sground_calib_para.txt", dataPath[grp]);
|
||
poseCalibPara = _readCalibPara(calibFile);
|
||
|
||
sprintf_s(calibFile, "%sparameter.txt", dataPath[grp]);
|
||
std::vector<SSX_rodParam> rodParas;
|
||
if (grp <= 2)
|
||
_readRodParas(calibFile, rodParas);
|
||
|
||
for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++)
|
||
{
|
||
//fidx =16;
|
||
char _scan_file[256];
|
||
if( (3 == grp) ||(4 == grp))
|
||
sprintf_s(_scan_file, "%s%d_LaserData_Hi229156.txt", dataPath[grp], fidx);
|
||
else if(5 == grp)
|
||
sprintf_s(_scan_file, "%s%d_LaserData_Ik256066.txt", dataPath[grp], fidx);
|
||
else
|
||
sprintf_s(_scan_file, "%sLaserData_%d.txt", dataPath[grp], fidx);
|
||
|
||
std::vector<std::vector< SVzNL3DPosition>> scanLines;
|
||
wdReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines);
|
||
|
||
//转成plyTxt格式
|
||
//sprintf_s(_scan_file, "%s%d_ply_Hi229229.txt", dataPath[grp], fidx);
|
||
//wdSavePlyTxt(_scan_file, scanLines);
|
||
|
||
long t1 = (long)GetTickCount64();//统计时间
|
||
|
||
SSX_rodParam rodParam;
|
||
if (grp <= 2)
|
||
{
|
||
rodParam = rodParas[fidx];
|
||
}
|
||
else if (grp == 5)
|
||
{
|
||
rodParam.diameter = 96.0; //圆棒直径
|
||
rodParam.len = 440;
|
||
}
|
||
else
|
||
{
|
||
rodParam.diameter = 68.0; //圆棒直径
|
||
rodParam.len = 187;
|
||
}
|
||
|
||
SSG_cornerParam cornerParam;
|
||
cornerParam.cornerTh = 45; //45度角
|
||
cornerParam.scale = rodParam.diameter / 4; // algoParam.bagParam.bagH / 8; // 15; // algoParam.bagParam.bagH / 8;
|
||
cornerParam.minEndingGap = 20; // algoParam.bagParam.bagW / 4;
|
||
cornerParam.minEndingGap_z = 5.0;
|
||
cornerParam.jumpCornerTh_1 = 15; //水平角度,小于此角度视为水平
|
||
cornerParam.jumpCornerTh_2 = 60;
|
||
|
||
SSG_outlierFilterParam filterParam;
|
||
filterParam.continuityTh = 5.0; //噪声滤除。当相邻点的z跳变大于此门限时,检查是否为噪声。若长度小于outlierLen, 视为噪声
|
||
filterParam.outlierTh = 5;
|
||
|
||
SSG_treeGrowParam growParam;
|
||
growParam.maxLineSkipNum = 5;
|
||
growParam.yDeviation_max = 10.0;
|
||
growParam.maxSkipDistance = 10.0;
|
||
growParam.zDeviation_max = 10.0;//
|
||
growParam.minLTypeTreeLen = rodParam.len * 0.75; //mm, 螺杆长度
|
||
growParam.minVTypeTreeLen = rodParam.len * 0.75; //mm
|
||
|
||
bool isHorizonScan = true; //true:激光线平行槽道;false:激光线垂直槽道
|
||
int errCode = 0;
|
||
std::vector<SSX_rodPositionInfo> rodInfo;
|
||
sx_rodPositioning(
|
||
scanLines,
|
||
poseCalibPara,
|
||
cornerParam,
|
||
filterParam,
|
||
growParam,
|
||
rodParam,
|
||
rodInfo,
|
||
&errCode);
|
||
|
||
long t2 = (long)GetTickCount64();
|
||
printf("%s: %d(ms),errCode=%d\n", _scan_file, (int)(t2 - t1),errCode);
|
||
//输出测试结果
|
||
sprintf_s(_scan_file, "%sresult\\%d_result.txt", dataPath[grp], fidx);
|
||
_outputRGBDScan_RGBD_rodInfo(_scan_file, scanLines, rodInfo);
|
||
sprintf_s(_scan_file, "%sresult\\%d_screw_info.txt", dataPath[grp], fidx);
|
||
_outputRodtInfo(_scan_file, rodInfo);
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
|
||
int counterValidPts(std::vector<SVzNL3DPosition>& lineData)
|
||
{
|
||
int num = 0;
|
||
for (int i = 0; i < (int)lineData.size(); i++)
|
||
{
|
||
if (lineData[i].pt3D.z > 1e-4)
|
||
num++;
|
||
else
|
||
{
|
||
lineData[i].pt3D = { 0, 0, 0 };
|
||
}
|
||
}
|
||
return num;
|
||
}
|
||
|
||
#define WELD_SEAM_TEST_GROUP 4
|
||
void rodWeldSeamPosition_test(void)
|
||
{
|
||
const char* dataPath[WELD_SEAM_TEST_GROUP] = {
|
||
"F:/ShangGu/项目/冠钦项目/筑裕视觉钢结构焊接/视觉照片1/", //0
|
||
"F:/ShangGu/项目/冠钦项目/筑裕视觉钢结构焊接/视觉照片2/", //1
|
||
"F:/ShangGu/项目/冠钦项目/筑裕视觉钢结构焊接/数据3/特征点1/", //2
|
||
"F:/ShangGu/项目/冠钦项目/筑裕视觉钢结构焊接/数据3/特征点2/", //3
|
||
};
|
||
|
||
SVzNLRange fileIdx[WELD_SEAM_TEST_GROUP] = {
|
||
{1,20},{1,20},{1,27}, { 1,21 },
|
||
};
|
||
|
||
const char* ver = wd_rodAndBarDetectionVersion();
|
||
printf("ver:%s\n", ver);
|
||
|
||
for (int grp = 2; grp < WELD_SEAM_TEST_GROUP; grp++)
|
||
{
|
||
SSG_planeCalibPara poseCalibPara;
|
||
//初始化成单位阵
|
||
poseCalibPara.planeCalib[0] = 1.0;
|
||
poseCalibPara.planeCalib[1] = 0.0;
|
||
poseCalibPara.planeCalib[2] = 0.0;
|
||
poseCalibPara.planeCalib[3] = 0.0;
|
||
poseCalibPara.planeCalib[4] = 1.0;
|
||
poseCalibPara.planeCalib[5] = 0.0;
|
||
poseCalibPara.planeCalib[6] = 0.0;
|
||
poseCalibPara.planeCalib[7] = 0.0;
|
||
poseCalibPara.planeCalib[8] = 1.0;
|
||
poseCalibPara.planeHeight = -1.0;
|
||
for (int i = 0; i < 9; i++)
|
||
poseCalibPara.invRMatrix[i] = poseCalibPara.planeCalib[i];
|
||
//char calibFile[250];
|
||
//sprintf_s(calibFile, "%sground_calib_para.txt", dataPath[grp]);
|
||
//poseCalibPara = _readCalibPara(calibFile);
|
||
|
||
for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++)
|
||
{
|
||
//fidx =1;
|
||
char _scan_file[256];
|
||
sprintf_s(_scan_file, "%s%d_LaserData_groundAdjusted.txt", dataPath[grp], fidx);
|
||
|
||
std::vector<std::vector< SVzNL3DPosition>> scanLines;
|
||
wdReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines);
|
||
|
||
if ((grp == 2) || (grp == 3)) //计算调平矩阵
|
||
{
|
||
#if 0
|
||
std::vector<cv::Point3f> validPts;
|
||
std::vector<std::vector< SVzNL3DPosition>> copy_scanLines;
|
||
copy_scanLines.resize(scanLines.size());
|
||
for (int line = 0; line < (int)scanLines.size(); line++)
|
||
{
|
||
std::vector< SVzNL3DPosition>& a_line = scanLines[line];
|
||
copy_scanLines[line].resize(a_line.size());
|
||
for (int j = 0; j < (int)a_line.size(); j++)
|
||
{
|
||
copy_scanLines[line][j] = a_line[j];
|
||
if (a_line[j].pt3D.z > 1e-4)
|
||
{
|
||
cv::Point3f a_pt = cv::Point3f((float)a_line[j].pt3D.x, (float)a_line[j].pt3D.y, (float)a_line[j].pt3D.z);
|
||
validPts.push_back(a_pt);
|
||
}
|
||
}
|
||
}
|
||
std::vector<cv::Point3f> out_inliers;
|
||
Plane res = ransacFitPlane(validPts, out_inliers);
|
||
if (res.C < 0)
|
||
{
|
||
res.A = -res.A;
|
||
res.B = -res.B;
|
||
res.C = -res.C;
|
||
res.D = -res.D;
|
||
}
|
||
float meanH = 0;
|
||
int counter = 0;
|
||
for (int i = 0; i < (int)out_inliers.size(); i++)
|
||
{
|
||
meanH += out_inliers[i].z;
|
||
counter++;
|
||
}
|
||
//计算投影向量
|
||
SVzNL3DPoint vec_1 = { res.A, res.B, res.C };
|
||
SVzNL3DPoint vec_2 = { 0, 0, 1.0 };
|
||
SSG_planeCalibPara calibPara = wd_computeRTMatrix(vec_1, vec_2);
|
||
for (int m = 0; m < 9; m++)
|
||
{
|
||
poseCalibPara.planeCalib[m] = calibPara.planeCalib[m];
|
||
poseCalibPara.invRMatrix[m] = calibPara.invRMatrix[m];
|
||
}
|
||
poseCalibPara.planeHeight = meanH / counter;
|
||
|
||
char _out_file[256];
|
||
sprintf_s(_out_file, "%s%d_calib_para.txt", dataPath[grp], fidx);
|
||
_outputCalibPara(_out_file, poseCalibPara);
|
||
|
||
sprintf_s(_out_file, "%s%d_LaserData_groundAdjusted.txt", dataPath[grp], fidx);
|
||
//if (false == fileExists(_out_file))
|
||
{
|
||
//输出调平效果
|
||
int firstValidLine = -1;
|
||
int lastValidLine = -1;
|
||
for (int line = 0; line < (int)copy_scanLines.size(); line++)
|
||
{
|
||
//行处理
|
||
//调平,去除地面
|
||
double cuttingZ = poseCalibPara.planeHeight - 100;
|
||
sx_rodPosition_lineDataR(copy_scanLines[line], poseCalibPara.planeCalib, cuttingZ);
|
||
int ptsNum = counterValidPts(copy_scanLines[line]);
|
||
if (ptsNum > 10)
|
||
{
|
||
if (firstValidLine < 0)
|
||
firstValidLine = line;
|
||
lastValidLine = line;
|
||
}
|
||
}
|
||
if ((lastValidLine > 0) && (lastValidLine < copy_scanLines.size() - 1))
|
||
{
|
||
copy_scanLines.erase(copy_scanLines.begin() + lastValidLine + 1, copy_scanLines.end());
|
||
}
|
||
if(firstValidLine > 1)
|
||
{
|
||
copy_scanLines.erase(copy_scanLines.begin(), copy_scanLines.begin() + firstValidLine - 1);
|
||
}
|
||
_outputScanDataFile(_out_file, copy_scanLines, 0.0f, 0, 0);
|
||
}
|
||
#endif
|
||
}
|
||
|
||
long t1 = (long)GetTickCount64();//统计时间
|
||
|
||
SSX_rodParam rodParam;
|
||
rodParam.diameter = 16.0; //钢筋直径
|
||
rodParam.len = 50;
|
||
|
||
SSG_cornerParam cornerParam;
|
||
cornerParam.cornerTh = 60; //45度角
|
||
cornerParam.scale = rodParam.diameter / 4; // algoParam.bagParam.bagH / 8; // 15; // algoParam.bagParam.bagH / 8;
|
||
cornerParam.minEndingGap = 20; // algoParam.bagParam.bagW / 4;
|
||
cornerParam.minEndingGap_z = 5.0;
|
||
cornerParam.jumpCornerTh_1 = 15; //水平角度,小于此角度视为水平
|
||
cornerParam.jumpCornerTh_2 = 60;
|
||
|
||
SSG_outlierFilterParam filterParam;
|
||
filterParam.continuityTh = 4.0; //噪声滤除。当相邻点的z跳变大于此门限时,检查是否为噪声。若长度小于outlierLen, 视为噪声
|
||
filterParam.outlierTh = 4;
|
||
|
||
SSG_treeGrowParam growParam;
|
||
growParam.maxLineSkipNum = 5;
|
||
growParam.yDeviation_max = 5.0;
|
||
growParam.maxSkipDistance = 20.0;
|
||
growParam.zDeviation_max = 5.0;//
|
||
growParam.minLTypeTreeLen = 50; //mm, 螺杆长度
|
||
growParam.minVTypeTreeLen = 50; //mm
|
||
|
||
bool isHorizonScan = true; //true:激光线平行槽道;false:激光线垂直槽道
|
||
SVzNLRangeD weldSeamRange;//焊缝距钢筋交叉点的范围
|
||
if ((grp == 0) || (grp == 1))
|
||
{
|
||
weldSeamRange.min = rodParam.diameter / 2;
|
||
weldSeamRange.max = 100;
|
||
}
|
||
else
|
||
{
|
||
weldSeamRange.min = 0;
|
||
weldSeamRange.max = 80;
|
||
}
|
||
|
||
EWD_weldingCategory weldCategory;
|
||
if ((grp == 0) || (grp == 1))
|
||
weldCategory = KeWD_WELD_CATEGPRY_I;
|
||
else
|
||
weldCategory = KeWD_WELD_CATEGPRY_II;
|
||
|
||
int errCode = 0;
|
||
std::vector<SSX_weldSeamInfo> weldSeamInfo;
|
||
sx_rebarWeldSeamPositioning(
|
||
scanLines,
|
||
poseCalibPara,
|
||
cornerParam,
|
||
filterParam,
|
||
growParam,
|
||
rodParam,
|
||
weldSeamRange,
|
||
weldCategory,
|
||
weldSeamInfo,
|
||
&errCode);
|
||
long t2 = (long)GetTickCount64();
|
||
printf("%s: %d(ms)!\n", _scan_file, (int)(t2 - t1));
|
||
if (errCode == 0)
|
||
{
|
||
//输出测试结果
|
||
sprintf_s(_scan_file, "%sresult\\%d_result.txt", dataPath[grp], fidx);
|
||
_outputRGBDScan_RGBD_weldSeam(_scan_file, scanLines, weldSeamInfo);
|
||
sprintf_s(_scan_file, "%sresult\\%d_screw_info.txt", dataPath[grp], fidx);
|
||
_outputWeldSeamInfo(_scan_file, weldSeamInfo);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
typedef enum
|
||
{
|
||
keSG_测试_配天螺杆定位 = 0,
|
||
keSG_测试_配天定位盘定位,
|
||
keSG_测试_配天新定位盘定位,
|
||
keSG_测试_矩森棒材抓取,
|
||
keSG_测试_筑裕钢筋焊缝定位,
|
||
} ESG_testMode;
|
||
|
||
int main()
|
||
{
|
||
//ESG_testMode testMode = keSG_测试_配天螺杆定位;
|
||
//ESG_testMode testMode = keSG_测试_配天定位盘定位;
|
||
//ESG_testMode testMode = keSG_测试_配天新定位盘定位;
|
||
ESG_testMode testMode = keSG_测试_矩森棒材抓取;
|
||
//ESG_testMode testMode = keSG_测试_筑裕钢筋焊缝定位;
|
||
|
||
if(keSG_测试_配天螺杆定位 == testMode)
|
||
screwTest();
|
||
else if(keSG_测试_配天定位盘定位 == testMode)
|
||
locatingPlateTest();
|
||
else if (keSG_测试_配天新定位盘定位 == testMode)
|
||
newLocatingPlateTest();
|
||
else if(keSG_测试_矩森棒材抓取 == testMode)
|
||
rodPositionTest();
|
||
else if(keSG_测试_筑裕钢筋焊缝定位 == testMode)
|
||
rodWeldSeamPosition_test();
|
||
|
||
return 0;
|
||
}
|
||
|
||
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
|
||
// 调试程序: F5 或调试 >“开始调试”菜单
|
||
|
||
// 入门使用技巧:
|
||
// 1. 使用解决方案资源管理器窗口添加/管理文件
|
||
// 2. 使用团队资源管理器窗口连接到源代码管理
|
||
// 3. 使用输出窗口查看生成输出和其他消息
|
||
// 4. 使用错误列表窗口查看错误
|
||
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
|
||
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
|