GrabBag/SDK/bagPosition/begPostionDemo.cpp

988 lines
30 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.

// 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)
{
SVzNLXYZRGBDLaserLine* _scanLines = NULL;
return _scanLines;
}
SVzNL3DLaserLine* vzReadLaserScanPointFromFile_XYZ(const char* fileName, int* scanLineNum, float* scanV,
int* dataCalib, int* scanMaxStamp, int* canClockUnit)
{
SVzNL3DLaserLine* _scanLines = NULL;
return _scanLines;
}
SVzNL3DLaserLine* _convertToGridData_XYZRGB(SVzNLXYZRGBDLaserLine* laser3DPoints, int lineNum, double _F, double* camPoseR, int* outLineNum)
{
SVzNL3DLaserLine* gridData = nullptr;
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)
{
}
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)
{
}
void _outputScanDataFile_RGBD_sideBagObj(char* fileName, SVzNL3DLaserLine* scanData, int lineNum,
float lineV, int maxTimeStamp, int clockPerSecond, std::vector<SSG_sideBagInfo>& objOps)
{
}
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()
{
/**
* 计算调平参数
*/
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++)
{
//调平,去除地面
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);
}
/**
* 计算抓取点
*/
const char* dataPath = "F:\\ShangGu\\编织袋数据\\点云1\\";
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
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;
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 calibFile[250];
sprintf_s(calibFile, "F:\\上古\\编织袋数据\\点云8_广东1213-1215数据\\ground_calib_para.txt");
poseCalibPara = _readCalibPara(calibFile);
algoParam.filterParam.continuityTh = 20.0; //噪声滤除。当相邻点的z跳变大于此门限时检查是否为噪声。若长度小于outlierLen 视为噪声
algoParam.filterParam.outlierTh = 5;
long t1 = GetTickCount64();
std::vector<SSG_peakRgnInfo> objOps;
sg_getBagPosition(laser3DPoints, lineNum, algoParam, poseCalibPara, objOps);
long t2 = GetTickCount64();
char _dbg_file[256];
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);
printf("%s: %d(ms)!\n", _scan_file, (int)(t2 - t1));
}