algoLib/gasFillingPortPosition_test/gasFillingPortPosition_test.cpp

404 lines
11 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// gasFillingPortPosition_test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <fstream>
#include <vector>
#include <stdio.h>
#include <VZNL_Types.h>
#include "direct.h"
#include <string>
#include "gasFillingPortPosition_Export.h"
#include <opencv2/opencv.hpp>
#include <Windows.h>
#include <limits>
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;
void vzReadLaserScanPointFromFile_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 vzReadPlyTxtPointFromFile_XYZRGB_vector(const char* fileName, std::vector<std::vector< SVzNLPointXYZRGBA>>& scanData)
{
std::ifstream inputFile(fileName);
std::string linedata;
if (inputFile.is_open() == false)
return;
const double lineYGap = 50;
std::vector< SVzNLPointXYZRGBA> a_line;
double pre_y = FLT_MIN;
while (getline(inputFile, linedata))
{
SVzNLPointXYZRGBA a_pt;
memset(&a_pt, 0, sizeof(SVzNLPointXYZRGBA));
double _x, _y, _z;
sscanf_s(linedata.c_str(), "%lf %lf %lf", &_x, &_y, &_z);
a_pt.x = (float)_x;
a_pt.y = (float)_y;
a_pt.z = (float)_z;
if (a_pt.y < pre_y - lineYGap) //新的扫描行
{
if (a_line.size() > 0)
{
scanData.push_back(a_line);
a_line.clear();
}
}
pre_y = a_pt.y;
a_line.push_back(a_pt);
}
if (a_line.size() > 0)
scanData.push_back(a_line);
inputFile.close();
return;
}
void _outputScanDataFile_XYZRGB(char* fileName, std::vector<std::vector< SVzNLPointXYZRGBA>>& 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++)
{
SVzNLPointXYZRGBA& pt3D = scanData[line][i];
float x = (float)pt3D.x;
float y = (float)pt3D.y;
float z = (float)pt3D.z;
sw << "{ " << x << "," << y << "," << z << " }-";
sw << "{0,0}-{0,0}" << std::endl;
}
}
sw.close();
}
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 _outputFillingPortInfo(char* fileName, SSG_6DOF centerPose)
{
std::ofstream sw(fileName);
char dataStr[250];
sw << "A:" << std::endl;
sprintf_s(dataStr, 250, "中心点: (%g, %g, %g)", centerPose.x, centerPose.y, centerPose.z);
sw << dataStr << std::endl;
sprintf_s(dataStr, 250, "法向量: (%g, %g, %g)", centerPose.x_roll, centerPose.y_pitch, centerPose.z_yaw);
sw << dataStr << std::endl;
sw.close();
}
void _outputRGBDScan_fillingPort_RGBD(
char* fileName,
std::vector<std::vector<SVzNL3DPosition>>& scanLines,
SSG_6DOF centerPose)
{
int lineNum = (int)scanLines.size();
std::ofstream sw(fileName);
int realLines = lineNum;
if (centerPose.z > 1e-4)
realLines++;
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 = { 255, 97, 0 };
size = 3;
}
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 (centerPose.z > 1e-4)
{
std::vector<SVzNL3DPoint> ptBuffer;
SVzNL3DPoint cpt = { centerPose.x, centerPose.y, centerPose.z };
ptBuffer.push_back(cpt);
int linePtNum = (int)ptBuffer.size();
sw << "Line_" << lineNum << "_0_" << linePtNum + 1 << std::endl;
lineNum++;
rgb = { 255, 0, 0 };
size = 15;
for (int j = 0; j < linePtNum; j++)
{
float x = (float)ptBuffer[j].x;
float y = (float)ptBuffer[j].y;
float z = (float)ptBuffer[j].z;
sw << "{" << x << "," << y << "," << z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
}
//加一个点用于跳过显示工具bug
float x = (float)ptBuffer[0].x;
float y = (float)ptBuffer[0].y;
float z = (float)ptBuffer[0].z;
sw << "{" << x << "," << y << "," << z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
size = 1;
double len = 60;
SVzNL3DPoint pt0 = { cpt.x + len * centerPose.x_roll,
cpt.y + len * centerPose.y_pitch,
cpt.z + len * centerPose.z_yaw };
SVzNL3DPoint pt1 = { cpt.x - len * centerPose.x_roll,
cpt.y - len * centerPose.y_pitch,
cpt.z - len * centerPose.z_yaw };
//显示法向量
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();
}
#define TEST_CONVERT_TO_GRID 1
#define TEST_COMPUTE_POSE 0
#define TEST_GROUP 2
int main()
{
const char* dataPath[TEST_GROUP] = {
"F:/ShangGu/项目/冠钦_LNG自动加气/加气口测试数据/", //0
"F:/ShangGu/项目/冠钦项目/圆环自动抓取/",
};
SVzNLRange fileIdx[TEST_GROUP] = {
{2,30},
};
const char* ver = wd_gasFillingPortPositionVersion();
printf("ver:%s\n", ver);
#if TEST_CONVERT_TO_GRID
for (int grp = 0; grp < TEST_GROUP; grp++)
{
for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++)
{
//fidx =7;
char _scan_file[256];
spr
LaserData_1
vzReadPlyTxtPointFromFile_XYZRGB_vector(const char* fileName, std::vector<std::vector< SVzNLPointXYZRGBA>>&scanData);
#endif
#if TEST_COMPUTE_POSE
for (int grp = 0; grp < TEST_GROUP; grp++)
{
for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++)
{
//fidx =7;
char _scan_file[256];
sprintf_s(_scan_file, "%s%d_LaserData_Hi229156.txt", dataPath[grp], fidx);
std::vector<std::vector< SVzNL3DPosition>> scanLines;
vzReadLaserScanPointFromFile_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_gasFillingPortPara gasFillingPortPara;
gasFillingPortPara.innerD = 42.0;
gasFillingPortPara.outerD = 52.0;
SSG_lineSegParam lineSegPara;
lineSegPara.maxDist = 1.0;
lineSegPara.segGapTh_y = 5.0; //y方向间隔大于5mm认为是分段
lineSegPara.segGapTh_z = 10.0; //z方向间隔大于10mm认为是分段
SSG_outlierFilterParam filterParam;
filterParam.continuityTh = 20.0; //噪声滤除。当相邻点的z跳变大于此门限时检查是否为噪声。若长度小于outlierLen 视为噪声
filterParam.outlierTh = 5;
SSG_treeGrowParam growParam;
growParam.maxLineSkipNum = 10;
growParam.yDeviation_max = 5.0;
growParam.maxSkipDistance = 5.0;
growParam.zDeviation_max = 2.0;//
growParam.minLTypeTreeLen = 100; //mm
growParam.minVTypeTreeLen = 100; //mm
int errCode = 0;
SSG_6DOF centerPose = wd_getGasFillingPortPosition(
scanLines,
gasFillingPortPara,
lineSegPara,
filterParam,
growParam,
&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_fillingPort_RGBD(_scan_file, scanLines, centerPose);
sprintf_s(_scan_file, "%sresult\\%d_fillingPort_info.txt", dataPath[grp], fidx);
_outputFillingPortInfo(_scan_file, centerPose);
}
}
#endif
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 入门使用技巧:
// 1. 使用解决方案资源管理器窗口添加/管理文件
// 2. 使用团队资源管理器窗口连接到源代码管理
// 3. 使用输出窗口查看生成输出和其他消息
// 4. 使用错误列表窗口查看错误
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件