algoLib/bagPositioning_test/bagPositioning_test.cpp
2025-06-08 11:03:52 +08:00

1940 lines
57 KiB
C++
Raw 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.

// bagPositioning_test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <fstream>
#include <vector>
#include <stdio.h>
#include <VZNL_Types.h>
#include "direct.h"
#include <string>
#include "SG_bagPositioning_Export.h"
#include <opencv2/opencv.hpp>
#include <Windows.h>
SVzNL3DPoint _ptRotate(SVzNL3DPoint pt3D, double matrix3d[9])
{
SVzNL3DPoint _r_pt;
_r_pt.x = pt3D.x * matrix3d[0] + pt3D.y * matrix3d[1] + pt3D.z * matrix3d[2];
_r_pt.y = pt3D.x * matrix3d[3] + pt3D.y * matrix3d[4] + pt3D.z * matrix3d[5];
_r_pt.z = pt3D.x * matrix3d[6] + pt3D.y * matrix3d[7] + pt3D.z * matrix3d[8];
return _r_pt;
}
#define DATA_VER_OLD 0
#define DATA_VER_NEW 1
#define DATA_VER_FROM_CUSTOM 2
#define VZ_LASER_LINE_PT_MAX_NUM 4096
SVzNLXYZRGBDLaserLine* vzReadLaserScanPointFromFile_XYZRGB(const char* fileName, int* scanLineNum, float* scanV,
int* dataCalib, int* scanMaxStamp, int* canClockUnit)
{
std::ifstream inputFile(fileName);
std::string linedata;
if (inputFile.is_open() == false)
return NULL;
SVzNLXYZRGBDLaserLine* _scanLines = NULL;
int lines = 0;
int dataElements = 4;
int firstIndex = -1;
int dataFileVer = DATA_VER_OLD;
std::getline(inputFile, linedata); //第一行
int lineNum = 0;
if (0 == strncmp("LineNum:", linedata.c_str(), 8))
{
dataFileVer = DATA_VER_NEW;
sscanf_s(linedata.c_str(), "LineNum:%d", &lines);
if (lines == 0)
return NULL;
lineNum = lines;
_scanLines = (SVzNLXYZRGBDLaserLine*)malloc(sizeof(SVzNLXYZRGBDLaserLine) * (lineNum + 1));
memset(_scanLines, 0, sizeof(SVzNLXYZRGBDLaserLine) * (lineNum + 1));
if (scanLineNum)
*scanLineNum = lines;
}
else if (0 == strncmp("LineNum_", linedata.c_str(), 8))
{
dataFileVer = DATA_VER_OLD;
sscanf_s(linedata.c_str(), "LineNum_%d", &lines);
if (lines == 0)
return NULL;
lineNum = lines;
_scanLines = (SVzNLXYZRGBDLaserLine*)malloc(sizeof(SVzNLXYZRGBDLaserLine) * (lineNum + 1));
memset(_scanLines, 0, sizeof(SVzNLXYZRGBDLaserLine) * (lineNum + 1));
if (scanLineNum)
*scanLineNum = lines;
}
if (_scanLines == NULL)
return NULL;
int ptNum = 0;
int lineIdx = -1;
int ptIdx = 0;
SVzNLPointXYZRGBA* p3DPoint = NULL;
if (dataFileVer == DATA_VER_NEW)
{
while (getline(inputFile, linedata))
{
if (0 == strncmp("ScanSpeed:", linedata.c_str(), 10))
{
double lineV = 0;
sscanf_s(linedata.c_str(), "ScanSpeed:%lf", &lineV);
if (scanV)
*scanV = (float)lineV;
}
else if (0 == strncmp("PointAdjust:", linedata.c_str(), 12))
{
int ptAdjusted = 0;
sscanf_s(linedata.c_str(), "PointAdjust:%d", &ptAdjusted);
if (dataCalib)
*dataCalib = ptAdjusted;
}
else if (0 == strncmp("MaxTimeStamp:", linedata.c_str(), 13))
{
unsigned int maxTimeStamp = 0;
unsigned int timePerStamp = 0;
sscanf_s(linedata.c_str(), "MaxTimeStamp:%u_%u", &maxTimeStamp, &timePerStamp);
if (scanMaxStamp)
*scanMaxStamp = maxTimeStamp;
if (canClockUnit)
*canClockUnit = timePerStamp;
}
else if (0 == strncmp("Line_", linedata.c_str(), 5))
{
int lineIndex;
unsigned int timeStamp;
sscanf_s(linedata.c_str(), "Line_%d_%u_%d", &lineIndex, &timeStamp, &ptNum);
if (firstIndex < 0)
firstIndex = lineIndex;
lineIndex = lineIndex - firstIndex;
if ((lineIndex < 0) || (lineIndex >= lines))
break;
//new Line
lineIdx++;
if (ptNum > 0)
{
p3DPoint = (SVzNLPointXYZRGBA*)malloc(sizeof(SVzNLPointXYZRGBA) * ptNum);
memset(p3DPoint, 0, sizeof(SVzNLPointXYZRGBA) * ptNum);
}
else
p3DPoint = NULL;
_scanLines[lineIdx].nPointCnt = 0;
_scanLines[lineIdx].nTimeStamp = timeStamp;
_scanLines[lineIdx].p3DPoint = p3DPoint;
}
else if (0 == strncmp("{", linedata.c_str(), 1))
{
float X, Y, Z;
int imageY = 0;
float leftX, leftY;
float rightX, rightY;
int r = -1, g = -1, b = -1;
sscanf_s(linedata.c_str(), "{%f,%f,%f,%f,%f,%f }-{%f,%f}-{%f,%f}", &X, &Y, &Z, &r, &g, &b, &leftX, &leftY, &rightX, &rightY);
int id = _scanLines[lineIdx].nPointCnt;
if (id < ptNum)
{
p3DPoint[id].x = X;
p3DPoint[id].y = Y;
p3DPoint[id].z = Z;
p3DPoint[id].nRGB = 0;
_scanLines[lineIdx].nPointCnt = id + 1;
}
}
}
}
else if (dataFileVer == DATA_VER_OLD)
{
while (getline(inputFile, linedata))
{
if (0 == strncmp("DataElements_", linedata.c_str(), 13))
{
sscanf_s(linedata.c_str(), "DataElements_%d", &dataElements);
if ((dataElements != 3) && (dataElements != 4))
break;
}
if (0 == strncmp("LineV_", linedata.c_str(), 6))
{
double lineV = 0;
sscanf_s(linedata.c_str(), "LineV_%lf", &lineV);
}
else if (0 == strncmp("Line_", linedata.c_str(), 5))
{
int lineIndex;
unsigned int timeStamp;
sscanf_s(linedata.c_str(), "Line_%d_%u", &lineIndex, &timeStamp);
#if 0
if (scanLineListTail == NULL)
firstIndex = lineIndex;
#endif
lineIndex = lineIndex - firstIndex;
if ((lineIndex < 0) || (lineIndex >= lines))
break;
//new Line
//new Line
lineIdx++;
p3DPoint = (SVzNLPointXYZRGBA*)malloc(sizeof(SVzNLPointXYZRGBA) * VZ_LASER_LINE_PT_MAX_NUM);
memset(p3DPoint, 0, sizeof(SVzNLPointXYZRGBA) * VZ_LASER_LINE_PT_MAX_NUM);
_scanLines[lineIdx].nPointCnt = 0;
_scanLines[lineIdx].nTimeStamp = timeStamp;
_scanLines[lineIdx].p3DPoint = p3DPoint;
}
else if (0 == strncmp("(", linedata.c_str(), 1))
{
float X, Y, Z;
int imageY = 0;
if (dataElements == 4)
sscanf_s(linedata.c_str(), "(%f,%f,%f,%d)", &X, &Y, &Z, &imageY);
else
sscanf_s(linedata.c_str(), "(%f,%f,%f)", &X, &Y, &Z);
int id = _scanLines[lineIdx].nPointCnt;
if (id < VZ_LASER_LINE_PT_MAX_NUM)
{
p3DPoint[id].x = X;
p3DPoint[id].y = Y;
p3DPoint[id].z = Z;
p3DPoint[id].nRGB = 0;
_scanLines[lineIdx].nPointCnt = id + 1;
}
}
}
}
inputFile.close();
return _scanLines;
}
SVzNL3DLaserLine* vzReadLaserScanPointFromFile_XYZ(const char* fileName, int* scanLineNum, float* scanV,
int* dataCalib, int* scanMaxStamp, int* canClockUnit)
{
std::ifstream inputFile(fileName);
std::string linedata;
if (inputFile.is_open() == false)
return NULL;
SVzNL3DLaserLine* _scanLines = NULL;
int lines = 0;
int dataElements = 4;
int firstIndex = -1;
int dataFileVer = DATA_VER_OLD;
std::getline(inputFile, linedata); //第一行
int lineNum = 0;
if (0 == strncmp("LineNum:", linedata.c_str(), 8))
{
dataFileVer = DATA_VER_NEW;
sscanf_s(linedata.c_str(), "LineNum:%d", &lines);
if (lines == 0)
return NULL;
lineNum = lines;
_scanLines = (SVzNL3DLaserLine*)malloc(sizeof(SVzNL3DLaserLine) * (lineNum + 1));
memset(_scanLines, 0, sizeof(SVzNL3DLaserLine) * (lineNum + 1));
if (scanLineNum)
*scanLineNum = lines;
}
else if (0 == strncmp("LineNum_", linedata.c_str(), 8))
{
dataFileVer = DATA_VER_OLD;
sscanf_s(linedata.c_str(), "LineNum_%d", &lines);
if (lines == 0)
return NULL;
lineNum = lines;
_scanLines = (SVzNL3DLaserLine*)malloc(sizeof(SVzNL3DLaserLine) * (lineNum + 1));
memset(_scanLines, 0, sizeof(SVzNL3DLaserLine) * (lineNum + 1));
if (scanLineNum)
*scanLineNum = lines;
}
if (_scanLines == NULL)
return NULL;
int ptNum = 0;
int lineIdx = -1;
int ptIdx = 0;
SVzNL3DPosition* p3DPoint = NULL;
if (dataFileVer == DATA_VER_NEW)
{
while (getline(inputFile, linedata))
{
if (0 == strncmp("ScanSpeed:", linedata.c_str(), 10))
{
double lineV = 0;
sscanf_s(linedata.c_str(), "ScanSpeed:%lf", &lineV);
if (scanV)
*scanV = (float)lineV;
}
else if (0 == strncmp("PointAdjust:", linedata.c_str(), 12))
{
int ptAdjusted = 0;
sscanf_s(linedata.c_str(), "PointAdjust:%d", &ptAdjusted);
if (dataCalib)
*dataCalib = ptAdjusted;
}
else if (0 == strncmp("MaxTimeStamp:", linedata.c_str(), 13))
{
unsigned int maxTimeStamp = 0;
unsigned int timePerStamp = 0;
sscanf_s(linedata.c_str(), "MaxTimeStamp:%u_%u", &maxTimeStamp, &timePerStamp);
if (scanMaxStamp)
*scanMaxStamp = maxTimeStamp;
if (canClockUnit)
*canClockUnit = timePerStamp;
}
else if (0 == strncmp("Line_", linedata.c_str(), 5))
{
int lineIndex;
unsigned int timeStamp;
sscanf_s(linedata.c_str(), "Line_%d_%u_%d", &lineIndex, &timeStamp, &ptNum);
if (firstIndex < 0)
firstIndex = lineIndex;
lineIndex = lineIndex - firstIndex;
if ((lineIndex < 0) || (lineIndex >= lines))
break;
//new Line
lineIdx++;
if (ptNum > 0)
{
p3DPoint = (SVzNL3DPosition*)malloc(sizeof(SVzNL3DPosition) * ptNum);
memset(p3DPoint, 0, sizeof(SVzNL3DPosition) * ptNum);
}
else
p3DPoint = NULL;
_scanLines[lineIdx].nPositionCnt = 0;
_scanLines[lineIdx].nTimeStamp = timeStamp;
_scanLines[lineIdx].p3DPosition = p3DPoint;
}
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);
int id = _scanLines[lineIdx].nPositionCnt;
if (id < ptNum)
{
p3DPoint[id].pt3D.x = X;
p3DPoint[id].pt3D.y = Y;
p3DPoint[id].pt3D.z = Z;
_scanLines[lineIdx].nPositionCnt = id + 1;
}
}
}
}
else if (dataFileVer == DATA_VER_OLD)
{
while (getline(inputFile, linedata))
{
if (0 == strncmp("DataElements_", linedata.c_str(), 13))
{
sscanf_s(linedata.c_str(), "DataElements_%d", &dataElements);
if ((dataElements != 3) && (dataElements != 4))
break;
}
if (0 == strncmp("LineV_", linedata.c_str(), 6))
{
double lineV = 0;
sscanf_s(linedata.c_str(), "LineV_%lf", &lineV);
}
else if (0 == strncmp("Line_", linedata.c_str(), 5))
{
int lineIndex;
unsigned int timeStamp;
sscanf_s(linedata.c_str(), "Line_%d_%u", &lineIndex, &timeStamp);
#if 0
if (scanLineListTail == NULL)
firstIndex = lineIndex;
#endif
lineIndex = lineIndex - firstIndex;
if ((lineIndex < 0) || (lineIndex >= lines))
break;
//new Line
//new Line
lineIdx++;
p3DPoint = (SVzNL3DPosition*)malloc(sizeof(SVzNL3DPosition) * VZ_LASER_LINE_PT_MAX_NUM);
memset(p3DPoint, 0, sizeof(SVzNL3DPosition) * VZ_LASER_LINE_PT_MAX_NUM);
_scanLines[lineIdx].nPositionCnt = 0;
_scanLines[lineIdx].nTimeStamp = timeStamp;
_scanLines[lineIdx].p3DPosition = p3DPoint;
}
else if (0 == strncmp("(", linedata.c_str(), 1))
{
float X, Y, Z;
int imageY = 0;
if (dataElements == 4)
sscanf_s(linedata.c_str(), "(%f,%f,%f,%d)", &X, &Y, &Z, &imageY);
else
sscanf_s(linedata.c_str(), "(%f,%f,%f)", &X, &Y, &Z);
int id = _scanLines[lineIdx].nPositionCnt;
if (id < VZ_LASER_LINE_PT_MAX_NUM)
{
p3DPoint[id].pt3D.x = X;
p3DPoint[id].pt3D.y = Y;
p3DPoint[id].pt3D.z = Z;
_scanLines[lineIdx].nPositionCnt = id + 1;
}
}
}
}
inputFile.close();
return _scanLines;
}
SVzNL3DLaserLine* _convertToGridData_XYZRGB(SVzNLXYZRGBDLaserLine* laser3DPoints, int lineNum, double _F, double* camPoseR, int* outLineNum)
{
int min_y = 100000000;
int max_y = -10000000;
int validStartLine = -1;
int validEndLine = -1;
for (int line = 0; line < lineNum; line++)
{
if (laser3DPoints[line].nPointCnt > 0)
{
if (validStartLine < 0)
{
validStartLine = line;
validEndLine = line;
}
else
validEndLine = line;
}
for (int i = 0; i < laser3DPoints[line].nPointCnt; i++)
{
SVzNLPointXYZRGBA* a_pt = &laser3DPoints[line].p3DPoint[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 NULL;
int vldLineNum = validEndLine - validStartLine + 1;
*outLineNum = vldLineNum;
int pt_counter = max_y - min_y + 1;
SVzNL3DLaserLine* gridData = (SVzNL3DLaserLine*)malloc(sizeof(SVzNL3DLaserLine) * (vldLineNum + 1));
memset(gridData, 0, sizeof(SVzNL3DLaserLine) * (vldLineNum + 1));
for (int line = validStartLine; line <= validEndLine; line++)
{
int gridLine = line - validStartLine;
gridData[gridLine].nPositionCnt = pt_counter;
gridData[gridLine].nTimeStamp = laser3DPoints[line].nTimeStamp;
gridData[gridLine].p3DPosition = (SVzNL3DPosition*)malloc(sizeof(SVzNL3DPosition) * pt_counter);
memset(gridData[gridLine].p3DPosition, 0, sizeof(SVzNL3DPosition) * pt_counter);
for (int i = 0; i < laser3DPoints[line].nPointCnt; i++)
{
SVzNLPointXYZRGBA a_pt = laser3DPoints[line].p3DPoint[i];
if (a_pt.z > 1e-4)
{
int pt_id = a_pt.nRGB - min_y;
SVzNL3DPoint tmp_pt = { a_pt.x, a_pt.y, a_pt.z };
SVzNL3DPoint r_pt = _ptRotate(tmp_pt, camPoseR);
gridData[gridLine].p3DPosition[pt_id].pt3D.x = r_pt.x;
gridData[gridLine].p3DPosition[pt_id].pt3D.y = r_pt.y;
gridData[gridLine].p3DPosition[pt_id].pt3D.z = r_pt.z;
}
}
}
return gridData;
}
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 _outputScanDataFile_self(char* fileName, SVzNL3DLaserLine* scanData, int lineNum,
float lineV, int maxTimeStamp, int clockPerSecond)
{
std::ofstream sw(fileName);
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++)
{
sw << "Line_" << line << "_" << scanData[line].nTimeStamp << "_" << scanData[line].nPositionCnt << std::endl;
for (int i = 0; i < scanData[line].nPositionCnt; i++)
{
SVzNL3DPosition* pt3D = &scanData[line].p3DPosition[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();
}
typedef struct
{
int r;
int g;
int b;
}SG_color;
void _outputScanDataFile_RGBD_obj(char* fileName, SVzNL3DLaserLine* scanData, int lineNum,
float lineV, int maxTimeStamp, int clockPerSecond, std::vector<SSG_peakRgnInfo>& objOps)
{
std::ofstream sw(fileName);
int realLines = lineNum;
if (objOps.size() > 0)
realLines++;
sw << "LineNum:" << realLines << std::endl;
sw << "DataType: 0" << std::endl;
sw << "ScanSpeed:" << lineV << std::endl;
sw << "PointAdjust: 1" << std::endl;
sw << "MaxTimeStamp:" << maxTimeStamp << "_" << clockPerSecond << 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 nTimeStamp = 0;
for (int line = 0; line < lineNum; line++)
{
sw << "Line_" << line << "_" << scanData[line].nTimeStamp << "_" << scanData[line].nPositionCnt << std::endl;
nTimeStamp = scanData[line].nTimeStamp;
for (int i = 0; i < scanData[line].nPositionCnt; i++)
{
SVzNL3DPosition* pt3D = &scanData[line].p3DPosition[i];
int vType = pt3D->nPointIdx & 0xff;
int hType = vType >> 4;
int objId = (pt3D->nPointIdx >> 16)&0xffff;
vType = vType & 0x0f;
if(LINE_FEATURE_L_JUMP_H2L == vType)
{
rgb = { 255, 97, 0 };
size = 3;
}
else if (LINE_FEATURE_L_JUMP_L2H == vType)
{
rgb = { 255, 255, 0 };
size = 3;
}
else if (LINE_FEATURE_V_SLOPE == vType)
{
rgb = { 255, 0, 255};
size = 3;
}
else if (LINE_FEATURE_L_SLOPE_H2L == vType)
{
rgb = { 160, 82, 45 };
size = 3;
}
else if ((LINE_FEATURE_LINE_ENDING_0 == vType) || (LINE_FEATURE_LINE_ENDING_1 == vType))
{
rgb = { 255, 0, 0 };
size = 3;
}
else if (LINE_FEATURE_L_SLOPE_L2H == vType)
{
rgb = { 233, 150, 122 };
size = 3;
}
else if (LINE_FEATURE_L_JUMP_H2L == hType)
{
rgb = { 0, 0, 255 };
size = 3;
}
else if ( LINE_FEATURE_L_JUMP_L2H == hType)
{
rgb = { 0, 255, 255};
size = 3;
}
else if ( LINE_FEATURE_V_SLOPE == hType)
{
rgb = { 0, 255, 0 };
size = 3;
}
else if ( LINE_FEATURE_L_SLOPE_H2L == hType)
{
rgb = { 85, 107, 47 };
size = 3;
}
else if ( LINE_FEATURE_L_SLOPE_L2H == hType)
{
rgb = { 0, 255, 154 };
size = 3;
}
else if ( (LINE_FEATURE_LINE_ENDING_0 == hType) || (LINE_FEATURE_LINE_ENDING_1 == hType))
{
rgb = { 255, 0, 0 };
size = 3;
}
else if (objId > 0) //目标
{
rgb = objColor[objId%8];
size = 5;
}
else
{
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 (objOps.size() > 0)
{
int ptNum = objOps.size();
sw << "Line_" << lineNum << "_" << (nTimeStamp+ 1000) << "_" << ptNum << std::endl;
for (int i = 0; i < objOps.size(); i++)
{
if(i == 0)
rgb = { 255, 0, 0 };
else
rgb = { 255, 255, 0 };
size = 25;
float x = (float)objOps[i].centerPos.x;
float y = (float)objOps[i].centerPos.y;
float z = (float)objOps[i].centerPos.z;
sw << "{" << x << "," << y << "," << z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
if (i == 0)
{
sw << "{" << x << "," << y << "," << z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
}
}
}
//画出方向线
sw.close();
}
void _outputScanDataFile_RGBD_sideBagObj(char* fileName, SVzNL3DLaserLine* scanData, int lineNum,
float lineV, int maxTimeStamp, int clockPerSecond, std::vector<SSG_sideBagInfo>& objOps)
{
std::ofstream sw(fileName);
int realLines = lineNum;
if (objOps.size() > 0)
realLines++;
sw << "LineNum:" << realLines << std::endl;
sw << "DataType: 0" << std::endl;
sw << "ScanSpeed:" << lineV << std::endl;
sw << "PointAdjust: 1" << std::endl;
sw << "MaxTimeStamp:" << maxTimeStamp << "_" << clockPerSecond << 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 nTimeStamp = 0;
for (int line = 0; line < lineNum; line++)
{
int nPntCount = 0;
for (int i = 0; i < scanData[line].nPositionCnt; i++)
{
SVzNL3DPosition* pt3D = &scanData[line].p3DPosition[i];
if (pt3D->pt3D.z > 1e-4)
nPntCount++;
}
sw << "Line_" << line << "_" << scanData[line].nTimeStamp << "_" << nPntCount << std::endl;
nTimeStamp = scanData[line].nTimeStamp;
for (int i = 0; i < scanData[line].nPositionCnt; i++)
{
SVzNL3DPosition* pt3D = &scanData[line].p3DPosition[i];
if (pt3D->pt3D.z < 1e-4)
continue;
int vType = pt3D->nPointIdx & 0xff;
int hType = vType >> 4;
int objId = (pt3D->nPointIdx >> 16) & 0xffff;
vType = vType & 0x0f;
if (LINE_FEATURE_L_JUMP_H2L == vType)
{
rgb = { 255, 97, 0 };
size = 3;
}
else if (LINE_FEATURE_L_JUMP_L2H == vType)
{
rgb = { 255, 255, 0 };
size = 3;
}
else if (LINE_FEATURE_V_SLOPE == vType)
{
rgb = { 255, 0, 255 };
size = 3;
}
else if (LINE_FEATURE_L_SLOPE_H2L == vType)
{
rgb = { 160, 82, 45 };
size = 3;
}
else if ((LINE_FEATURE_LINE_ENDING_0 == vType) || (LINE_FEATURE_LINE_ENDING_1 == vType))
{
rgb = { 255, 0, 0 };
size = 3;
}
else if (LINE_FEATURE_L_SLOPE_L2H == vType)
{
rgb = { 233, 150, 122 };
size = 3;
}
else if (LINE_FEATURE_L_JUMP_H2L == hType)
{
rgb = { 0, 0, 255 };
size = 3;
}
else if (LINE_FEATURE_L_JUMP_L2H == hType)
{
rgb = { 0, 255, 255 };
size = 3;
}
else if (LINE_FEATURE_V_SLOPE == hType)
{
rgb = { 0, 255, 0 };
size = 3;
}
else if (LINE_FEATURE_L_SLOPE_H2L == hType)
{
rgb = { 85, 107, 47 };
size = 3;
}
else if (LINE_FEATURE_L_SLOPE_L2H == hType)
{
rgb = { 0, 255, 154 };
size = 3;
}
else if ((LINE_FEATURE_LINE_ENDING_0 == hType) || (LINE_FEATURE_LINE_ENDING_1 == hType))
{
rgb = { 255, 0, 0 };
size = 3;
}
else if (objId > 0) //目标
{
rgb = objColor[objId % 8];
size = 5;
}
else
{
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 (objOps.size() > 0)
{
int ptNum = objOps.size();
sw << "Line_" << lineNum << "_" << (nTimeStamp + 1000) << "_" << ptNum << std::endl;
for (int i = 0; i < objOps.size(); i++)
{
if (i == 0)
rgb = { 255, 0, 0 };
else
rgb = { 255, 255, 0 };
size = 25;
float x = (float)objOps[i].graspPos.x;
float y = (float)objOps[i].graspPos.y;
float z = (float)objOps[i].graspPos.z;
sw << "{" << x << "," << y << "," << z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
if (i == 0)
{
sw << "{" << x << "," << y << "," << z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
}
}
}
sw.close();
}
void EulerRpyToRotation1(double rpy[3], double matrix3d[9]) {
double cos0 = cos(rpy[0]*PI/180);
double sin0 = sin(rpy[0]*PI/180);
double cos1 = cos(rpy[1]*PI/180);
double sin1 = sin(rpy[1]*PI/180);
double cos2 = cos(rpy[2]*PI/180);
double sin2 = sin(rpy[2]*PI/180);
matrix3d[0] = cos2 * cos1;
matrix3d[1] = cos2 * sin1 * sin0 - sin2 * cos0;
matrix3d[2] = cos2 * sin1 * cos0 + sin2 * sin0;
matrix3d[3] = sin2 * cos1;
matrix3d[4] = sin2 * sin1 * sin0 + cos2 * cos0;
matrix3d[5] = sin2 * sin1 * cos0 - cos2 * sin0;
matrix3d[6] = -sin1;
matrix3d[7] = cos1 * sin0;
matrix3d[8] = cos1 * cos0;
return;
}
void _rotateCloudPts(SVzNL3DLaserLine* scanData, int lineNum, double matrix3d[9], std::vector<std::vector< SVzNL3DPosition>>& rotateLines, SVzNLRangeD* rx_range, SVzNLRangeD* ry_range)
{
rx_range->min = 0;
rx_range->max = -1;
ry_range->min = 0;
ry_range->max = -1;
for (int line = 0; line < lineNum; line++)
{
std::vector< SVzNL3DPosition> linePts;
for (int i = 0; i < scanData[line].nPositionCnt; i++)
{
SVzNL3DPosition* pt3D = &scanData[line].p3DPosition[i];
if (pt3D->pt3D.z < 1e-4)
continue;
SVzNL3DPosition r_pt;
r_pt.pt3D = _ptRotate(pt3D->pt3D, matrix3d);
r_pt.nPointIdx = pt3D->nPointIdx;
if (rx_range->max < rx_range->min)
{
rx_range->min = r_pt.pt3D.x;
rx_range->max = r_pt.pt3D.x;
}
else
{
if (rx_range->min > r_pt.pt3D.x)
rx_range->min = r_pt.pt3D.x;
if (rx_range->max < r_pt.pt3D.x)
rx_range->max = r_pt.pt3D.x;
}
if (ry_range->max < ry_range->min)
{
ry_range->min = r_pt.pt3D.y;
ry_range->max = r_pt.pt3D.y;
}
else
{
if (ry_range->min > r_pt.pt3D.y)
ry_range->min = r_pt.pt3D.y;
if (ry_range->max < r_pt.pt3D.y)
ry_range->max = r_pt.pt3D.y;
}
linePts.push_back(r_pt);
}
rotateLines.push_back(linePts);
}
}
void _XOYprojection(cv::Mat& img, std::vector<std::vector< SVzNL3DPosition>>& dataLines, std::vector<SSG_peakRgnInfo>& objOps,
const double x_scale, const double y_scale, const SVzNLRangeD x_range, const SVzNLRangeD y_range, bool drawDirAngle)
{
int x_skip = 16;
int y_skip = 16;
cv::Vec3b rgb = cv::Vec3b(0, 0, 0);
cv::Vec3b 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;
for (int line = 0; line < dataLines.size(); line++)
{
std::vector< SVzNL3DPosition>& a_line = dataLines[line];
for (int i = 0; i < a_line.size(); i++)
{
SVzNL3DPosition* pt3D = &a_line[i];
if (pt3D->pt3D.z < 1e-4)
continue;
int vType = pt3D->nPointIdx & 0xff;
int hType = vType >> 4;
int objId = (pt3D->nPointIdx >> 16) & 0xff;
vType = vType & 0x0f;
if (LINE_FEATURE_L_JUMP_H2L == vType)
{
rgb = { 255, 97, 0 };
size = 2;
}
else if (LINE_FEATURE_L_JUMP_L2H == vType)
{
rgb = { 255, 255, 0 };
size = 2;
}
else if (LINE_FEATURE_V_SLOPE == vType)
{
rgb = { 255, 0, 255 };
size = 2;
}
else if (LINE_FEATURE_L_SLOPE_H2L == vType)
{
rgb = { 160, 82, 45 };
size = 2;
}
else if ((LINE_FEATURE_LINE_ENDING_0 == vType) || (LINE_FEATURE_LINE_ENDING_1 == vType))
{
rgb = { 255, 0, 0 };
size = 2;
}
else if (LINE_FEATURE_L_SLOPE_L2H == vType)
{
rgb = { 233, 150, 122 };
size = 2;
}
else if (LINE_FEATURE_L_JUMP_H2L == hType)
{
rgb = { 0, 0, 255 };
size = 2;
}
else if (LINE_FEATURE_L_JUMP_L2H == hType)
{
rgb = { 0, 255, 255 };
size = 2;
}
else if (LINE_FEATURE_V_SLOPE == hType)
{
rgb = { 0, 255, 0 };
size = 2;
}
else if (LINE_FEATURE_L_SLOPE_H2L == hType)
{
rgb = { 85, 107, 47 };
size = 2;
}
else if (LINE_FEATURE_L_SLOPE_L2H == hType)
{
rgb = { 0, 255, 154 };
size = 2;
}
else if ((LINE_FEATURE_LINE_ENDING_0 == hType) || (LINE_FEATURE_LINE_ENDING_1 == hType))
{
rgb = { 255, 0, 0 };
size = 2;
}
else if (objId > 0) //目标
{
rgb = objColor[objId % 8];
size = 1;
}
else
{
rgb = { 60, 60, 60 };
size = 1;
}
double x = pt3D->pt3D.x;
double y = pt3D->pt3D.y;
int px = (int)((x - x_range.min) / x_scale + x_skip);
int py = (int)((y - y_range.min) / y_scale + y_skip);
if (size == 1)
img.at<cv::Vec3b>(py, px) = cv::Vec3b(rgb[2], rgb[1], rgb[0]);
else
cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), -1);
}
}
if (objOps.size() > 0)
{
for (int i = 0; i < objOps.size(); i++)
{
if (i == 0)
{
rgb = { 255, 0, 0 };
size = 20;
}
else
{
rgb = { 255, 255, 0 };
size = 10;
}
int px = (int)((objOps[i].centerPos.x - x_range.min) / x_scale + x_skip);
int py = (int)((objOps[i].centerPos.y - y_range.min) / y_scale + y_skip);
cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), -1);
if (true == drawDirAngle)
{
//画线
double R = 100;
const double deg2rad = PI / 180.0;
const double yaw = objOps[i].centerPos.z_yaw * deg2rad;
double cy = cos(yaw); double sy = sin(yaw);
double x1 = objOps[i].centerPos.x + R * cy; double y1 = objOps[i].centerPos.y - R * sy;
double x2 = objOps[i].centerPos.x - R * cy; double y2 = objOps[i].centerPos.y + R * sy;
int px1 = (int)((x1 - x_range.min) / x_scale + x_skip);
int py1 = (int)((y1 - y_range.min) / y_scale + y_skip);
int px2 = (int)((x2 - x_range.min) / x_scale + x_skip);
int py2 = (int)((y2 - y_range.min) / y_scale + y_skip);
cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 2);
}
}
}
}
void _XOYprojection_sideBagInfo(cv::Mat& img, std::vector<std::vector< SVzNL3DPosition>>& dataLines, std::vector<SSG_sideBagInfo>& objOps,
const double x_scale, const double y_scale, const SVzNLRangeD x_range, const SVzNLRangeD y_range)
{
int x_skip = 16;
int y_skip = 16;
cv::Vec3b rgb = cv::Vec3b(0, 0, 0);
cv::Vec3b 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;
for (int line = 0; line < dataLines.size(); line++)
{
std::vector< SVzNL3DPosition>& a_line = dataLines[line];
for (int i = 0; i < a_line.size(); i++)
{
SVzNL3DPosition* pt3D = &a_line[i];
if (pt3D->pt3D.z < 1e-4)
continue;
int vType = pt3D->nPointIdx & 0xff;
int hType = vType >> 4;
int objId = (pt3D->nPointIdx >> 16) & 0xffff;
vType = vType & 0x0f;
if (LINE_FEATURE_L_JUMP_H2L == vType)
{
rgb = { 255, 97, 0 };
size = 2;
}
else if (LINE_FEATURE_L_JUMP_L2H == vType)
{
rgb = { 255, 255, 0 };
size = 2;
}
else if (LINE_FEATURE_V_SLOPE == vType)
{
rgb = { 255, 0, 255 };
size = 2;
}
else if (LINE_FEATURE_L_SLOPE_H2L == vType)
{
rgb = { 160, 82, 45 };
size = 2;
}
else if ((LINE_FEATURE_LINE_ENDING_0 == vType) || (LINE_FEATURE_LINE_ENDING_1 == vType))
{
rgb = { 255, 0, 0 };
size = 2;
}
else if (LINE_FEATURE_L_SLOPE_L2H == vType)
{
rgb = { 233, 150, 122 };
size = 2;
}
else if (LINE_FEATURE_L_JUMP_H2L == hType)
{
rgb = { 0, 0, 255 };
size = 2;
}
else if (LINE_FEATURE_L_JUMP_L2H == hType)
{
rgb = { 0, 255, 255 };
size = 2;
}
else if (LINE_FEATURE_V_SLOPE == hType)
{
rgb = { 0, 255, 0 };
size = 2;
}
else if (LINE_FEATURE_L_SLOPE_H2L == hType)
{
rgb = { 85, 107, 47 };
size = 2;
}
else if (LINE_FEATURE_L_SLOPE_L2H == hType)
{
rgb = { 0, 255, 154 };
size = 2;
}
else if ((LINE_FEATURE_LINE_ENDING_0 == hType) || (LINE_FEATURE_LINE_ENDING_1 == hType))
{
rgb = { 255, 0, 0 };
size = 2;
}
else if ( (objId > 0) &&( objId< 1000)) //目标
{
rgb = objColor[objId % 8];
size = 3;
}
else
{
rgb = { 150, 150, 150 };
size = 1;
}
double x = pt3D->pt3D.x;
double y = pt3D->pt3D.y;
int px = (int)((x - x_range.min) / x_scale + x_skip);
int py = (int)((y - y_range.min) / y_scale + y_skip);
if (size == 1)
img.at<cv::Vec3b>(py, px) = cv::Vec3b(rgb[2], rgb[1], rgb[0]);
else
cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), -1);
}
}
if (objOps.size() > 0)
{
for (int i = 0; i < objOps.size(); i++)
{
if (i == 0)
{
rgb = { 255, 0, 0 };
size = 20;
}
else
{
rgb = { 255, 255, 0 };
size = 10;
}
int px = (int)((objOps[i].graspPos.x - x_range.min) / x_scale + x_skip);
int py = (int)((objOps[i].graspPos.y - y_range.min) / y_scale + y_skip);
cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), -1);
//画ROI
size = 3;
cv::Point2d vec2d[4];
vec2d[0].x = objOps[i].objROI.left; vec2d[0].y = objOps[i].objROI.top;
vec2d[1].x = objOps[i].objROI.right; vec2d[1].y = objOps[i].objROI.top;
vec2d[2].x = objOps[i].objROI.right; vec2d[2].y = objOps[i].objROI.bottom;
vec2d[3].x = objOps[i].objROI.left; vec2d[3].y = objOps[i].objROI.bottom;
cv::Point vec[4];
for (int j = 0; j < 4; j++)
{
vec[j].x = (int)((vec2d[j].x - x_range.min) / x_scale + x_skip);
vec[j].y = (int)((vec2d[j].y - y_range.min) / y_scale + y_skip);
}
for (int j = 0; j < 4; j++)
{
int nxtIdx = (j + 1) % 4;
cv::line(img, vec[j], vec[nxtIdx], cv::Scalar(rgb[2], rgb[1], rgb[0]), size);
}
//画倾角
double r = 50;
double angle = objOps[i].graspPos.z_yaw;
angle = -angle * PI / 180;
cv::Point2d line_pt[2];
line_pt[0].x = (int)(r * cos(angle) + px);
line_pt[0].y = (int)(-r * sin(angle) + py);
line_pt[1].x = (int)(-r * cos(angle) + px);
line_pt[1].y = (int)(r * sin(angle) + py);
cv::line(img, line_pt[0], line_pt[1], cv::Scalar(rgb[2], rgb[1], rgb[0]), size);
}
}
}
void _genXOYProjectionImage(cv::String& fileName, SVzNL3DLaserLine* scanData, int lineNum, std::vector<SSG_peakRgnInfo>& objOps, double rpy[3])
{
//统计X和Y的范围
std::vector<std::vector< SVzNL3DPosition>> scan_lines;
SVzNLRangeD x_range = {0, -1};
SVzNLRangeD y_range = {0, -1};
for (int line = 0; line < lineNum; line++)
{
std::vector< SVzNL3DPosition> a_line;
for (int i = 0; i < scanData[line].nPositionCnt; i++)
{
SVzNL3DPosition* pt3D = &scanData[line].p3DPosition[i];
if (pt3D->pt3D.z < 1e-4)
continue;
a_line.push_back(*pt3D);
if (x_range.max < x_range.min)
{
x_range.min = pt3D->pt3D.x;
x_range.max = pt3D->pt3D.x;
}
else
{
if(x_range.min > pt3D->pt3D.x)
x_range.min = pt3D->pt3D.x;
if(x_range.max < pt3D->pt3D.x)
x_range.max = pt3D->pt3D.x;
}
if (y_range.max < y_range.min)
{
y_range.min = pt3D->pt3D.y;
y_range.max = pt3D->pt3D.y;
}
else
{
if (y_range.min > pt3D->pt3D.y)
y_range.min = pt3D->pt3D.y;
if (y_range.max < pt3D->pt3D.y)
y_range.max = pt3D->pt3D.y;
}
}
scan_lines.push_back(a_line);
}
int imgRows = 992;
int imgCols = 1056;
double y_rows = 960.0;
double x_cols = 1024.0;
cv::Mat img = cv::Mat::zeros(imgRows, imgCols, CV_8UC3);
//计算投影比例
double x_scale = (x_range.max - x_range.min) / x_cols;
double y_scale = (y_range.max - y_range.min) / y_rows;
_XOYprojection(img, scan_lines, objOps, x_scale, y_scale, x_range, y_range, true);
//旋转视角显示
double matrix3d[9];
EulerRpyToRotation1(rpy, matrix3d);
std::vector<SSG_peakRgnInfo> r_objOps;
r_objOps.insert(r_objOps.end(), objOps.begin(), objOps.end());
for (int i = 0; i < objOps.size(); i++)
{
SVzNL3DPoint c_pt = { objOps[i].centerPos .x, objOps[i].centerPos .y, objOps[i].centerPos .z};
SVzNL3DPoint r_c_pt = _ptRotate(c_pt, matrix3d);
r_objOps[i].centerPos.x = r_c_pt.x;
r_objOps[i].centerPos.y = r_c_pt.y;
r_objOps[i].centerPos.z = r_c_pt.z;
}
std::vector<std::vector< SVzNL3DPosition>> rotateLines;
SVzNLRangeD rx_range, ry_range;
_rotateCloudPts(scanData, lineNum, matrix3d, rotateLines, &rx_range, &ry_range);
cv::Mat r_img = cv::Mat::zeros(imgRows, imgCols, CV_8UC3);
//计算投影比例
double rx_scale = (rx_range.max - rx_range.min) / x_cols;
double ry_scale = (ry_range.max - ry_range.min) / y_rows;
_XOYprojection(r_img, rotateLines, r_objOps, rx_scale, ry_scale, rx_range, ry_range, false);
cv::Mat dis_img;
cv::hconcat(img, r_img, dis_img);
cv::imwrite(fileName, dis_img);
return;
}
void _genXOYProjectionImage_sideBagInfo(cv::String& fileName, SVzNL3DLaserLine* scanData, int lineNum, std::vector<SSG_sideBagInfo>& objOps, double rpy[3])
{
//统计X和Y的范围
std::vector<std::vector< SVzNL3DPosition>> scan_lines;
SVzNLRangeD x_range = { 0, -1 };
SVzNLRangeD y_range = { 0, -1 };
for (int line = 0; line < lineNum; line++)
{
std::vector< SVzNL3DPosition> a_line;
for (int i = 0; i < scanData[line].nPositionCnt; i++)
{
SVzNL3DPosition* pt3D = &scanData[line].p3DPosition[i];
if (pt3D->pt3D.z < 1e-4)
continue;
a_line.push_back(*pt3D);
if (x_range.max < x_range.min)
{
x_range.min = pt3D->pt3D.x;
x_range.max = pt3D->pt3D.x;
}
else
{
if (x_range.min > pt3D->pt3D.x)
x_range.min = pt3D->pt3D.x;
if (x_range.max < pt3D->pt3D.x)
x_range.max = pt3D->pt3D.x;
}
if (y_range.max < y_range.min)
{
y_range.min = pt3D->pt3D.y;
y_range.max = pt3D->pt3D.y;
}
else
{
if (y_range.min > pt3D->pt3D.y)
y_range.min = pt3D->pt3D.y;
if (y_range.max < pt3D->pt3D.y)
y_range.max = pt3D->pt3D.y;
}
}
scan_lines.push_back(a_line);
}
double x_scale = 1.0;
double y_scale = 1.0;
int x_rows = int((x_range.max - x_range.min) / x_scale);
int y_rows = int((y_range.max - y_range.min) / y_scale);
if (x_rows % 2 > 0)
x_rows += 1;
if (y_rows % 2 > 0)
y_rows += 1;
int imgRows = y_rows + 32;
int imgCols = x_rows + 32;
cv::Mat img = cv::Mat::zeros(imgRows, imgCols, CV_8UC3);
//计算投影比例
_XOYprojection_sideBagInfo(img, scan_lines, objOps, x_scale, y_scale, x_range, y_range);
#if 0
//旋转视角显示
double matrix3d[9];
EulerRpyToRotation1(rpy, matrix3d);
std::vector<SSG_sideBagInfo> r_objOps;
r_objOps.insert(r_objOps.end(), objOps.begin(), objOps.end());
for (int i = 0; i < objOps.size(); i++)
{
SVzNL3DPoint c_pt = { objOps[i].graspPos.x, objOps[i].graspPos.y, objOps[i].graspPos.z };
SVzNL3DPoint r_c_pt = _ptRotate(c_pt, matrix3d);
r_objOps[i].graspPos.x = r_c_pt.x;
r_objOps[i].graspPos.y = r_c_pt.y;
r_objOps[i].graspPos.z = r_c_pt.z;
}
std::vector<std::vector< SVzNL3DPosition>> rotateLines;
SVzNLRangeD rx_range, ry_range;
_rotateCloudPts(scanData, lineNum, matrix3d, rotateLines, &rx_range, &ry_range);
cv::Mat r_img = cv::Mat::zeros(imgRows, imgCols, CV_8UC3);
//计算投影比例
double rx_scale = (rx_range.max - rx_range.min) / x_cols;
double ry_scale = (ry_range.max - ry_range.min) / y_rows;
_XOYprojection_sideBagInfo(r_img, rotateLines, r_objOps, rx_scale, ry_scale, rx_range, ry_range);
cv::Mat dis_img;
cv::hconcat(img, r_img, dis_img);
cv::imwrite(fileName, dis_img);
#else
cv::Mat rot;
cv::rotate(img, rot, cv::ROTATE_90_CLOCKWISE); // 顺时针90°旋转
cv::flip(rot, img, 1); // 左右翻转
cv::imwrite(fileName, img);
#endif
return;
}
//量化成640*640左右大小的图像。
void project2DWithInterpolate(cv::Mat& img, SVzNL3DLaserLine* scanData, int lineNum, double fixed_xy_scale, double z_scale)
{
double namedSize = 640.0;//目标图像最大尺度为640像素
SVzNLRangeD x_range = { 0, -1 };
SVzNLRangeD y_range = { 0, -1 };
SVzNLRangeD z_range = { 0, -1 };
for (int line = 0; line < lineNum; line++)
{
for (int i = 0; i < scanData[line].nPositionCnt; i++)
{
SVzNL3DPosition* pt3D = &scanData[line].p3DPosition[i];
if (pt3D->pt3D.z < 1e-4)
continue;
if (x_range.max < x_range.min)
{
x_range.min = pt3D->pt3D.x;
x_range.max = pt3D->pt3D.x;
}
else
{
if (x_range.min > pt3D->pt3D.x)
x_range.min = pt3D->pt3D.x;
if (x_range.max < pt3D->pt3D.x)
x_range.max = pt3D->pt3D.x;
}
if (y_range.max < y_range.min)
{
y_range.min = pt3D->pt3D.y;
y_range.max = pt3D->pt3D.y;
}
else
{
if (y_range.min > pt3D->pt3D.y)
y_range.min = pt3D->pt3D.y;
if (y_range.max < pt3D->pt3D.y)
y_range.max = pt3D->pt3D.y;
}
if (z_range.max < z_range.min)
{
z_range.min = pt3D->pt3D.z;
z_range.max = pt3D->pt3D.z;
}
else
{
if (z_range.min > pt3D->pt3D.z)
z_range.min = pt3D->pt3D.z;
if (z_range.max < pt3D->pt3D.z)
z_range.max = pt3D->pt3D.z;
}
}
}
double xy_scale = fixed_xy_scale;
if (fixed_xy_scale < 1e-4)
{
double x_scale = (x_range.max - x_range.min) / namedSize;
double y_scale = (y_range.max - y_range.min) / namedSize;
double xy_scale;
if (x_scale < y_scale)
xy_scale = y_scale;
else
xy_scale = x_scale;
}
int img_rows = (int)((y_range.max - y_range.min) / xy_scale)+1;
if(img_rows %2 >0)
img_rows +=1;
int img_cols = (int)((x_range.max - x_range.min) / xy_scale)+ 1;
if (img_cols % 2 > 0)
img_cols += 1;
img = cv::Mat::zeros(img_rows, img_cols, CV_8UC1);
int polateWin = 5;
for (int line = 0; line < lineNum; line++)
{
//同时进行垂直插值
int pre_py = -1;
SVzNL3DPosition* pre_pt3D = NULL;
int pre_i = -1;
for (int i = 0; i < scanData[line].nPositionCnt; i++)
{
SVzNL3DPosition* pt3D = &scanData[line].p3DPosition[i];
if (pt3D->pt3D.z < 1e-4)
continue;
double x = pt3D->pt3D.x;
double y = pt3D->pt3D.y;
int px = (int)((x - x_range.min) / xy_scale);
int py = (int)((y - y_range.min) / xy_scale);
int value = (int)((pt3D->pt3D.z - z_range.min) / z_scale);
if (value > 254)
value = 254;
value = 255 - value;
img.at<uchar>(py, px) = (uchar)value;
//检查是否需要插值
if ( (py > pre_py + 1)&& (py <= pre_py + polateWin + 1) && (pre_py >= 0) && (pre_i >= 0) && (i == pre_i + 1)) //3D点连续量化点不连续插值
{
double dist = double(py - pre_py);
for (int iy = pre_py + 1; iy < py; iy++)
{
double k1 = (double)(iy - pre_py) / dist;
double k0 = 1 - k1;
double inter_x = pre_pt3D->pt3D.x * k0 + pt3D->pt3D.x * k1;
double inter_y = pre_pt3D->pt3D.y * k0 + pt3D->pt3D.y * k1;
double inter_z = pre_pt3D->pt3D.z * k0 + pt3D->pt3D.z * k1;
int polate_px = (int)((inter_x - x_range.min) / xy_scale);
int polate_py = (int)((inter_y - y_range.min) / xy_scale);
int polate_value = (int)((inter_z - z_range.min) / z_scale);
if (polate_value > 254)
polate_value = 254;
polate_value = 255 - polate_value;
img.at<uchar>(polate_py, polate_px) = (uchar)polate_value;
}
}
pre_i = i;
pre_py = py;
pre_pt3D = pt3D;
}
}
//水平插值
for (int y = 0; y < img.rows; y++)
{
int pre_x = -1;
uchar pre_value = 0;
for (int x = 0; x < img.cols; x++)
{
uchar value = img.at<uchar>(y, x);
if (value > 0)
{
if ((x > pre_x + 1) && (x <= pre_x + polateWin + 1) &&(pre_x >= 0)) //水平不连续,插值
{
double dist = double(x - pre_x);
for (int ix = pre_x + 1; ix < x; ix++)
{
double k1 = (double)(ix - pre_x) / dist;
double k0 = 1 - k1;
double inter_data = (double)pre_value * k0 + (double)value * k1;
if (inter_data > 255)
inter_data = 255;
uchar polate_value = (uchar)inter_data;
img.at<uchar>(y, ix) = polate_value;
}
}
pre_x = x;
pre_value = value;
}
}
}
}
void _outputScanDataFile_removeZeros(char* fileName, SVzNL3DLaserLine* scanData, int lineNum,
float lineV, int maxTimeStamp, int clockPerSecond)
{
std::ofstream sw(fileName);
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 realNum = 0;
for (int i = 0; i < scanData[line].nPositionCnt; i++)
{
if (scanData[line].p3DPosition[i].pt3D.z > 1e-4)
realNum++;
}
sw << "Line_" << line << "_" << scanData[line].nTimeStamp << "_" << realNum << std::endl;
for (int i = 0; i < scanData[line].nPositionCnt; i++)
{
if (scanData[line].p3DPosition[i].pt3D.z > 1e-4)
{
SVzNL3DPosition* pt3D = &scanData[line].p3DPosition[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();
}
#define TEST_CONVERT_TO_GRID 0
#define TEST_COMPUTE_GRASP_POINT 1
#define TEST_COMPUTE_CALIB_PARA 1
#define TEST_GROUP 16
int main()
{
#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:\\上古\\编织袋数据\\侧抓数据\\");
char _scan_file[256];
double _F = 1248.5;// 1231.2; //1729.0;; //f
for (int i = 1; i <= 2; i++)
{
sprintf_s(_scan_file, "%s%d_LaserData_Hi228621.txt", _scan_dir, i);
SVzNLXYZRGBDLaserLine* laser3DPoints_RGBD = vzReadLaserScanPointFromFile_XYZRGB(_scan_file, &lineNum, &lineV, &dataCalib, &maxTimeStamp, &clockPerSecond);
if (laser3DPoints_RGBD == NULL)
continue;
#if 1
double rpy[3] = { 0,-18, 0 };
double camPoseR[9];
EulerRpyToRotation1(rpy, camPoseR);
#else
double camPoseR[9] = {
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0 };
#endif
int vldLineNum = 0;
SVzNL3DLaserLine* gridData = _convertToGridData_XYZRGB(laser3DPoints_RGBD, lineNum, _F, camPoseR, &vldLineNum);
//生成水平扫描数据
int hLineNum = gridData[0].nPositionCnt;
SVzNL3DLaserLine* hScanData = (SVzNL3DLaserLine*)malloc(sizeof(SVzNL3DLaserLine) * hLineNum);
memset(hScanData, 0, sizeof(SVzNL3DLaserLine) * hLineNum);
for (int hLine = 0; hLine < hLineNum; hLine++)
{
hScanData[hLine].nPositionCnt = vldLineNum;
hScanData[hLine].nTimeStamp = hLine * 1000;
hScanData[hLine].p3DPosition = (SVzNL3DPosition*)malloc(sizeof(SVzNL3DPosition) * lineNum);
memset(hScanData[hLine].p3DPosition, 0, sizeof(SVzNL3DPosition) * lineNum);
for (int m = 0; m < vldLineNum; m++)
{
hScanData[hLine].p3DPosition[m].nPointIdx = m;
hScanData[hLine].p3DPosition[m].pt3D.x = gridData[m].p3DPosition[hLine].pt3D.y;
hScanData[hLine].p3DPosition[m].pt3D.y = gridData[m].p3DPosition[hLine].pt3D.x;
hScanData[hLine].p3DPosition[m].pt3D.z = gridData[m].p3DPosition[hLine].pt3D.z;
}
}
char _out_file[256];
sprintf_s(_out_file, "%sLaserLine%d_grid.txt", _scan_dir, i);
_outputScanDataFile_self(_out_file, gridData, vldLineNum,
lineV, maxTimeStamp, clockPerSecond);
sprintf_s(_out_file, "%sLaserLine%d_hScanData.txt", _scan_dir, i);
_outputScanDataFile_removeZeros(_out_file, hScanData, hLineNum,
lineV, maxTimeStamp, clockPerSecond);
printf("%s: convert done!\n", _scan_file);
}
#endif
#if TEST_COMPUTE_CALIB_PARA
char _calib_datafile[256];
sprintf_s(_calib_datafile, "F:\\上古\\编织袋数据\\点云8_广东1213-1215数据\\LaserLine10_grid.txt");
int lineNum = 0;
float lineV = 0.0f;
int dataCalib = 0;
int maxTimeStamp = 0;
int clockPerSecond = 0;
SVzNL3DLaserLine* laser3DPoints = vzReadLaserScanPointFromFile_XYZ(_calib_datafile, &lineNum, &lineV, &dataCalib, &maxTimeStamp, &clockPerSecond);
if (laser3DPoints)
{
SSG_planeCalibPara calibPara = sg_getBagBaseCalibPara(
laser3DPoints,
lineNum);
//结果进行验证
for (int i = 0; i < lineNum; i++)
{
if (i == 14)
int kkk = 1;
//行处理
//调平,去除地面
sg_lineDataR(&laser3DPoints[i], calibPara.planeCalib, calibPara.planeHeight);
}
//
char calibFile[250];
sprintf_s(calibFile, "F:\\上古\\编织袋数据\\点云8_广东1213-1215数据\\ground_calib_para.txt");
_outputCalibPara(calibFile, calibPara);
char _out_file[256];
sprintf_s(_out_file, "F:\\上古\\编织袋数据\\点云8_广东1213-1215数据\\LaserLine10_grid_calib.txt");
_outputScanDataFile_self(_out_file, laser3DPoints, lineNum,
lineV, maxTimeStamp, clockPerSecond);
printf("%s: calib done!\n", _calib_datafile);
}
#endif
#if TEST_COMPUTE_GRASP_POINT
const char* dataPath[TEST_GROUP] = {
"F:\\上古\\编织袋数据\\点云1\\", //0
"F:\\上古\\编织袋数据\\点云2\\", //1
"F:\\上古\\编织袋数据\\点云3\\", //2
"F:\\上古\\编织袋数据\\点云4_广东\\", //3
"F:\\上古\\编织袋数据\\点云5_广东\\", //4
"F:\\上古\\编织袋数据\\点云6_河南平顶山\\", //5
"F:\\上古\\编织袋数据\\点云7_广东1214\\", //6
"F:\\上古\\编织袋数据\\点云8_广东1213-1215数据\\", //7
"F:\\上古\\编织袋数据\\点云9_广东1219数据\\", //8
"F:\\上古\\编织袋数据\\点云10\\", //9
"F:\\上古\\编织袋数据\\侧抓数据\\", //10
"F:\\上古\\编织袋数据\\侧抓数据_现场\\20250419\\", //11
"F:\\上古\\编织袋数据\\侧抓数据_现场\\20250420-1\\", //12
"F:\\上古\\编织袋数据\\侧抓数据_现场\\20250420-2\\", //13
"F:\\上古\\编织袋数据\\侧抓数据_现场\\20250420-3\\", //14
"F:\\上古\\编织袋数据\\侧抓数据_现场\\20250420-4\\", //15
};
SVzNLRange fileIdx[TEST_GROUP] = {
{0,176},{1,200},{1,166},{122,141},{1,65},
{1,29},{108,135},{0,200}, {1,200}, {1,12},
{3,3}, {1,51}, {4,83}, {1,74}, {1,61},
{1,84}
};
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];
SG_bagPositionParam algoParam;
algoParam.bagParam.bagL = 650; //袋子长65cm
algoParam.bagParam.bagW = 450; //袋子宽40cm
algoParam.bagParam.bagH = 160; //袋子高16cm
#if BAG_ALGO_USE_CORNER_FEATURE
algoParam.cornerParam.cornerTh = 30; //45度角
algoParam.cornerParam.scale = 15; // 30; // algoParam.bagParam.bagH / 8;
algoParam.cornerParam.minEndingGap = algoParam.bagParam.bagW / 4;
algoParam.cornerParam.jumpCornerTh_1 = 60;
algoParam.cornerParam.jumpCornerTh_2 = 15;
#else
algoParam.slopeParam.LSlopeZWin = 10.0;
algoParam.slopeParam.validSlopeH = 10.0;
algoParam.slopeParam.minLJumpH = 20.0;
algoParam.slopeParam.minEndingGap = algoParam.bagParam.bagW / 4; ///当没有中间袋子只有左右袋子时有两组Ending。此参数确定两个ending最小间距
algoParam.valleyPara.valleyMinH = 10.0;
algoParam.valleyPara.valleyMaxW = 80.0; //取袋子宽度的1/5
#endif
algoParam.growParam.maxLineSkipNum = 5;
algoParam.growParam.yDeviation_max = 20.0;
algoParam.growParam.maxSkipDistance = 20.0;
algoParam.growParam.zDeviation_max = 80.0; //袋子高度1/2
algoParam.growParam.minLTypeTreeLen = 50.0; //mm
algoParam.growParam.minVTypeTreeLen = 50.0; //mm
char _scan_file[256];
int endGroup = TEST_GROUP - 1;
for (int grp = 0; grp <= 9; grp++)
{
if (grp == 7)
{
char calibFile[250];
sprintf_s(calibFile, "F:\\上古\\编织袋数据\\点云8_广东1213-1215数据\\ground_calib_para.txt");
poseCalibPara = _readCalibPara(calibFile);
}
for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++)
{
//fidx = 102;
int lineNum = 0;
float lineV = 0.0f;
int dataCalib = 0;
int maxTimeStamp = 0;
int clockPerSecond = 0;
sprintf_s(_scan_file, "%sLaserLine%d_grid.txt", dataPath[grp], fidx);
SVzNL3DLaserLine* laser3DPoints = vzReadLaserScanPointFromFile_XYZ(_scan_file, &lineNum, &lineV, &dataCalib, &maxTimeStamp, &clockPerSecond);
if (laser3DPoints == NULL)
continue;
if (grp < 10) //正面抓取
{
algoParam.filterParam.continuityTh = 20.0; //噪声滤除。当相邻点的z跳变大于此门限时检查是否为噪声。若长度小于outlierLen 视为噪声
algoParam.filterParam.outlierTh = 5;
long t1 = GetTickCount64();
#if 0
int errCode = 0;
std::vector<SSG_lineFeature> all_vLineFeatures;
std::vector<std::vector<int>> all_vLineNoises;
for (int i = 0; i < lineNum; i++)
{
if (i == 14)
int kkk = 1;
//行处理
sg_lineDataR(&laser3DPoints[i], camPoseR);
//sg_bagPositioning_lineProc(&laser3DPoints[i], i, &errCode, all_vLineFeatures, all_vLineNoises, algoParam);
}
std::vector<SSG_peakRgnInfo> objOps;
sg_getBagPosition(laser3DPoints, lineNum, all_vLineFeatures, all_vLineNoises, algoParam, objOps);
#else
for (int i = 0; i < lineNum; i++)
{
if (i == 14)
int kkk = 1;
//行处理
//调平,去除地面
sg_lineDataR(&laser3DPoints[i], poseCalibPara.planeCalib, poseCalibPara.planeHeight);
}
std::vector<SSG_peakRgnInfo> objOps;
sg_getBagPosition(laser3DPoints, lineNum, algoParam, poseCalibPara, objOps);
#endif
long t2 = GetTickCount64();
char _dbg_file[256];
#if 1
sprintf_s(_dbg_file, "%sresult\\LaserLine%d_result.txt", dataPath[grp], fidx);
_outputScanDataFile_RGBD_obj(_dbg_file, laser3DPoints, lineNum, lineV, maxTimeStamp, clockPerSecond, objOps);
sprintf_s(_dbg_file, "%sresult\\LaserLine%d_result_img.png", dataPath[grp], fidx);
cv::String imgName(_dbg_file);
double rpy[3] = { -30, 15, 0 }; //{ 0,-45, 0 }; //
_genXOYProjectionImage(imgName, laser3DPoints, lineNum, objOps, rpy);
#endif
#if 0
//量化成2D图像作为训练样本
cv::Mat project2D_img;
double z_scale = 3.0;
double xy_scale = 2.0;
project2DWithInterpolate(project2D_img, laser3DPoints, lineNum, xy_scale, z_scale);
cv::Mat project2D_color;
cv::applyColorMap(project2D_img, project2D_color, cv::COLORMAP_JET);
sprintf_s(_dbg_file, "%simg2D_JET\\LaserLine%d_img2D.png", dataPath[grp], fidx);
cv::String img2DName(_dbg_file);
cv::imwrite(img2DName, project2D_color);
cv::Mat project2D_color_HOT;
cv::applyColorMap(project2D_img, project2D_color_HOT, cv::COLORMAP_HOT);
sprintf_s(_dbg_file, "%simg2D\\LaserLine%d_img2D.png", dataPath[grp], fidx);
cv::String img2DName_HOT(_dbg_file);
cv::imwrite(img2DName_HOT, project2D_color_HOT);
#endif
printf("%s: %d(ms)!\n", _scan_file, (int)(t2 - t1));
}
else if (grp >= 10) //侧面抓取
{
algoParam.filterParam.continuityTh = 5.0; //噪声滤除。当相邻点的距离大于此门限时检查是否为噪声。若长度小于outlierLen 视为噪声
algoParam.filterParam.outlierTh = 5;
algoParam.bagParam.bagL = 650; //袋子长65cm
algoParam.bagParam.bagW = 450; //袋子宽40cm
algoParam.bagParam.bagH = 80; //袋子高16cm
algoParam.growParam.maxLineSkipNum = 5;
algoParam.growParam.yDeviation_max = 20.0;
algoParam.growParam.zDeviation_max = 8.0;
long t1 = GetTickCount64();
int errCode = 0;
SSG_stackBaseParam stackBaseParam = {200, 260, 550};
SSG_treeGrowParam stackBaseGrowParam;
memset(&stackBaseGrowParam, 0, sizeof(SSG_treeGrowParam));
stackBaseGrowParam.maxLineSkipNum = 10;
stackBaseGrowParam.yDeviation_max = 20.0;
stackBaseGrowParam.zDeviation_max = 20.0;
SSG_6DOF stackBasePosition;
sg_getSideBagStackBasePosition(
laser3DPoints,
lineNum,
stackBaseParam,
stackBaseGrowParam,
&stackBasePosition //垛的托盘的中心位置和角度
);
//行列转置。侧面扫描时激光线水平,所以要按列处理
std::vector<SSG_sideBagInfo> objOps;
//sg_sideBagPosition(laser3DPoints, lineNum, algoParam, objOps);
long t2 = GetTickCount64();
char _dbg_file[256];
sprintf_s(_dbg_file, "%sresult\\LaserLine%d_result.txt", dataPath[grp], fidx);
_outputScanDataFile_RGBD_sideBagObj(_dbg_file, laser3DPoints, lineNum, lineV, maxTimeStamp, clockPerSecond, objOps);
sprintf_s(_dbg_file, "%sresult\\LaserLine%d_result_img.png", dataPath[grp], fidx);
cv::String imgName(_dbg_file);
double rpy[3] = { -30, 15, 0 }; //{ 0,-45, 0 }; //
_genXOYProjectionImage_sideBagInfo(imgName, laser3DPoints, lineNum, objOps, rpy);
printf("%s: %d(ms)!\n", _scan_file, (int)(t2 - t1));
}
}
}
#endif
printf("all done!\n");
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 入门使用技巧:
// 1. 使用解决方案资源管理器窗口添加/管理文件
// 2. 使用团队资源管理器窗口连接到源代码管理
// 3. 使用输出窗口查看生成输出和其他消息
// 4. 使用错误列表窗口查看错误
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件