|
|
|
|
@ -1070,9 +1070,11 @@ int ImgCheckAnalysisy::CheckRun()
|
|
|
|
|
|
|
|
|
|
/* 检测支架偏移(bDetSupport 开关关闭时不做支架判定)
|
|
|
|
|
不使用参数绘制区域,结合两次定位的 mask 计算:
|
|
|
|
|
1、bigmask 最大连通域 = 产品区域 rp(近似矩形,四周可能有凸起)
|
|
|
|
|
1、产品边缘:优先复用把手提取对 bigmask 做的"四边抗凸起拟合"主体四边形
|
|
|
|
|
(CheckHandleByBigMask -> GetMaskProtrusions;边缘上的凸起(把手等)不会把边缘带偏),
|
|
|
|
|
拟合不可用/无效时回退 bigmask 最大连通域外接矩形 rp(近似矩形,四周可能有凸起)
|
|
|
|
|
2、smallmask 最大连通域 = 支架区域 rs(按定位裁剪区 m_outer_rroi 外接矩形映射回原图坐标)
|
|
|
|
|
3、按 edge_select 指定方向(left/right/up/down)计算 rs 中心到 rp 对应边缘的距离
|
|
|
|
|
3、按 edge_select 指定方向(left/right/up/down)计算 rs 中心到产品对应边缘的距离
|
|
|
|
|
4、计算值与标准值(x_standard/y_standard)做差取平均,平均差超过 offset(x_offset) → 偏移 */
|
|
|
|
|
{
|
|
|
|
|
Function_Support_Det &supportDet = m_pbaseCheckFunction->supportDet;
|
|
|
|
|
@ -1132,7 +1134,7 @@ int ImgCheckAnalysisy::CheckRun()
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// rp 边缘:产品最大连通域的外接矩形(含凸起)
|
|
|
|
|
// rp 边缘(拟合不可用时的回退):产品最大连通域的外接矩形(含凸起)
|
|
|
|
|
cv::Rect rpRect = cv::boundingRect(rpContour);
|
|
|
|
|
|
|
|
|
|
// rs 映射回原图坐标:smallmask 对应定位时裁剪的大轮廓区域(m_outer_rroi 外接矩形),按比例映射
|
|
|
|
|
@ -1146,18 +1148,87 @@ int ImgCheckAnalysisy::CheckRun()
|
|
|
|
|
cvRound(rsSmallRect.width * fx),
|
|
|
|
|
cvRound(rsSmallRect.height * fy));
|
|
|
|
|
|
|
|
|
|
// 3、rs 中心到 rp 上下左右边缘的距离
|
|
|
|
|
// 3、产品边缘:优先复用把手提取对 bigmask 做的"四边抗凸起拟合"主体四边形
|
|
|
|
|
// (CheckHandleByBigMask -> GetMaskProtrusions 输出):边缘上的凸起(把手等)不会把边缘带偏;
|
|
|
|
|
// 拟合不可用/无效时回退到产品最大连通域外接矩形 rpRect(含凸起)
|
|
|
|
|
bool bFitQuad = false; // 是否用上了拟合主体四边形
|
|
|
|
|
float fDL = 0, fDR = 0, fDT = 0, fDB = 0; // 支架中心到产品左/右/上/下边缘的距离(原图像素,后乘缩放系数)
|
|
|
|
|
cv::Point2f ptEdgeArr[4]; // 连线端点(边缘线上):0 left 1 right 2 up 3 down
|
|
|
|
|
cv::Point2f ptSegAArr[4]; // 边缘线段端点A
|
|
|
|
|
cv::Point2f ptSegBArr[4]; // 边缘线段端点B
|
|
|
|
|
|
|
|
|
|
float fCx = rsRect.x + rsRect.width * 0.5f;
|
|
|
|
|
float fCy = rsRect.y + rsRect.height * 0.5f;
|
|
|
|
|
float fDL = fCx - rpRect.x; // 到左边缘
|
|
|
|
|
float fDR = (rpRect.x + rpRect.width) - fCx; // 到右边缘
|
|
|
|
|
float fDT = fCy - rpRect.y; // 到上边缘
|
|
|
|
|
float fDB = (rpRect.y + rpRect.height) - fCy; // 到下边缘
|
|
|
|
|
|
|
|
|
|
if (m_HandleBodyQuad.size() == 4)
|
|
|
|
|
{
|
|
|
|
|
// 四边形角点顺序:左上/右上/右下/左下;左/右边 x=k*y+b、上/下边 y=k*x+b(与 GetMaskProtrusions 约定一致);
|
|
|
|
|
// 边长过小说明拟合退化,不用
|
|
|
|
|
const cv::Point2f &ptTL = m_HandleBodyQuad[0];
|
|
|
|
|
const cv::Point2f &ptTR = m_HandleBodyQuad[1];
|
|
|
|
|
const cv::Point2f &ptBR = m_HandleBodyQuad[2];
|
|
|
|
|
const cv::Point2f &ptBL = m_HandleBodyQuad[3];
|
|
|
|
|
if (fabs(ptBL.y - ptTL.y) > 2.0f && fabs(ptBR.y - ptTR.y) > 2.0f &&
|
|
|
|
|
fabs(ptTR.x - ptTL.x) > 2.0f && fabs(ptBR.x - ptBL.x) > 2.0f)
|
|
|
|
|
{
|
|
|
|
|
float fKL = (ptBL.x - ptTL.x) / (ptBL.y - ptTL.y); // 左边 x = k*y + b
|
|
|
|
|
float fBL = ptTL.x - fKL * ptTL.y;
|
|
|
|
|
float fKR = (ptBR.x - ptTR.x) / (ptBR.y - ptTR.y); // 右边 x = k*y + b
|
|
|
|
|
float fBR = ptTR.x - fKR * ptTR.y;
|
|
|
|
|
float fKT = (ptTR.y - ptTL.y) / (ptTR.x - ptTL.x); // 上边 y = k*x + b
|
|
|
|
|
float fBT = ptTL.y - fKT * ptTL.x;
|
|
|
|
|
float fKB = (ptBR.y - ptBL.y) / (ptBR.x - ptBL.x); // 下边 y = k*x + b
|
|
|
|
|
float fBB = ptBL.y - fKB * ptBL.x;
|
|
|
|
|
// 连线端点:取边缘线在支架中心行/列上的点;长度即中心到边缘的水平/垂直距离
|
|
|
|
|
float fXEdgeL = fKL * fCy + fBL;
|
|
|
|
|
float fXEdgeR = fKR * fCy + fBR;
|
|
|
|
|
float fYEdgeT = fKT * fCx + fBT;
|
|
|
|
|
float fYEdgeB = fKB * fCx + fBB;
|
|
|
|
|
fDL = fCx - fXEdgeL;
|
|
|
|
|
fDR = fXEdgeR - fCx;
|
|
|
|
|
fDT = fCy - fYEdgeT;
|
|
|
|
|
fDB = fYEdgeB - fCy;
|
|
|
|
|
// 拟合有效性:支架中心应位于四条拟合边内侧(四个方向距离均为正),否则放弃拟合
|
|
|
|
|
if (fDL > 0 && fDR > 0 && fDT > 0 && fDB > 0)
|
|
|
|
|
{
|
|
|
|
|
ptEdgeArr[0] = cv::Point2f(fXEdgeL, fCy);
|
|
|
|
|
ptEdgeArr[1] = cv::Point2f(fXEdgeR, fCy);
|
|
|
|
|
ptEdgeArr[2] = cv::Point2f(fCx, fYEdgeT);
|
|
|
|
|
ptEdgeArr[3] = cv::Point2f(fCx, fYEdgeB);
|
|
|
|
|
ptSegAArr[0] = ptTL; ptSegBArr[0] = ptBL; // left:整条拟合左边
|
|
|
|
|
ptSegAArr[1] = ptTR; ptSegBArr[1] = ptBR; // right:整条拟合右边
|
|
|
|
|
ptSegAArr[2] = ptTL; ptSegBArr[2] = ptTR; // up:整条拟合上边
|
|
|
|
|
ptSegAArr[3] = ptBL; ptSegBArr[3] = ptBR; // down:整条拟合下边
|
|
|
|
|
bFitQuad = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!bFitQuad)
|
|
|
|
|
{
|
|
|
|
|
// 回退:产品区域外接矩形(含凸起)的四条边
|
|
|
|
|
fDL = fCx - rpRect.x;
|
|
|
|
|
fDR = (rpRect.x + rpRect.width) - fCx;
|
|
|
|
|
fDT = fCy - rpRect.y;
|
|
|
|
|
fDB = (rpRect.y + rpRect.height) - fCy;
|
|
|
|
|
ptEdgeArr[0] = cv::Point2f((float)rpRect.x, fCy);
|
|
|
|
|
ptEdgeArr[1] = cv::Point2f((float)(rpRect.x + rpRect.width), fCy);
|
|
|
|
|
ptEdgeArr[2] = cv::Point2f(fCx, (float)rpRect.y);
|
|
|
|
|
ptEdgeArr[3] = cv::Point2f(fCx, (float)(rpRect.y + rpRect.height));
|
|
|
|
|
ptSegAArr[0] = cv::Point2f((float)rpRect.x, (float)rpRect.y);
|
|
|
|
|
ptSegBArr[0] = cv::Point2f((float)rpRect.x, (float)(rpRect.y + rpRect.height));
|
|
|
|
|
ptSegAArr[1] = cv::Point2f((float)(rpRect.x + rpRect.width), (float)rpRect.y);
|
|
|
|
|
ptSegBArr[1] = cv::Point2f((float)(rpRect.x + rpRect.width), (float)(rpRect.y + rpRect.height));
|
|
|
|
|
ptSegAArr[2] = cv::Point2f((float)rpRect.x, (float)rpRect.y);
|
|
|
|
|
ptSegBArr[2] = cv::Point2f((float)(rpRect.x + rpRect.width), (float)rpRect.y);
|
|
|
|
|
ptSegAArr[3] = cv::Point2f((float)rpRect.x, (float)(rpRect.y + rpRect.height));
|
|
|
|
|
ptSegBArr[3] = cv::Point2f((float)(rpRect.x + rpRect.width), (float)(rpRect.y + rpRect.height));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 像素 -> mm
|
|
|
|
|
fDL *= m_fImgage_Scale_X;
|
|
|
|
|
fDR *= m_fImgage_Scale_X;
|
|
|
|
|
fDT *= m_fImgage_Scale_Y;
|
|
|
|
|
fDB *= m_fImgage_Scale_Y;
|
|
|
|
|
float fDistArr[4] = {fDL, fDR, fDT, fDB}; // 顺序固定:0 left 1 right 2 up 3 down
|
|
|
|
|
|
|
|
|
|
// 4、按 edge_select 指定方向(left/right/up/down)取计算值,与标准值做差取平均,平均差超过 offset → 偏移
|
|
|
|
|
// left/right 用 x_standard,up/down 用 y_standard;offset 用 x_offset
|
|
|
|
|
@ -1169,26 +1240,26 @@ int ImgCheckAnalysisy::CheckRun()
|
|
|
|
|
for (size_t iselect = 0; iselect < supportDet.edge_select.size(); iselect++)
|
|
|
|
|
{
|
|
|
|
|
const std::string &strEdge = supportDet.edge_select[iselect];
|
|
|
|
|
float fDist = 0;
|
|
|
|
|
int gi = -1; // 方向索引:0 left 1 right 2 up 3 down
|
|
|
|
|
float fStandard = 0;
|
|
|
|
|
if (strEdge == "left")
|
|
|
|
|
{
|
|
|
|
|
fDist = fDL;
|
|
|
|
|
gi = 0;
|
|
|
|
|
fStandard = supportDet.x_standard;
|
|
|
|
|
}
|
|
|
|
|
else if (strEdge == "right")
|
|
|
|
|
{
|
|
|
|
|
fDist = fDR;
|
|
|
|
|
gi = 1;
|
|
|
|
|
fStandard = supportDet.x_standard;
|
|
|
|
|
}
|
|
|
|
|
else if (strEdge == "up")
|
|
|
|
|
{
|
|
|
|
|
fDist = fDT;
|
|
|
|
|
gi = 2;
|
|
|
|
|
fStandard = supportDet.y_standard;
|
|
|
|
|
}
|
|
|
|
|
else if (strEdge == "down")
|
|
|
|
|
{
|
|
|
|
|
fDist = fDB;
|
|
|
|
|
gi = 3;
|
|
|
|
|
fStandard = supportDet.y_standard;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
@ -1196,6 +1267,7 @@ int ImgCheckAnalysisy::CheckRun()
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float fDist = fDistArr[gi];
|
|
|
|
|
float fDiff = fabs(fDist - fStandard);
|
|
|
|
|
fSumDiff += fDiff;
|
|
|
|
|
nDiffNum++;
|
|
|
|
|
@ -1206,6 +1278,9 @@ int ImgCheckAnalysisy::CheckRun()
|
|
|
|
|
edgeDraw.fDist = fDist;
|
|
|
|
|
edgeDraw.fStandard = fStandard;
|
|
|
|
|
edgeDraw.bExceed = (fDiff > supportDet.x_offset);
|
|
|
|
|
edgeDraw.ptEdge = ptEdgeArr[gi];
|
|
|
|
|
edgeDraw.ptEdgeA = ptSegAArr[gi];
|
|
|
|
|
edgeDraw.ptEdgeB = ptSegBArr[gi];
|
|
|
|
|
m_SupportDrawInfo.edgeList.push_back(edgeDraw);
|
|
|
|
|
}
|
|
|
|
|
sprintf(strTmp, "%s(%.1f/%.1f) ", strEdge.c_str(), fDist, fStandard);
|
|
|
|
|
@ -1225,10 +1300,10 @@ int ImgCheckAnalysisy::CheckRun()
|
|
|
|
|
m_SupportDrawInfo.ptCenter = cv::Point2f(fCx, fCy);
|
|
|
|
|
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_0, "支架检测",
|
|
|
|
|
"rp [%d %d %d %d] rs [%d %d %d %d] scale (%.4f %.4f) center (%.1f %.1f) dL %.1f dR %.1f dT %.1f dB %.1f | select %s diff %s avgDiff %.1f limit %.1f ng %d",
|
|
|
|
|
"rp [%d %d %d %d] rs [%d %d %d %d] scale (%.4f %.4f) center (%.1f %.1f) edge %s quad %ld dL %.1f dR %.1f dT %.1f dB %.1f | select %s diff %s avgDiff %.1f limit %.1f ng %d",
|
|
|
|
|
rpRect.x, rpRect.y, rpRect.width, rpRect.height,
|
|
|
|
|
rsRect.x, rsRect.y, rsRect.width, rsRect.height,
|
|
|
|
|
fx, fy, fCx, fCy, fDL, fDR, fDT, fDB,
|
|
|
|
|
fx, fy, fCx, fCy, bFitQuad ? "fitquad" : "rpbox", (long)m_HandleBodyQuad.size(), fDL, fDR, fDT, fDB,
|
|
|
|
|
strSelect.c_str(), strDiff.c_str(), fAvgDiff, supportDet.x_offset, bOffset);
|
|
|
|
|
|
|
|
|
|
if (bOffset)
|
|
|
|
|
@ -2618,56 +2693,47 @@ int ImgCheckAnalysisy::DrawResult_Step_1()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 支架偏移检测绘制(受参数 bDrawSupport 控制,默认关闭):支架中心十字(绿=正常/红=偏移NG)+ 支架到边缘的距离(绿=正常/红=超标准)
|
|
|
|
|
// 支架偏移检测绘制(受参数 bDrawSupport 控制,默认关闭):
|
|
|
|
|
// 支架中心十字(绿=正常/红=偏移NG)+ 各方向"所计算的产品边缘"线段(抗凸起拟合直边,见 CheckRun 支架块)
|
|
|
|
|
// + 支架中心到该边缘的连线(连线长度=支架中心到所计算边缘的距离;绿=正常/红=超标准)+ 实测/标准(mm)文字
|
|
|
|
|
if (m_SupportDrawInfo.bValid && m_pbaseCheckFunction->supportDet.bDrawSupport && !m_CheckResult_shareP->resultimg.empty())
|
|
|
|
|
{
|
|
|
|
|
// 支架中心:原图坐标 -> 检测图(裁剪) -> 结果图
|
|
|
|
|
cv::Point2f detPt = MatAffinePoint(m_matSrc2Det, m_SupportDrawInfo.ptCenter);
|
|
|
|
|
cv::Point pCenter(cvRound(detPt.x * fs_resize_x), cvRound(detPt.y * fs_resize_y));
|
|
|
|
|
// 原图坐标 -> 检测图(裁剪) -> 结果图
|
|
|
|
|
auto srcToResult = [&](const cv::Point2f &pt) -> cv::Point {
|
|
|
|
|
cv::Point2f detPt = MatAffinePoint(m_matSrc2Det, pt);
|
|
|
|
|
return cv::Point(cvRound(detPt.x * fs_resize_x), cvRound(detPt.y * fs_resize_y));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 支架中心十字:NG 红色 / 正常绿色
|
|
|
|
|
cv::Point pCenter = srcToResult(m_SupportDrawInfo.ptCenter);
|
|
|
|
|
cv::Scalar colorCross = m_SupportDrawInfo.bOffset ? cv::Scalar(0, 0, 255) : cv::Scalar(0, 255, 0);
|
|
|
|
|
colorCross = CheckUtil::GetDrawColor(m_CheckResult_shareP->resultimg, colorCross);
|
|
|
|
|
const int nCrossLen = 40; // 结果图上十字半长(px)
|
|
|
|
|
cv::line(m_CheckResult_shareP->resultimg, cv::Point(pCenter.x - nCrossLen, pCenter.y), cv::Point(pCenter.x + nCrossLen, pCenter.y), colorCross, 2);
|
|
|
|
|
cv::line(m_CheckResult_shareP->resultimg, cv::Point(pCenter.x, pCenter.y - nCrossLen), cv::Point(pCenter.x, pCenter.y + nCrossLen), colorCross, 2);
|
|
|
|
|
|
|
|
|
|
// 支架到边缘的距离:中心 -> 产品区域对应边缘连线 + 实测/标准(像素)文字
|
|
|
|
|
// 各方向:所计算边缘线段(抗凸起拟合直边/回退外接矩形边) + 中心到边缘点的连线(长度=点到所计算边缘) + 实测/标准文字
|
|
|
|
|
// 几何(边缘点/线段两端点)由 CheckRun 支架块算好存入 edgeDraw,此处只做坐标映射与绘制
|
|
|
|
|
char strTxt[64];
|
|
|
|
|
for (size_t i = 0; i < m_SupportDrawInfo.edgeList.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
const Support_Draw_Info_::Edge_Draw_ &edgeDraw = m_SupportDrawInfo.edgeList[i];
|
|
|
|
|
cv::Point2f ptEdge = m_SupportDrawInfo.ptCenter;
|
|
|
|
|
if (edgeDraw.strEdge == "left")
|
|
|
|
|
{
|
|
|
|
|
ptEdge.x = (float)m_SupportDrawInfo.rpRect.x;
|
|
|
|
|
}
|
|
|
|
|
else if (edgeDraw.strEdge == "right")
|
|
|
|
|
{
|
|
|
|
|
ptEdge.x = (float)(m_SupportDrawInfo.rpRect.x + m_SupportDrawInfo.rpRect.width);
|
|
|
|
|
}
|
|
|
|
|
else if (edgeDraw.strEdge == "up")
|
|
|
|
|
{
|
|
|
|
|
ptEdge.y = (float)m_SupportDrawInfo.rpRect.y;
|
|
|
|
|
}
|
|
|
|
|
else if (edgeDraw.strEdge == "down")
|
|
|
|
|
{
|
|
|
|
|
ptEdge.y = (float)(m_SupportDrawInfo.rpRect.y + m_SupportDrawInfo.rpRect.height);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cv::Point2f detEdge = MatAffinePoint(m_matSrc2Det, ptEdge);
|
|
|
|
|
cv::Point pEdge(cvRound(detEdge.x * fs_resize_x), cvRound(detEdge.y * fs_resize_y));
|
|
|
|
|
cv::Point pEdge = srcToResult(edgeDraw.ptEdge);
|
|
|
|
|
cv::Point pEdgeA = srcToResult(edgeDraw.ptEdgeA);
|
|
|
|
|
cv::Point pEdgeB = srcToResult(edgeDraw.ptEdgeB);
|
|
|
|
|
|
|
|
|
|
// 超标准红色 / 正常绿色
|
|
|
|
|
cv::Scalar colorEdge = edgeDraw.bExceed ? cv::Scalar(0, 0, 255) : cv::Scalar(0, 255, 0);
|
|
|
|
|
colorEdge = CheckUtil::GetDrawColor(m_CheckResult_shareP->resultimg, colorEdge);
|
|
|
|
|
|
|
|
|
|
// 1、所计算边缘线段:标出参与计算的产品边缘(细线;抗凸起拟合直边/回退边)
|
|
|
|
|
cv::line(m_CheckResult_shareP->resultimg, pEdgeA, pEdgeB, colorEdge, 1);
|
|
|
|
|
|
|
|
|
|
// 2、中心 -> 边缘点连线:长度即支架中心到所计算边缘的距离
|
|
|
|
|
cv::line(m_CheckResult_shareP->resultimg, pCenter, pEdge, colorEdge, 2);
|
|
|
|
|
|
|
|
|
|
// 距离文字:实测/标准(原图像素)
|
|
|
|
|
// 3、距离文字:实测/标准(mm)
|
|
|
|
|
snprintf(strTxt, sizeof(strTxt), "%s %.0f/%.0f", edgeDraw.strEdge.c_str(), edgeDraw.fDist, edgeDraw.fStandard);
|
|
|
|
|
cv::putText(m_CheckResult_shareP->resultimg, strTxt,
|
|
|
|
|
cv::Point((pCenter.x + pEdge.x) / 2 + 6, (pCenter.y + pEdge.y) / 2 - 6),
|
|
|
|
|
@ -2864,6 +2930,7 @@ int ImgCheckAnalysisy::AI_Edge(const cv::Mat &img, cv::RotatedRect &outerRoi, cv
|
|
|
|
|
// 3、凸起本身不算 NG,只有"某个把手区域附近找不到匹配的凸起"才算把手缺失(NG 由 CheckRun 上报)
|
|
|
|
|
// 4、-s(存过程图)时输出 {通道}_handle_det.jpg:绿色四边形=拟合主体、红框=凸起(带编号/角/深度)、
|
|
|
|
|
// 蓝框=参数把手区域、绿框=匹配到的把手,便于从图像观察问题
|
|
|
|
|
// 5、拟合出的主体四边形存 m_HandleBodyQuad:支架偏移检测复用其四边(抗凸起)做测距与绘制
|
|
|
|
|
int ImgCheckAnalysisy::CheckHandleByBigMask(const cv::Mat &bigmask)
|
|
|
|
|
{
|
|
|
|
|
m_bHandleDetSucc = false;
|
|
|
|
|
@ -2871,6 +2938,7 @@ int ImgCheckAnalysisy::CheckHandleByBigMask(const cv::Mat &bigmask)
|
|
|
|
|
m_bHandleExpect = false;
|
|
|
|
|
m_HandleProtrusionList.clear();
|
|
|
|
|
m_HandleRegionResultList.clear();
|
|
|
|
|
m_HandleBodyQuad.clear();
|
|
|
|
|
|
|
|
|
|
if (bigmask.empty())
|
|
|
|
|
{
|
|
|
|
|
@ -2910,8 +2978,8 @@ int ImgCheckAnalysisy::CheckHandleByBigMask(const cv::Mat &bigmask)
|
|
|
|
|
nEdgeMargin = (int)(fEdgeMarginCoef * nStep + 0.5f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
std::vector<cv::Point2f> vecBodyQuad; // 拟合出的主体四边形(仅 -s 存图观察用)
|
|
|
|
|
int re = CheckUtil::GetMaskProtrusions(bigmask, m_HandleProtrusionList, nMinDepth, nMinArea, &vecBodyQuad, nEdgeMargin);
|
|
|
|
|
// m_HandleBodyQuad:拟合出的主体四边形(左上/右上/右下/左下);-s 存图观察用,支架偏移检测复用其四边做抗凸起测距/绘制
|
|
|
|
|
int re = CheckUtil::GetMaskProtrusions(bigmask, m_HandleProtrusionList, nMinDepth, nMinArea, &m_HandleBodyQuad, nEdgeMargin);
|
|
|
|
|
if (re != 0)
|
|
|
|
|
{
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "Handle", "GetMaskProtrusions error %d", re);
|
|
|
|
|
@ -2992,12 +3060,12 @@ int ImgCheckAnalysisy::CheckHandleByBigMask(const cv::Mat &bigmask)
|
|
|
|
|
show = bigmask.clone();
|
|
|
|
|
}
|
|
|
|
|
// 主体四边形(拟合出的四条边缘)
|
|
|
|
|
if (vecBodyQuad.size() == 4)
|
|
|
|
|
if (m_HandleBodyQuad.size() == 4)
|
|
|
|
|
{
|
|
|
|
|
std::vector<cv::Point> vecQuad;
|
|
|
|
|
for (size_t i = 0; i < vecBodyQuad.size(); i++)
|
|
|
|
|
for (size_t i = 0; i < m_HandleBodyQuad.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
vecQuad.push_back(cv::Point(cvRound(vecBodyQuad[i].x), cvRound(vecBodyQuad[i].y)));
|
|
|
|
|
vecQuad.push_back(cv::Point(cvRound(m_HandleBodyQuad[i].x), cvRound(m_HandleBodyQuad[i].y)));
|
|
|
|
|
}
|
|
|
|
|
cv::polylines(show, vecQuad, true, cv::Scalar(0, 255, 0), 8);
|
|
|
|
|
}
|
|
|
|
|
|