|
|
|
@ -881,17 +881,36 @@ int ImgCheckAnalysisy::CheckRun()
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_0, "2、pre detect", "-------------------------AI_Edge------------succ---time %ld----\n", time_edge_e - time_edge_s);
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_0, "2、pre detect", "-------------------------AI_Edge------------succ---time %ld----\n", time_edge_e - time_edge_s);
|
|
|
|
|
|
|
|
|
|
|
|
m_Crop_Roi_paramImg = m_CutRoi;
|
|
|
|
m_Crop_Roi_paramImg = m_CutRoi;
|
|
|
|
// 计算产品左上角在检测图(detImg)中的偏移(间隙),用于缺陷坐标转换到产品坐标系
|
|
|
|
// 产品坐标换算所需的参考几何:
|
|
|
|
|
|
|
|
// 1) ptRoiOffsetInDet:产品左上角顶点在 detImg 中的偏移(轴对齐,仅作退化路径)
|
|
|
|
|
|
|
|
// 2) vProductQuadInDet:产品旋转外接矩形四角在 detImg 中的坐标(0左上 1右上 2左下 3右下),
|
|
|
|
|
|
|
|
// 用于「缺陷点到两边线段的距离」的抗倾斜产品坐标换算
|
|
|
|
if (m_bRotCurRoiValid)
|
|
|
|
if (m_bRotCurRoiValid)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// 取旋转矩形实际的左上角顶点(非轴对齐外接框 boundingRect,后者在带旋转角时会偏大)
|
|
|
|
// 取旋转矩形实际的左上角顶点(非轴对齐外接框 boundingRect,后者在带旋转角时会偏大)
|
|
|
|
std::vector<cv::Point2f> rroi_vertices = sort_vertices(m_rot_cur_roi);
|
|
|
|
std::vector<cv::Point2f> rroi_vertices = sort_vertices(m_rot_cur_roi);
|
|
|
|
m_pImageAllResult->ptRoiOffsetInDet.x = cvRound(rroi_vertices[0].x) - m_CutRoi.x;
|
|
|
|
m_pImageAllResult->ptRoiOffsetInDet.x = cvRound(rroi_vertices[0].x) - m_CutRoi.x;
|
|
|
|
m_pImageAllResult->ptRoiOffsetInDet.y = cvRound(rroi_vertices[0].y) - m_CutRoi.y;
|
|
|
|
m_pImageAllResult->ptRoiOffsetInDet.y = cvRound(rroi_vertices[0].y) - m_CutRoi.y;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m_pImageAllResult->vProductQuadInDet.clear();
|
|
|
|
|
|
|
|
m_pImageAllResult->vProductQuadInDet.reserve(4);
|
|
|
|
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// 原图坐标 -> detImg 坐标
|
|
|
|
|
|
|
|
m_pImageAllResult->vProductQuadInDet.push_back(
|
|
|
|
|
|
|
|
cv::Point2f(rroi_vertices[i].x - m_CutRoi.x, rroi_vertices[i].y - m_CutRoi.y));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "Convert",
|
|
|
|
|
|
|
|
"product quad in det [(%d,%d) (%d,%d) (%d,%d) (%d,%d)]",
|
|
|
|
|
|
|
|
cvRound(rroi_vertices[0].x - m_CutRoi.x), cvRound(rroi_vertices[0].y - m_CutRoi.y),
|
|
|
|
|
|
|
|
cvRound(rroi_vertices[1].x - m_CutRoi.x), cvRound(rroi_vertices[1].y - m_CutRoi.y),
|
|
|
|
|
|
|
|
cvRound(rroi_vertices[2].x - m_CutRoi.x), cvRound(rroi_vertices[2].y - m_CutRoi.y),
|
|
|
|
|
|
|
|
cvRound(rroi_vertices[3].x - m_CutRoi.x), cvRound(rroi_vertices[3].y - m_CutRoi.y));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
m_pImageAllResult->ptRoiOffsetInDet = cv::Point(0, 0);
|
|
|
|
m_pImageAllResult->ptRoiOffsetInDet = cv::Point(0, 0);
|
|
|
|
|
|
|
|
m_pImageAllResult->vProductQuadInDet.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_pImageAllResult->pDetResult->CutRoi = m_CutRoi;
|
|
|
|
m_pImageAllResult->pDetResult->CutRoi = m_CutRoi;
|
|
|
|
m_pImageAllResult->pDetResult->Param_CropRoi = m_Crop_Roi_paramImg;
|
|
|
|
m_pImageAllResult->pDetResult->Param_CropRoi = m_Crop_Roi_paramImg;
|
|
|
|
@ -2512,6 +2531,35 @@ int ImgCheckAnalysisy::UpdateImgageScale()
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 缺陷框(detImg 坐标) -> 产品坐标
|
|
|
|
|
|
|
|
// 旧实现:roi = roiDet - 产品左上角顶点,只做了轴对齐平移,产品倾斜时同一物理位置的
|
|
|
|
|
|
|
|
// 坐标会随倾斜角漂移(沿产品长/宽方向产生 offset*sin(θ) 量级的误差)。
|
|
|
|
|
|
|
|
// 新实现:缺陷中心点到旋转矩形左边线段的垂距作为 x,到顶边线段的垂距作为 y,
|
|
|
|
|
|
|
|
// 任意倾斜角下同一物理位置得到相同坐标;再用中心反推产品坐标系下的框左上角,
|
|
|
|
|
|
|
|
// 保持 roi 原有的「框左上角 + 框尺寸」语义。roiDet 保留 detImg 坐标供内部裁剪使用。
|
|
|
|
|
|
|
|
int ImgCheckAnalysisy::ConvertDetRoiToProduct(QX_ERROR_INFO_ &qxerror)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// 1) 记录 detImg 坐标下的缺陷框(小图裁剪等内部用途,不受倾斜影响)
|
|
|
|
|
|
|
|
qxerror.roiDet = qxerror.roi;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (m_pImageAllResult == nullptr)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 2) 缺陷中心 -> 产品坐标(点到左边/顶边线段的垂距)
|
|
|
|
|
|
|
|
const cv::Point2f pcDet(qxerror.roiDet.x + qxerror.roiDet.width * 0.5f,
|
|
|
|
|
|
|
|
qxerror.roiDet.y + qxerror.roiDet.height * 0.5f);
|
|
|
|
|
|
|
|
const cv::Point2f pcProduct = m_pImageAllResult->DetPointToProductCoord(pcDet);
|
|
|
|
|
|
|
|
qxerror.ptProduct = pcProduct;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 3) 用中心反推框左上角
|
|
|
|
|
|
|
|
qxerror.roi.x = cvRound(pcProduct.x - qxerror.roiDet.width * 0.5f);
|
|
|
|
|
|
|
|
qxerror.roi.y = cvRound(pcProduct.y - qxerror.roiDet.height * 0.5f);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int ImgCheckAnalysisy::Edge_Qx_Det(const cv::Mat &img)
|
|
|
|
int ImgCheckAnalysisy::Edge_Qx_Det(const cv::Mat &img)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
@ -2603,12 +2651,8 @@ int ImgCheckAnalysisy::Edge_Qx_Det(const cv::Mat &img)
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// 缺陷坐标转换到产品坐标系:减去裁剪框与产品左上角的间隙
|
|
|
|
// 缺陷坐标转换到产品坐标系(点到左边/顶边线段的垂距,抗倾斜)
|
|
|
|
if (m_bRotCurRoiValid)
|
|
|
|
ConvertDetRoiToProduct(temerror);
|
|
|
|
{
|
|
|
|
|
|
|
|
temerror.roi.x -= m_pImageAllResult->ptRoiOffsetInDet.x;
|
|
|
|
|
|
|
|
temerror.roi.y -= m_pImageAllResult->ptRoiOffsetInDet.y;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
m_pDetResult->pQx_ErrorList->push_back(temerror);
|
|
|
|
m_pDetResult->pQx_ErrorList->push_back(temerror);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -2681,12 +2725,8 @@ int ImgCheckAnalysisy::BLobToDetResult()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QX_ERROR_INFO_ temerror;
|
|
|
|
QX_ERROR_INFO_ temerror;
|
|
|
|
temerror.roi = roi;
|
|
|
|
temerror.roi = roi;
|
|
|
|
// 缺陷坐标转换到产品坐标系:减去裁剪框与产品左上角的间隙
|
|
|
|
// 缺陷坐标转换到产品坐标系(点到左边/顶边线段的垂距,抗倾斜)
|
|
|
|
if (m_bRotCurRoiValid)
|
|
|
|
ConvertDetRoiToProduct(temerror);
|
|
|
|
{
|
|
|
|
|
|
|
|
temerror.roi.x -= m_pImageAllResult->ptRoiOffsetInDet.x;
|
|
|
|
|
|
|
|
temerror.roi.y -= m_pImageAllResult->ptRoiOffsetInDet.y;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
temerror.Idx = m_pDetResult->pQx_ErrorList->size();
|
|
|
|
temerror.Idx = m_pDetResult->pQx_ErrorList->size();
|
|
|
|
temerror.area = blobs.blobTab[i].area;
|
|
|
|
temerror.area = blobs.blobTab[i].area;
|
|
|
|
temerror.JudgArea = JudgArea;
|
|
|
|
temerror.JudgArea = JudgArea;
|
|
|
|
|