algoLib/boxCarMeasure_test/boxCarMeasureTest.cpp
2025-06-11 22:14:58 +08:00

984 lines
27 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.

// boxCarMeasure.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <fstream>
#include <vector>
#include <stdio.h>
#include <VZNL_Types.h>
#include "direct.h"
#include <string>
#include "boxCarMeasure_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* _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 _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();
}
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;
}
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, SSG_boxCarDimension* dimen)
{
std::ofstream sw(fileName);
int realLines = lineNum;
if (dimen)
realLines += 1;
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];
if (pt3D->pt3D.z < 1e-4)
continue;
int vType = pt3D->nPointIdx & 0xff;
int hType = vType >> 4;
int objId = (pt3D->nPointIdx >> 8) & 0xff;
vType = vType & 0x0f;
if (LINE_FEATURE_RIGHT_ANGLE_HR == vType)
{
rgb = { 255, 97, 0 };
size = 3;
}
else if (LINE_FEATURE_RIGHT_ANGLE_HF == vType)
{
rgb = { 255, 255, 0 };
size = 3;
}
else if (LINE_FEATURE_RIGHT_ANGLE_RH == vType)
{
rgb = { 255, 0, 255 };
size = 3;
}
else if (LINE_FEATURE_RIGHT_ANGLE_FH == vType)
{
rgb = { 160, 82, 45 };
size = 3;
}
else if (LINE_FEATURE_RIGHT_ANGLE_HR == hType)
{
rgb = { 0, 0, 255 };
size = 3;
}
else if (LINE_FEATURE_RIGHT_ANGLE_HF == hType)
{
rgb = { 0, 255, 255 };
size = 3;
}
else if (LINE_FEATURE_RIGHT_ANGLE_RH == hType)
{
rgb = { 0, 255, 0 };
size = 3;
}
else if (LINE_FEATURE_RIGHT_ANGLE_FH == hType)
{
rgb = { 85, 107, 47 };
size = 3;
}
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 (dimen)
{
int ptNum = 4;
sw << "Line_" << lineNum << "_" << (nTimeStamp + 1000) << "_" << ptNum << std::endl;
for (int i = 0; i < 4; i++)
{
rgb = { 255, 0, 0 };
size = 25;
float x = (float)dimen->endings[i].x;
float y = (float)dimen->endings[i].y;
float z = (float)dimen->endings[i].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 _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,
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 >> 8) & 0xff;
vType = vType & 0x0f;
if (LINE_FEATURE_RIGHT_ANGLE_HR == vType)
{
rgb = { 255, 97, 0 };
size = 3;
}
else if (LINE_FEATURE_RIGHT_ANGLE_HF == vType)
{
rgb = { 255, 255, 0 };
size = 3;
}
else if (LINE_FEATURE_RIGHT_ANGLE_RH == vType)
{
rgb = { 255, 0, 255 };
size = 3;
}
else if (LINE_FEATURE_RIGHT_ANGLE_FH == vType)
{
rgb = { 160, 82, 45 };
size = 3;
}
else if (LINE_FEATURE_RIGHT_ANGLE_HR == hType)
{
rgb = { 0, 0, 255 };
size = 3;
}
else if (LINE_FEATURE_RIGHT_ANGLE_HF == hType)
{
rgb = { 0, 255, 255 };
size = 3;
}
else if (LINE_FEATURE_RIGHT_ANGLE_RH == hType)
{
rgb = { 0, 255, 0 };
size = 3;
}
else if (LINE_FEATURE_RIGHT_ANGLE_FH == hType)
{
rgb = { 85, 107, 47 };
size = 3;
}
else
{
rgb = { 200, 200, 200 };
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);
}
}
}
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 _genXOYProjectionImage(cv::String& fileName, SVzNL3DLaserLine* scanData, int lineNum, 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, x_scale, y_scale, x_range, y_range);
//旋转视角显示
double matrix3d[9];
EulerRpyToRotation1(rpy, matrix3d);
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, rx_scale, ry_scale, rx_range, ry_range);
cv::Mat dis_img;
cv::hconcat(img, r_img, dis_img);
cv::imwrite(fileName, dis_img);
return;
}
#define TEST_GROUP 1
int main()
{
#if 0
//将数据转换成栅格格式格式
char _scan_dir[256];
int lineNum = 0;
float lineV = 0.0f;
int dataCalib = 0;
int maxTimeStamp = 0;
int clockPerSecond = 0;
sprintf_s(_scan_dir, "E:\\上古\\车厢动态扫描\\");
char _scan_file[256];
double _F = 1210.06; //f
for (int i = 1; i <= 5; i++)
{
sprintf_s(_scan_file, "%sLaserLine%d.txt", _scan_dir, i);
SVzNLXYZRGBDLaserLine* laser3DPoints_RGBD = vzReadLaserScanPointFromFile_XYZRGB(_scan_file, &lineNum, &lineV, &dataCalib, &maxTimeStamp, &clockPerSecond);
if (laser3DPoints_RGBD == NULL)
continue;
double camPoseR[9] = {
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0 };
int vldLineNum = 0;
SVzNL3DLaserLine* gridData = _convertToGridData_XYZRGB(laser3DPoints_RGBD, lineNum, _F, camPoseR, &vldLineNum);
char _out_file[256];
sprintf_s(_out_file, "%sLaserLine%d_grid.txt", _scan_dir, i);
_outputScanDataFile_self(_out_file, gridData, vldLineNum,
lineV, maxTimeStamp, clockPerSecond);
printf("%s: convert done!\n", _scan_file);
}
#else
const char* dataPath[TEST_GROUP] = {
"E:\\上古\\车厢动态扫描\\", //0
};
SVzNLRange fileIdx[TEST_GROUP] = {
{1,5} };
double camPoseR[9] = {
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0 };
SG_boxCarMeasureParam algoParam;
//algoParam.filterParam.zJumpTh = 20.0; //噪声滤除。当相邻点的z跳变大于此门限时检查是否为噪声。若长度小于outlierLen 视为噪声
//algoParam.filterParam.outlierLen = 5;
algoParam.templatePara_HF.H_len = 25.0; //mm
algoParam.templatePara_HF.V_len = 100.0; //mm
algoParam.templatePara_HF.maxDelta = 8.0; //mm
algoParam.templatePara_FH.H_len = 100.0; //mm
algoParam.templatePara_FH.V_len = 100.0; //mm
algoParam.templatePara_FH.maxDelta = 8.0; //mm
algoParam.templatePara_HR.H_len = 100.0; //mm
algoParam.templatePara_HR.V_len = 100.0; //mm
algoParam.templatePara_HR.maxDelta = 8.0; //mm
algoParam.templatePara_RH.H_len = 25.0; //mm
algoParam.templatePara_RH.V_len = 100.0; //mm
algoParam.templatePara_RH.maxDelta = 8.0; //mm
algoParam.growParam.maxLineSkipNum = -1;
algoParam.growParam.maxSkipDistance = 100.0;
algoParam.growParam.yDeviation_max = 10.0;
algoParam.growParam.zDeviation_max = 10.0;
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 <= endGroup; grp++)
{
for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++)
{
//fidx = 4;
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;
long t1 = GetTickCount64();
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 == 1400)
int kkk = 1;
//行处理
sg_boxCarMeasure_lineProc(
&laser3DPoints[i],
i,
&errCode,
all_vLineFeatures,
all_vLineNoises,
algoParam);
}
SSG_boxCarDimension dimen = sg_getBoxCarDimension(
laser3DPoints,
lineNum,
all_vLineFeatures,
all_vLineNoises,
algoParam);
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, &dimen);
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, rpy);
#endif
printf("%s: %d(ms), L=%f, W=%f, Angle=%f!\n", _scan_file, (int)(t2 - t1), dimen.L, dimen.W, dimen.angle);
for (int i = 0; i < 4; i++)
{
printf(" (%0.1f, %.1f, %.1f)\n", dimen.endings[i].x, dimen.endings[i].y, dimen.endings[i].z);
}
}
}
#endif
printf("all done!\n");
}