hybridPosePositioning
version 1.5.1 : 转子钢芯,2D结果由ROI输入换成掩码输入
This commit is contained in:
parent
5772788729
commit
3f2d18e871
@ -2490,7 +2490,7 @@ void HaiRuiMa_rotorCorePositioning_test(void)
|
||||
const char* ver = wd_hybridPositioningVersion();
|
||||
printf("ver:%s\n", ver);
|
||||
|
||||
for (int grp = 8; grp <= 8; grp++)
|
||||
for (int grp = 4; grp <= 8; grp++)
|
||||
{
|
||||
SSG_planeCalibPara groundCalibPara;
|
||||
//初始化成单位阵
|
||||
@ -2557,13 +2557,42 @@ void HaiRuiMa_rotorCorePositioning_test(void)
|
||||
binInfo = _readBinInfo(calibFile);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if( (grp ==3) || (grp == 4) ||(grp == 8))
|
||||
sprintf_s(_scan_file, "%s%d_origin_result.txt", dataPath[grp], fidx);
|
||||
else
|
||||
sprintf_s(_scan_file, "%s%d_result.txt", dataPath[grp], fidx);
|
||||
std::vector<WD_objArea2D> objROIs;
|
||||
vzReadObj2DROI(_scan_file, objROIs);
|
||||
|
||||
#else //使用掩膜
|
||||
sprintf_s(_scan_file, "%s%d_mask.bmp", dataPath[grp], fidx);
|
||||
//
|
||||
// 读取 BMP 文件(彩色,默认)
|
||||
cv::Mat img = cv::imread(_scan_file, cv::IMREAD_COLOR);
|
||||
// 检查是否读取成功
|
||||
if (img.empty()) {
|
||||
std::cerr << "读取失败:检查路径或文件是否损坏" << std::endl;
|
||||
continue;
|
||||
}
|
||||
std::vector<std::vector<SWDColorRGB>> objDataMask; //和扫描线存储结构相同:按列存储
|
||||
const int rows = img.rows; // 高(y 方向)
|
||||
const int cols = img.cols; // 宽(x 方向)
|
||||
// 2. 创建按列存储的二维容器:data[x][y]
|
||||
// 外层 = 列号 x,内层 = 行号 y
|
||||
objDataMask.resize(cols);
|
||||
for (int i = 0; i < cols; i++)
|
||||
objDataMask[i].resize(rows);
|
||||
// 3. 逐像素转换(OpenCV 默认是 BGR 顺序,需交换成 R、G、B)
|
||||
for (int y = 0; y < rows; ++y) {
|
||||
const cv::Vec3b* ptr = img.ptr<cv::Vec3b>(y); // 第 y 行首地址
|
||||
for (int x = 0; x < cols; ++x) {
|
||||
objDataMask[x][y].B = ptr[x][0];
|
||||
objDataMask[x][y].G = ptr[x][1];
|
||||
objDataMask[x][y].R = ptr[x][2];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
SWD_Cylinder workpieceParam; //圆柱形工件的标称半径和高度
|
||||
workpieceParam.radius = 18.0; //最小半径
|
||||
workpieceParam.height = 20.0; //最小高度
|
||||
@ -2611,7 +2640,7 @@ void HaiRuiMa_rotorCorePositioning_test(void)
|
||||
std::vector<std::vector<SVzNL3DPosition>> debugScanLines;
|
||||
wd_HRM_RotorCorePositioning(
|
||||
scanLines,
|
||||
objROIs,
|
||||
objDataMask,
|
||||
groundCalibPara,
|
||||
spacerParam,
|
||||
workpieceParam,
|
||||
|
||||
@ -27,6 +27,7 @@ void vzReadLaserScanPointFromFile_plyTxt(const char* fileName, std::vector< SVzN
|
||||
if (inputFile.is_open() == false)
|
||||
return;
|
||||
|
||||
std::getline(inputFile, linedata); //skip first line
|
||||
while (std::getline(inputFile, linedata))
|
||||
{
|
||||
if (linedata.empty())
|
||||
@ -34,19 +35,14 @@ void vzReadLaserScanPointFromFile_plyTxt(const char* fileName, std::vector< SVzN
|
||||
|
||||
double X, Y, Z;
|
||||
sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &X, &Y, &Z);
|
||||
SVzNL3DPoint a_pt;
|
||||
if (true == exchangeXY)
|
||||
{
|
||||
a_pt.x = Y; //将扫描线调整为Y方向;扫描方向为X方向
|
||||
a_pt.y = X;
|
||||
}
|
||||
else
|
||||
if (Z > 1e-4)
|
||||
{
|
||||
SVzNL3DPoint a_pt;
|
||||
a_pt.x = X;
|
||||
a_pt.y = Y;
|
||||
a_pt.z = Z;
|
||||
scanData.push_back(a_pt);
|
||||
}
|
||||
a_pt.z = Z;
|
||||
scanData.push_back(a_pt);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -757,48 +753,148 @@ void _outputWeldInfo(char* outFileName, std::vector<SVzNL3DPoint>& weldRawPoints
|
||||
sw.close();
|
||||
}
|
||||
|
||||
//将ply格式的数据恢复成扫描行的数据形式,从而方面按行进行处理
|
||||
void wd_getScanLines(
|
||||
std::vector<SVzNL3DPoint>& scanData,
|
||||
std::vector<std::vector< SVzNLPointXYZRGBA>>& scanLines)
|
||||
{
|
||||
std::vector<SVzNLPointXYZRGBA> a_line;
|
||||
for (int i = 0, i_max = scanData.size(); i < i_max; i++)
|
||||
{
|
||||
SVzNL3DPoint a_ptXYZ = scanData[i];
|
||||
SVzNLPointXYZRGBA a_pt;
|
||||
a_pt.nRGB = 0;
|
||||
a_pt.x = a_ptXYZ.x;
|
||||
a_pt.y = a_ptXYZ.y;
|
||||
a_pt.z = a_ptXYZ.z;
|
||||
|
||||
if (a_line.size() == 0)
|
||||
a_line.push_back(a_pt);
|
||||
else
|
||||
{
|
||||
SVzNLPointXYZRGBA pre_pt = a_line.back();
|
||||
double y_diff = a_pt.y - pre_pt.y;
|
||||
if (y_diff < -100.0)
|
||||
{
|
||||
scanLines.push_back(a_line);
|
||||
a_line.clear();
|
||||
a_line.push_back(a_pt);
|
||||
}
|
||||
else
|
||||
a_line.push_back(a_pt);
|
||||
}
|
||||
}
|
||||
//last line
|
||||
if (a_line.size() > 0)
|
||||
scanLines.push_back(a_line);
|
||||
return;
|
||||
}
|
||||
|
||||
void _convertToGridData_XYZRGB(std::vector<std::vector< SVzNLPointXYZRGBA>>& scanData, double _F, std::vector<std::vector< SVzNL3DPosition>>& gridData)
|
||||
{
|
||||
int lineNum = (int)scanData.size();
|
||||
int min_y = 100000000;
|
||||
int max_y = -10000000;
|
||||
int validStartLine = -1;
|
||||
int validEndLine = -1;
|
||||
for (int line = 0; line < lineNum; line++)
|
||||
{
|
||||
if (scanData[line].size() > 0)
|
||||
{
|
||||
if (validStartLine < 0)
|
||||
{
|
||||
validStartLine = line;
|
||||
validEndLine = line;
|
||||
}
|
||||
else
|
||||
validEndLine = line;
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)scanData[line].size(); i++)
|
||||
{
|
||||
SVzNLPointXYZRGBA& a_pt = scanData[line][i];
|
||||
if (a_pt.z > 1e-4)
|
||||
{
|
||||
double v = _F * a_pt.y / a_pt.z + 2000;
|
||||
a_pt.nRGB = (int)(v + 0.5);
|
||||
max_y = max_y < (int)a_pt.nRGB ? (int)a_pt.nRGB : max_y;
|
||||
min_y = min_y > (int)a_pt.nRGB ? (int)a_pt.nRGB : min_y;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (min_y == 100000000)
|
||||
return;
|
||||
|
||||
int vldLineNum = validEndLine - validStartLine + 1;
|
||||
gridData.resize(vldLineNum);
|
||||
int pt_counter = max_y - min_y + 1;
|
||||
for (int i = 0; i < vldLineNum; i++)
|
||||
{
|
||||
gridData[i].resize(pt_counter);
|
||||
for (int j = 0; j < pt_counter; j++)
|
||||
{
|
||||
gridData[i][j].nPointIdx = j;
|
||||
gridData[i][j].pt3D.x = 0;
|
||||
gridData[i][j].pt3D.y = 0;
|
||||
gridData[i][j].pt3D.z = 0;
|
||||
}
|
||||
}
|
||||
for (int line = validStartLine; line <= validEndLine; line++)
|
||||
{
|
||||
int gridLine = line - validStartLine;
|
||||
for (int i = 0; i < (int)scanData[line].size(); i++)
|
||||
{
|
||||
SVzNLPointXYZRGBA& a_pt = scanData[line][i];
|
||||
if (a_pt.z > 1e-4)
|
||||
{
|
||||
int pt_id = a_pt.nRGB - min_y;
|
||||
gridData[gridLine][pt_id].pt3D.x = a_pt.x;
|
||||
gridData[gridLine][pt_id].pt3D.y = a_pt.y;
|
||||
gridData[gridLine][pt_id].pt3D.z = a_pt.z;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#define CONVERT_TO_GRID 0
|
||||
#define TEST_COMPUTE_CALIB_PARA 0
|
||||
#define TEST_COMPUTE_POSITION 1
|
||||
#define TEST_GROUP 2
|
||||
#define TEST_GROUP 3
|
||||
void lapWeldTest()
|
||||
{
|
||||
const char* dataPath[TEST_GROUP] = {
|
||||
"F:\\ShangGu\\项目\\钢板搭接焊缝检测\\数据\\", //0
|
||||
"F:\\ShangGu\\项目\\钢板搭接焊缝检测\\模拟数据\\",
|
||||
"F:/ShangGu/项目/冠钦_博清科技/焊缝识别/博清实验室模拟数据/", //0
|
||||
};
|
||||
|
||||
SVzNLRange fileIdx[TEST_GROUP] = {
|
||||
{1,6}, {1,1}
|
||||
{1,6}, {1,1}, {3, 3}
|
||||
};
|
||||
|
||||
#if CONVERT_TO_GRID
|
||||
int convertGrp = 0;
|
||||
int convertGrp = 2;
|
||||
for (int fidx = fileIdx[convertGrp].nMin; fidx <= fileIdx[convertGrp].nMax; fidx++)
|
||||
{
|
||||
char _scan_file[256];
|
||||
sprintf_s(_scan_file, "%sglove_%d.txt", dataPath[convertGrp], fidx);
|
||||
sprintf_s(_scan_file, "%s%d_LaserData_Jh26B083.txt", dataPath[convertGrp], fidx);
|
||||
std::vector< SVzNL3DPoint> scanData;
|
||||
bool exchangeXY = true;
|
||||
vzReadLaserScanPointFromFile_plyTxt(_scan_file, scanData, exchangeXY);
|
||||
//将数据恢复为按扫描线存储格式
|
||||
std::vector< std::vector<SVzNL3DPosition>> scanLines;
|
||||
std::vector< std::vector<SVzNLPointXYZRGBA>> scanLines;
|
||||
wd_getScanLines(scanData, scanLines);
|
||||
|
||||
double y_step;
|
||||
if ((fidx == 4) || (fidx == 5))
|
||||
y_step = 0.106;
|
||||
else
|
||||
y_step = 0.091;
|
||||
std::vector< std::vector<SVzNL3DPosition>> grid_scanLines;
|
||||
_convertToGridData(scanLines, grid_scanLines, y_step);
|
||||
sprintf_s(_scan_file, "%sglove_%d_scanLine.txt", dataPath[convertGrp], fidx);
|
||||
double _F = 1181.04542; //f
|
||||
std::vector<std::vector< SVzNL3DPosition>> gridData;
|
||||
_convertToGridData_XYZRGB(scanLines, _F, gridData);
|
||||
sprintf_s(_scan_file, "%s%d_scanLine.txt", dataPath[convertGrp], fidx);
|
||||
int headNullLines = 0;
|
||||
_outputScanDataFile_vector(_scan_file, grid_scanLines, false, &headNullLines);
|
||||
_outputScanDataFile_vector(_scan_file, gridData, false, &headNullLines);
|
||||
printf("%s: head null lines = %d\n", _scan_file, headNullLines);
|
||||
#if 1
|
||||
sprintf_s(_scan_file, "%sglove_%d_scanLine_h.txt", dataPath[convertGrp], fidx);
|
||||
_outputScanDataFile_vector_h(_scan_file, grid_scanLines);
|
||||
_outputScanDataFile_vector_h(_scan_file, gridData);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@ -929,16 +1025,17 @@ void lapWeldTest()
|
||||
|
||||
#define TEST_BQ_CALIB_PARA 0
|
||||
#define TEST_BQ_WELD_SEAM 1
|
||||
#define BQ_TEST_GROUP 2
|
||||
#define BQ_TEST_GROUP 3
|
||||
void BQ_thinWeldSeamTest()
|
||||
{
|
||||
const char* dataPath[BQ_TEST_GROUP] = {
|
||||
"F:/ShangGu/项目/冠钦_博清科技/焊缝识别/数据/", //0
|
||||
"F:/ShangGu/项目/冠钦_博清科技/焊缝识别/博清实验室模拟数据/", //0
|
||||
"F:/ShangGu/项目/冠钦_博清科技/焊缝识别/博清实验室模拟数据/", //1
|
||||
"F:/ShangGu/项目/冠钦_博清科技/焊缝识别/博清实验室模拟数据2/", //2
|
||||
};
|
||||
|
||||
SVzNLRange fileIdx[BQ_TEST_GROUP] = {
|
||||
{1,4},{1,2}
|
||||
{1,4},{3,3}, {1,3}
|
||||
};
|
||||
|
||||
|
||||
@ -1017,7 +1114,7 @@ void BQ_thinWeldSeamTest()
|
||||
|
||||
#if TEST_BQ_WELD_SEAM
|
||||
//for (int group = 0; group < TEST_GROUPS; group++)
|
||||
for (int grp = 1; grp < BQ_TEST_GROUP; grp++)
|
||||
for (int grp = 2; grp < BQ_TEST_GROUP; grp++)
|
||||
{
|
||||
SSG_planeCalibPara groundCalibPara;
|
||||
//初始化成单位阵
|
||||
@ -1040,19 +1137,17 @@ void BQ_thinWeldSeamTest()
|
||||
groundCalibPara = _readCalibPara(calibFile);
|
||||
}
|
||||
|
||||
double para_chkWidth_wide = 2.5f;
|
||||
|
||||
SSG_cornerParam cornerPara;
|
||||
SVzNLRangeD gapParam;
|
||||
|
||||
SWD_valleyParam valleyParam;
|
||||
valleyParam.chkWin_width = 5.0; // 2.5; //mm, 检测2.5mm宽的V型
|
||||
valleyParam.chkWin_width = 2.5; // .0; // 2.5; //mm, 检测2.5mm宽的V型
|
||||
valleyParam.maxWidth = 20.0; //最大宽度20mm,用于过滤虚假信号
|
||||
valleyParam.minHeight = 0.5;
|
||||
valleyParam.minHeight = 0.3;
|
||||
|
||||
SSG_treeGrowParam growParam;
|
||||
growParam.maxLineSkipNum = 50;
|
||||
growParam.yDeviation_max = 1.5;
|
||||
growParam.yDeviation_max = 1.0;
|
||||
growParam.maxSkipDistance = 30.0;
|
||||
growParam.zDeviation_max = 5.0;//
|
||||
growParam.minLTypeTreeLen = 50; //mm,
|
||||
@ -1070,8 +1165,10 @@ void BQ_thinWeldSeamTest()
|
||||
char _scan_file[256];
|
||||
if(0 == grp)
|
||||
sprintf_s(_scan_file, "%s%d_LaserData_Jl26C077.txt", dataPath[grp], fidx);
|
||||
else
|
||||
else if(1 == grp)
|
||||
sprintf_s(_scan_file, "%s%d_LaserData_Jh26B083.txt", dataPath[grp], fidx);
|
||||
else if(2 == grp)
|
||||
sprintf_s(_scan_file, "%s%d_LaserData_Jh26B489.txt", dataPath[grp], fidx);
|
||||
printf("process: %s......\n", _scan_file);
|
||||
|
||||
std::vector<std::vector< SVzNL3DPosition>> scanLines;
|
||||
@ -1117,7 +1214,7 @@ void BQ_thinWeldSeamTest()
|
||||
growParam);
|
||||
}
|
||||
|
||||
int weldRefPoints = 3;
|
||||
int weldRefPoints = 6;
|
||||
int errCode = 0;
|
||||
std::vector<SVzNL3DPoint> weldOps;
|
||||
std::vector<SVzNL3DPosition> weldRawPoints;
|
||||
|
||||
@ -55,6 +55,13 @@ typedef struct
|
||||
double z;
|
||||
}SWD3DPoint;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int R;
|
||||
int G;
|
||||
int B;
|
||||
}SWDColorRGB;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double cx, cy, r;
|
||||
@ -151,6 +158,14 @@ typedef struct
|
||||
int ptIdx;
|
||||
}SSG_featureClusteringInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int left;
|
||||
int right;
|
||||
int top;
|
||||
int bottom;
|
||||
}SSG_ROIRect;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double left;
|
||||
|
||||
@ -33,7 +33,8 @@
|
||||
//version 1.4.8 : 转子钢芯,隔板下工作部分可见时虚假检测的滤除时的距离系数由0.3调整为0.75。当点云质量不好时,0.3会导致无法找到隔板上的比较点
|
||||
//version 1.4.9 : 转子钢芯,隔板下工作部分可见时虚假检测的滤除时的距离系数由0.3调整为2.0(直径)。当点云质量不好时,0.3会导致无法找到隔板上的比较点
|
||||
//version 1.5.0 : 转子钢芯,使用2D识别结果的ROI来确定目标的大小(不再需要输入工件半径参数)。支持定子检测
|
||||
std::string m_strVersion = "HybridPositioning 1.5.0";
|
||||
//version 1.5.1 : 转子钢芯,2D结果由ROI输入换成掩码输入
|
||||
std::string m_strVersion = "HybridPositioning 1.5.1";
|
||||
const char* wd_hybridPositioningVersion(void)
|
||||
{
|
||||
return m_strVersion.c_str();
|
||||
@ -1568,9 +1569,33 @@ void _searchRCirclePoints(
|
||||
return;
|
||||
}
|
||||
|
||||
void _updateROI(int col, int row, SSG_ROIRect& a_roi)
|
||||
{
|
||||
if (a_roi.right == 0)
|
||||
{
|
||||
a_roi.left = col;
|
||||
a_roi.right = col;
|
||||
a_roi.top = row;
|
||||
a_roi.bottom = row;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (a_roi.left > col)
|
||||
a_roi.left = col;
|
||||
if (a_roi.right < col)
|
||||
a_roi.right = col;
|
||||
if (a_roi.top > row)
|
||||
a_roi.top = row;
|
||||
if (a_roi.bottom < row)
|
||||
a_roi.bottom = row;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void wd_HRM_RotorCorePositioning(
|
||||
std::vector< std::vector<SVzNLPositionD>>& scanLinesInput,
|
||||
std::vector<WD_objArea2D>& objROIs,
|
||||
std::vector<std::vector<SWDColorRGB>>& objDataMask, //2D目标腌膜
|
||||
//std::vector<WD_objArea2D>& objROIs,
|
||||
const SSG_planeCalibPara groundCalibPara,
|
||||
const SVzNLSizeD spacerParam, //隔板参数:长和宽
|
||||
const SWD_Cylinder workpieceParam, //圆柱形工件的标称半径和高度
|
||||
@ -1606,19 +1631,10 @@ void wd_HRM_RotorCorePositioning(
|
||||
return;
|
||||
}
|
||||
|
||||
int maxU = 0; //2DͼÏñµÄ×î´óCol
|
||||
int maxV = 0; //2DͼÏñµÄ×î´óRow
|
||||
for (int line = 0; line < lineNum; line++)
|
||||
{
|
||||
for (int ptIdx = 0; ptIdx < (int)scanLinesInput[line].size(); ptIdx++)
|
||||
{
|
||||
if (scanLinesInput[line][ptIdx].pt3D.z < 1e-4)
|
||||
continue;
|
||||
|
||||
maxU = maxU < scanLinesInput[line][ptIdx].ptLeft2D.x ? scanLinesInput[line][ptIdx].ptLeft2D.x : maxU;
|
||||
maxV = maxV < scanLinesInput[line][ptIdx].ptLeft2D.y ? scanLinesInput[line][ptIdx].ptLeft2D.y : maxV;
|
||||
}
|
||||
}
|
||||
int Mask_U = (int)objDataMask.size();
|
||||
int Mask_V = (int)objDataMask[0].size();
|
||||
int maxU = Mask_U-1; //2D图像的最大Col
|
||||
int maxV = Mask_V-1; //2D图像的最大Row
|
||||
|
||||
//生成图像与3d的对应表
|
||||
const int imgCols = maxU+1;
|
||||
@ -1826,24 +1842,75 @@ void wd_HRM_RotorCorePositioning(
|
||||
}
|
||||
}
|
||||
|
||||
int objNum = (int)objROIs.size();
|
||||
//ver_1.5.1:使用2D腌膜进行处理
|
||||
std::vector<SSG_ROIRect> objROIs;
|
||||
int objNum = 0;
|
||||
for (int m = 0; m < (int)objDataMask.size(); m++)
|
||||
{
|
||||
for (int n = 0; n < (int)objDataMask[m].size(); n++)
|
||||
{
|
||||
if (objNum < objDataMask[m][n].R)
|
||||
objNum = objDataMask[m][n].R;
|
||||
if (objNum < objDataMask[m][n].G)
|
||||
objNum = objDataMask[m][n].G;
|
||||
if (objNum < objDataMask[m][n].B)
|
||||
objNum = objDataMask[m][n].B;
|
||||
}
|
||||
}
|
||||
if (objNum > 0)
|
||||
{
|
||||
objROIs.resize(objNum+1);
|
||||
for (int m = 0; m < (int)objDataMask.size(); m++)
|
||||
{
|
||||
for (int n = 0; n < (int)objDataMask[m].size(); n++)
|
||||
{
|
||||
SWDColorRGB a_mask = objDataMask[m][n];
|
||||
if (a_mask.R > 0)
|
||||
{
|
||||
SSG_ROIRect a_roi = objROIs[a_mask.R];
|
||||
_updateROI(m, n, a_roi);
|
||||
objROIs[a_mask.R] = a_roi;
|
||||
}
|
||||
if (a_mask.G > 0)
|
||||
{
|
||||
SSG_ROIRect a_roi = objROIs[a_mask.G];
|
||||
_updateROI(m, n, a_roi);
|
||||
objROIs[a_mask.G] = a_roi;
|
||||
}
|
||||
if (a_mask.B > 0)
|
||||
{
|
||||
SSG_ROIRect a_roi = objROIs[a_mask.B];
|
||||
_updateROI(m, n, a_roi);
|
||||
objROIs[a_mask.B] = a_roi;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
objNum = (int)objROIs.size();
|
||||
std::vector<WD_workpieceInfo> allWorkpiece;
|
||||
for (int idx = 0; idx < objNum; idx++)
|
||||
for (int idx = 1; idx < objNum; idx++)
|
||||
{
|
||||
if (idx == 44)
|
||||
int kkk = 1;
|
||||
WD_objArea2D& obj_roi = objROIs[idx];
|
||||
double cx = (obj_roi.roi.left + obj_roi.roi.right) / 2;
|
||||
double cy = (obj_roi.roi.top + obj_roi.roi.bottom) / 2;
|
||||
double roi_R = cx - obj_roi.roi.left;
|
||||
double radius = roi_R * 1.414;
|
||||
SSG_ROIRect& obj_roi = objROIs[idx];
|
||||
int ex_w = (obj_roi.right - obj_roi.left) / 6;
|
||||
int ex_h = (obj_roi.bottom - obj_roi.top) / 6;
|
||||
double roi_R = ex_w < ex_h ? (double)ex_w : (double)ex_h;
|
||||
int L = obj_roi.left - ex_w;
|
||||
if (L < 0)
|
||||
L = 0;
|
||||
int R = obj_roi.right + ex_w;
|
||||
if (R > maxU)
|
||||
R = maxU;
|
||||
int T = obj_roi.top - ex_h;
|
||||
if (T < 0)
|
||||
T = 0;
|
||||
int B = obj_roi.bottom + ex_h;
|
||||
if (B > maxV)
|
||||
B = maxV;
|
||||
|
||||
int L = (int)(cx - radius);
|
||||
int R = (int)(cx + radius + 0.5);
|
||||
int T = (int)(cy - radius);
|
||||
int B = (int)(cy + radius + 0.5);
|
||||
int nCx = (int)cx;
|
||||
int nCy = (int)cy;
|
||||
int nCx = (obj_roi.left + obj_roi.right) / 2;
|
||||
int nCy = (obj_roi.top + obj_roi.bottom) / 2;
|
||||
|
||||
//统计ROI中的扫描线和PtIdx范围
|
||||
SVzNLRange roiLineIndice = { INT_MAX, 0 };
|
||||
@ -1919,11 +1986,12 @@ void wd_HRM_RotorCorePositioning(
|
||||
roiScanLines[roiLineIdx][roiPtIdx].nPointIdx = 0;
|
||||
roiScanLines[roiLineIdx][roiPtIdx].pt3D = scanLines[lineIdx][ptIdx].pt3D;
|
||||
|
||||
double dist = sqrt((x - nCx)* (x - nCx) + (y - nCy)* (y - nCy));
|
||||
if (dist <= (roi_R+2))
|
||||
SWDColorRGB a_mask = objDataMask[x][y];
|
||||
if( (a_mask.R == idx) || (a_mask.G == idx) || (a_mask.B == idx))
|
||||
dataRoiMask[roiLineIdx][roiPtIdx] = 1;
|
||||
|
||||
//搜索中心点
|
||||
double dist = sqrt((x - nCx) * (x - nCx) + (y - nCy) * (y - nCy));
|
||||
if (minDist < 0)
|
||||
{
|
||||
minDist = dist;
|
||||
@ -1955,7 +2023,7 @@ void wd_HRM_RotorCorePositioning(
|
||||
outsideEdgePtIndice,
|
||||
centerPtIndice);
|
||||
a_workpiece.imgCenter = { nCx, nCy };
|
||||
a_workpiece.id = idx + 1;
|
||||
a_workpiece.id = idx;
|
||||
//添加对隔板下部分可见被识别目标的过滤
|
||||
if ((spacerInfo.center.z > 1e-4)&& (a_workpiece.center.z > 1e-4)) //隔板存在
|
||||
{
|
||||
|
||||
@ -61,7 +61,8 @@ SG_APISHARED_EXPORT void wd_lineDataR(
|
||||
|
||||
SG_APISHARED_EXPORT void wd_HRM_RotorCorePositioning(
|
||||
std::vector< std::vector<SVzNLPositionD>>& scanLinesInput,
|
||||
std::vector<WD_objArea2D>& objROIs,
|
||||
std::vector<std::vector<SWDColorRGB>>& objDataMask, //和扫描线存储结构相同:按列存储
|
||||
//std::vector<WD_objArea2D>& objROIs,
|
||||
const SSG_planeCalibPara groundCalibPara,
|
||||
const SVzNLSizeD spacerParam, //隔板参数:长和宽
|
||||
const SWD_Cylinder workpieceParam, //圆柱形工件的标称半径和高度
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user