#include "stdafx.h" #include "KeyDistDotProcess.h" #include "VisionRecipe.h" #include "VisionBufferPro.h" #include "FileRecipe.h" #include "SoftVisionApp.h" CKeyDistDotProcess::CKeyDistDotProcess() { /* code */ m_eDir = DIMENSION_NONE; m_id = 0; m_nStdDist = 0; m_nUse = 0; m_strName.Format(_T("P%d"), m_id); m_poseType = 0; m_keyPoseX = 0; m_keyPoseY = 0; m_nPosX = 0; m_nPosY = 0; m_nEndThres = 0; // m_nLineWidth = 200; m_nInc = 0; m_nMin = 0; m_nMax = 0; m_nRoiSize = 100; m_distResult = 0.0f; } CKeyDistDotProcess::CKeyDistDotProcess(DimensionDir eDir, int id) { /* code */ m_eDir = eDir; m_id = id; m_nUse = 0; switch (eDir) { case GLOBAL_DEFINE::DIMENSION_A: m_strName.Format(_T("TopA_D%d"), m_id); break; case GLOBAL_DEFINE::DIMENSION_B: m_strName.Format(_T("TopB_D%d"), m_id); break; case GLOBAL_DEFINE::DIMENSION_C: m_strName.Format(_T("TopC_D%d"), m_id); break; case GLOBAL_DEFINE::DIMENSION_D: m_strName.Format(_T("TopD_D%d"), m_id); break; case GLOBAL_DEFINE::DIMENSION_A_DN: m_strName.Format(_T("BotA_D%d"), m_id); break; case GLOBAL_DEFINE::DIMENSION_B_DN: m_strName.Format(_T("BotB_D%d"), m_id); break; case GLOBAL_DEFINE::DIMENSION_C_DN: m_strName.Format(_T("BotC_D%d"), m_id); break; case GLOBAL_DEFINE::DIMENSION_D_DN: m_strName.Format(_T("BotD_D%d"), m_id); break; case GLOBAL_DEFINE::DIMENSION_NONE: m_strName.Format(_T("P_D%d"), m_id); break; default: m_strName.Format(_T("P_D%d"), m_id); break; } m_poseType = 0; m_keyPoseX = 0; m_keyPoseY = 0; m_nPosX = 0; m_nPosY = 0; m_nEndThres = 0; // m_nLineWidth = 200; m_nStdDist = 0; m_nInc = 0; m_nMin = 0; m_nMax = 0; m_nRoiSize = 100; m_distResult = 0.0f; } CKeyDistDotProcess::~CKeyDistDotProcess() { /* code */ } int CKeyDistDotProcess::Execute(DimensionDir eDir, Point2I offset) { /* code */ m_nNgInfo.clear(); m_ptNearResult.x = 0.0f; m_ptNearResult.y = 0.0f; m_ptMeasureResult.x = 0.0f; m_ptMeasureResult.y = 0.0f; if (1 != m_nUse) return 0; if (0 == m_keyPoseY && 0 == m_keyPoseX) return 0; if (0 == m_nPosX && 0 == m_nPosY) return 0; //1. »ñÈ¡½âÊÍ¶È getMmvsp(eDir); //2. ²éÕÒ½á¹û if (!findEndPoint(eDir)) return -1; //3. ½á¹ûÅÐ¶Ï judgeResult(); return 0; } bool CKeyDistDotProcess::getImageROI(HalconCpp::HObject &hImage, Point2I &result) { /* code */ // ¶¨ÒåÁ½¸övector£¬·Ö±ð´æ´¢±ê×¼µãºÍʵ¼ÊµãµÄ×ø±ê std::vector vStdPoint, vRealPoint; // ¼ÆËã±ê×¼µãÓëʵ¼ÊµãÖ®¼äµÄ¾àÀë double dx = m_locPointResult.x - m_ptMeasureResult.x; double dy = m_locPointResult.y - m_ptMeasureResult.y; double dist = sqrt(dx * dx + dy * dy); // ´´½¨Ò»¸öposeµã£¬ÓÃÓÚ´æ´¢±ê×¼µã Point2D pose; pose.x = m_nRoiSize + 10; //³ß´ç´óС 2 * m_nRoiSize + 20 // 110; pose.y = 40; vStdPoint.push_back(pose); // ½«±ê×¼µãÑØ×žàÀëÒÆ¶¯ pose.x = m_nRoiSize + 10 + dist;//110.0 + dist; vStdPoint.push_back(pose); // ½«Êµ¼Êµã´æÈëvRealPoint pose.x = m_locPointResult.x; pose.y = m_locPointResult.y; vRealPoint.push_back(pose); vRealPoint.push_back(m_ptMeasureResult); // ½«vStdPointºÍvRealPointת»»Îª·ÂÉ侨Õó ParaAffine2D affine = ClsVision::VectorToSimilarity(vStdPoint, vRealPoint); //4¸öµã // ÉèÖÃxºÍyµÄֵΪ0 pose.x = 0.0; pose.y = 0.0; // ½«pose×ø±êת»»Îªpoint×ø±ê Point2D point = ClsVision::CoordinateTransform(pose, affine); // ½«point×ø±êת»»ÎªÕûÊý int x1 = (int)(point.x); int y1 = (int)(point.y); int x2 = (int)(point.x); int y2 = (int)(point.y); // ÉèÖÃxºÍyµÄֵΪ0 pose.x = 0.0; pose.y = 79.0; // ½«pose×ø±êת»»Îªpoint×ø±ê point = ClsVision::CoordinateTransform(pose, affine); // Èç¹ûx1´óÓÚpoint.x£¬Ôò½«x1ÉèÖÃΪpoint.x if (x1 > point.x) x1 = (int)(point.x); // Èç¹ûy1´óÓÚpoint.y£¬Ôò½«y1ÉèÖÃΪpoint.y if (y1 > point.y) y1 = (int)(point.y); // Èç¹ûx2СÓÚpoint.x£¬Ôò½«x2ÉèÖÃΪpoint.x if (x2 < point.x) x2 = (int)(point.x); // Èç¹ûy2СÓÚpoint.y£¬Ôò½«y2ÉèÖÃΪpoint.y if (y2 < point.y) y2 = (int)(point.y); // ÉèÖÃxºÍyµÄֵΪ219.0 pose.x = 2 * (m_nRoiSize + 10) - 1; //219.0; pose.y = 79.0; // ½«pose×ø±êת»»Îªpoint×ø±ê point = ClsVision::CoordinateTransform(pose, affine); // Èç¹ûx1´óÓÚpoint.x£¬Ôò½«x1ÉèÖÃΪpoint.x if (x1 > point.x) x1 = (int)(point.x); // Èç¹ûy1´óÓÚpoint.y£¬Ôò½«y1ÉèÖÃΪpoint.y if (y1 > point.y) y1 = (int)(point.y); // Èç¹ûx2СÓÚpoint.x£¬Ôò½«x2ÉèÖÃΪpoint.x if (x2 < point.x) x2 = (int)(point.x); // Èç¹ûy2СÓÚpoint.y£¬Ôò½«y2ÉèÖÃΪpoint.y if (y2 < point.y) y2 = (int)(point.y); // ÉèÖÃxºÍyµÄֵΪ219.0 pose.x = 2 * (m_nRoiSize + 10) - 1; //219.0; pose.y = 0.0; // ½«pose×ø±êת»»Îªpoint×ø±ê point = ClsVision::CoordinateTransform(pose, affine); // Èç¹ûx1´óÓÚpoint.x£¬Ôò½«x1ÉèÖÃΪpoint.x if (x1 > point.x) x1 = (int)(point.x); // Èç¹ûy1´óÓÚpoint.y£¬Ôò½«y1ÉèÖÃΪpoint.y if (y1 > point.y) y1 = (int)(point.y); // Èç¹ûx2СÓÚpoint.x£¬Ôò½«x2ÉèÖÃΪpoint.x if (x2 < point.x) x2 = (int)(point.x); // Èç¹ûy2СÓÚpoint.y£¬Ôò½«y2ÉèÖÃΪpoint.y if (y2 < point.y) y2 = (int)(point.y); // ¼ÆËã¿í¶È int dWidth = x2 - x1 + 1; // Èç¹û¿í¶ÈСÓÚ220£¬Ôò½«x1ºÍx2ÉèÖÃΪ110µÄÆ«ÒÆÁ¿ if (dWidth <= 2 * (m_nRoiSize + 10)) { x1 = m_locPointResult.x - (m_nRoiSize + 10); x2 = m_locPointResult.x + (m_nRoiSize + 10); } // ·ñÔò£¬¼ÆËãx1ºÍx2µÄÆ«ÒÆÁ¿£¬²¢½«ËüÃÇÉèÖÃΪx1ºÍx2µÄÖмäÖµ else { int dd = (int)((dWidth + 2) / 2); x1 = m_locPointResult.x - dd; x2 = m_locPointResult.x + dd; } // ¼ÆËã¸ß¶È int dHeight = y2 - y1 + 1; // Èç¹û¸ß¶ÈСÓÚ80£¬Ôò½«y1ºÍy2ÉèÖÃΪ40µÄÆ«ÒÆÁ¿ if (dHeight <= 80) { y1 = m_locPointResult.y - 40; y2 = m_locPointResult.y + 40; } // ·ñÔò£¬¼ÆËãy1ºÍy2µÄÆ«ÒÆÁ¿£¬²¢½«ËüÃÇÉèÖÃΪy1ºÍy2µÄÖмäÖµ else { int dd = (int)((dHeight + 2) / 2); y1 = m_locPointResult.y - dd; y2 = m_locPointResult.y + dd; } HalconCpp::HObject hTmpObject; // Èç¹û»ñÈ¡ROIʧ°Ü£¬Ôò·µ»Øfalse if (!CVisionBufferPro::getImageROI(m_eDir, hTmpObject, x1, y1, x2, y2)) return false; // ½«½á¹ûµÄxºÍyÉèÖÃΪx1ºÍy1 result.x = x1; result.y = y1; // »ñȡͼÏñ´óС int width = 0; int height = 0; ClsVision::GetImageSize(hTmpObject, width, height); if (width < 1 || height < 1) return false; // Çå³ý֮ǰ¼Ç¼µÄµã vStdPoint.clear(); // ½«µãת»»Îª±ê×¼×ø±êϵ pose.x = 0.5 * (width - 1); pose.y = 0.5 * (height - 1); vStdPoint.push_back(pose); // ½«µãת»»ÎªÊµ¼Ê×ø±êϵ pose.x += (m_ptMeasureResult.x - m_locPointResult.x); pose.y += (m_ptMeasureResult.y - m_locPointResult.y); vStdPoint.push_back(pose); // ½«µãת»»ÎªÊµ¼Ê×ø±êϵ vRealPoint.clear(); pose.x = m_nRoiSize + 10; //110; pose.y = 40; vRealPoint.push_back(pose); pose.x = m_nRoiSize + 10 + dist;// 110.0 + dist; vRealPoint.push_back(pose); // ½«±ê×¼µãºÍʵ¼Êµãת»»ÎªÏàËÆ¶È affine = ClsVision::VectorToSimilarity(vStdPoint, vRealPoint); // ¶ÔͼÏñ½øÐзÂÉä±ä»» ClsVision::AffineTransImage(hTmpObject, affine, hImage); return true; } bool CKeyDistDotProcess::findEndPoint(DimensionDir eDir) { /* code */ //»ñȡָ¶¨·½ÏòµÄ²à±ßÊý¾Ý CBlSideData *pSideData = CVisionRecipe::getInstance()->getSideData(m_eDir); //Èç¹û²à±ßÊý¾ÝΪ¿Õ£¬Ôò·µ»Øfalse if (nullptr == pSideData) return false; if (0 == m_poseType) { //Èç¹û²à±ßÊý¾ÝÖÐûÓÐÕÒµ½Éϵ㣬Ôò·µ»Øfalse if (!pSideData->m_bBotMark_Find) return false; //Èç¹û²à±ßÊý¾ÝÖÐûÓÐÕÒµ½Ïµ㣬Ôò·µ»Øfalse if (!pSideData->m_bTopMark_Find) return false; } else { //Èç¹û²à±ßÊý¾ÝÖÐûÓÐÕÒµ½Éϵ㣬Ôò·µ»Øfalse if (!pSideData->m_bTopPoint_Find) return false; //Èç¹û²à±ßÊý¾ÝÖÐûÓÐÕÒµ½Ïµ㣬Ôò·µ»Øfalse if (!pSideData->m_bBotPoint_Find) return false; } //1. Ê×ÏȼÆËãKeyµÄλÖà Point2I ptOffset; ptOffset.x = m_keyPoseX; ptOffset.y = m_keyPoseY; Point2I result; if (!CVisionBufferPro::TransformToReal(m_eDir, ptOffset, m_poseType, result)) return false; m_ptMeasureResult.x = result.x; m_ptMeasureResult.y = result.y; ptOffset.x = m_nPosX; ptOffset.y = m_nPosY; if (!CVisionBufferPro::TransformToReal(m_eDir, ptOffset, m_poseType, result)) return false; m_locPointResult = result; HalconCpp::HObject hImage; Point2I leftTop; if (!getImageROI(hImage, leftTop)) return false; // ¶¨ÒåHObjectÀàÐ͵ıäÁ¿ HalconCpp::HObject hMeanObject, hRoiRegion, hTmpObj, hProcObject; // ʹÓÃMeanImageº¯Êý¼ÆËãͼÏñµÄƽ¾ùÖµ£¬²¢½«½á¹û´æ´¢ÔÚhMeanObjectÖÐ HalconCpp::MeanImage(hImage, &hMeanObject, 1, 15); // ¶¨ÒåÒ»¸ö¾ØÐÎÇøÓò£¬×óÉϽÇ×ø±êΪ(10, 10)£¬ÓÒϽÇ×ø±êΪ(69, 219) HalconCpp::GenRectangle1(&hRoiRegion, 10, 10, 69, 2 * (m_nRoiSize + 10)- 1 /* 219 */ ); // ʹÓÃReduceDomainº¯Êý½«hMeanObjectµÄÖµ¼õÈ¥hRoiRegionµÄÖµ£¬²¢½«½á¹û´æ´¢ÔÚhTmpObjÖÐ HalconCpp::ReduceDomain(hMeanObject, hRoiRegion, &hTmpObj); // ʹÓÃCropDomainº¯Êý²Ã¼ôhTmpObj£¬²¢½«½á¹û´æ´¢ÔÚhProcObjectÖÐ HalconCpp::CropDomain(hTmpObj, &hProcObject); int width = 0; int height = 0; ClsVision::GetImageSize(hProcObject, width, height); if (width < 1 || height < 1) return false; Line2D line; line.pt0.x = 5; line.pt0.y = 0.5 * height - 1; line.pt1.x = width - 6; line.pt1.y = 0.5 * height - 1; int nThreshold = 10; if (m_nEndThres > 3) nThreshold = m_nEndThres; Point2D ptStart, ptEnd; if (!CVisionBufferPro::GetMeasureNearPos(hProcObject, line, nThreshold, 0, 10, ptStart, ptEnd)) return false; Point2D posLeftPoint; posLeftPoint.x = ptStart.x + 10; posLeftPoint.y = 0.5 * (height - 1) + 10; std::vector vStdPoint, vRealPoint; // ¼ÆËã±ê×¼µãÓëʵ¼ÊµãÖ®¼äµÄ¾àÀë double dx = m_locPointResult.x - m_ptMeasureResult.x; double dy = m_locPointResult.y - m_ptMeasureResult.y; double dist = sqrt(dx * dx + dy * dy); // ´´½¨Ò»¸öposeµã£¬ÓÃÓÚ´æ´¢±ê×¼µã Point2D pose; pose.x = 10 + m_nRoiSize; // 110; pose.y = 40; vStdPoint.push_back(pose); // ½«±ê×¼µãÑØ×žàÀëÒÆ¶¯ pose.x = 10 + m_nRoiSize + dist; // 110.0 + dist; vStdPoint.push_back(pose); // ½«Êµ¼Êµã´æÈëvRealPoint pose.x = m_locPointResult.x; pose.y = m_locPointResult.y; vRealPoint.push_back(pose); vRealPoint.push_back(m_ptMeasureResult); // ½«vStdPointºÍvRealPointת»»Îª·ÂÉ侨Õó ParaAffine2D affine = ClsVision::VectorToSimilarity(vStdPoint, vRealPoint); m_ptNearResult = ClsVision::CoordinateTransform(posLeftPoint, affine); if (m_nEndThres > 3) { Point2D posEndPoint; posEndPoint.x = ptEnd.x + 10; posEndPoint.y = 0.5 * (height - 1) + 10; m_ptMeasureResult = ClsVision::CoordinateTransform(posEndPoint, affine); } // return true; } int CKeyDistDotProcess::getID(void) { /* code */ return m_id; } void CKeyDistDotProcess::setRoiSize(int sz) { /* code */ m_nRoiSize = sz; } void CKeyDistDotProcess::getMmvsp(DimensionDir eDir) { /* code */ CBlSideData *pSideData = CVisionRecipe::getInstance()->getSideData(eDir); m_xMmvsp = pSideData->m_dPixelSizeX; m_yMmvsp = pSideData->m_dPixelSizeY; } void CKeyDistDotProcess::judgeResult(void) { /* code */ m_nNgInfo.clear(); if (fabs(m_ptMeasureResult.x) < 0.1 && fabs(m_ptMeasureResult.y) < 0.1f) return; //´´½¨È±ÏÝdotÐÅÏ¢ NgDotInfo ng; ng.eDir = m_eDir; ng.id = m_id; ng.isRes = true; ng.minValue = m_nMin; ng.maxValue = m_nMax; ng.strName = m_strName; ng.ngType = DefectLoc_OK; //ȱÏÝÀàÐÍ ng.eVision = VISION_KDIST; //¼ÆËãȱÏÝλÖà ng.xPosPxl = m_locPointResult.x; ng.yPosPxl = m_locPointResult.y; ng.xResult = 0.0f; ng.yResult = 0.0f; ng.x1 = m_locPointResult.x - 40; ng.y1 = m_locPointResult.y - 20; ng.x2 = m_locPointResult.x + 40; ng.y2 = m_locPointResult.y + 20; //¼ÆËãȱÏÝÀàÐÍ ng.ngType = DefectLoc_Corner_Dist; double dx = m_xMmvsp *(m_ptMeasureResult.x - m_ptNearResult.x); double dy = m_yMmvsp *(m_ptMeasureResult.y - m_ptNearResult.y); m_distResult = sqrt(dx * dx + dy * dy); //Êä³öÏÔʾÊý¾Ý CBlSideData* pSideData = CVisionRecipe::getInstance()->getSideData(m_eDir); if (nullptr != pSideData) { //ÇøÓòµÄÏÔʾ½á¹û DispVisionResult inf; inf.nType = 3; inf.strName = m_strName; inf.eDir = (int)(m_eDir); inf.eVision = (int)(VISION_KDIST); inf.rectX1 = (int)(m_ptMeasureResult.x); inf.rectY1 = (int)(m_ptMeasureResult.y); inf.rectX2 = (int)(m_ptNearResult.x); inf.rectY2 = (int)(m_ptNearResult.y); pSideData->m_vDispVisionResult.push_back(inf); inf.nType = 0; inf.strName = m_strName; inf.eDir = (int)(m_eDir); inf.eVision = (int)(VISION_KDIST); inf.pointX = (int)(m_ptNearResult.x); inf.pointY = (int)(m_ptNearResult.y); pSideData->m_vDispVisionResult.push_back(inf); inf.nType = 4; inf.strName = m_strName; inf.eDir = (int)(m_eDir); inf.eVision = (int)(VISION_KDIST); inf.pointX = (int)(m_ptNearResult.x); inf.pointY = (int)(m_ptNearResult.y); pSideData->m_vDispVisionResult.push_back(inf); } //¼ÆËãȱÏݾàÀë m_distResult += m_nInc; ng.result = m_distResult; //ÅжÏȱÏÝÊÇ·ñ·ûºÏ±ê×¼ if (m_nMax < 0.5) { m_nNgInfo.push_back(ng); return; } double dDist = m_distResult - m_nStdDist; if (dDist < m_nMin || dDist > m_nMax) { ng.isRes = false; } m_nNgInfo.push_back(ng); } Json::Value CKeyDistDotProcess::WriteToJson(void) { /* code */ std::string strName = CFileRecipe::toString(m_strName); Json::Value jsValue; jsValue["alg type"] = KDIST_VISION_TYPE; jsValue["side"] = (int)(m_eDir); jsValue["id"] = m_id; jsValue["name"] = strName; jsValue["use"] = m_nUse; jsValue["pos type"] = m_poseType; jsValue["key pos x"] = m_keyPoseX; jsValue["key pos y"] = m_keyPoseY; jsValue["pos x"] = m_nPosX; jsValue["pos y"] = m_nPosY; jsValue["inc"] = m_nInc; jsValue["min"] = m_nMin; jsValue["max"] = m_nMax; jsValue["end thres"] = m_nEndThres; jsValue["std dist"] = m_nStdDist; return jsValue; } void CKeyDistDotProcess::DecodeJson(Json::Value &jsValue) { /* code */ int num = (int)(jsValue.size()); if (num < 1) return; //1. side std::string strName = "side"; if (jsValue.isMember(strName.c_str()) && jsValue[strName.c_str()].isInt()) { m_eDir = (DimensionDir)(jsValue[strName.c_str()].asInt()); } //2. id strName = "id"; if (jsValue.isMember(strName.c_str()) && jsValue[strName.c_str()].isInt()) { m_id = jsValue[strName.c_str()].asInt(); } //3. name strName = "name"; if (jsValue.isMember(strName.c_str()) && jsValue[strName.c_str()].isString()) { m_strName = CFileRecipe::toCString(jsValue[strName.c_str()].asString()); } //4. use strName = "use"; if (jsValue.isMember(strName.c_str()) && jsValue[strName.c_str()].isInt()) { m_nUse = jsValue[strName.c_str()].asInt(); } //5. pos type strName = "pos type"; if (jsValue.isMember(strName.c_str()) && jsValue[strName.c_str()].isInt()) { m_poseType = jsValue[strName.c_str()].asInt(); } //6. key pos x strName = "key pos x"; if (jsValue.isMember(strName.c_str()) && jsValue[strName.c_str()].isInt()) { m_keyPoseX = jsValue[strName.c_str()].asInt(); } //7. key pos y strName = "key pos y"; if (jsValue.isMember(strName.c_str()) && jsValue[strName.c_str()].isInt()) { m_keyPoseY = jsValue[strName.c_str()].asInt(); } //8. pos x strName = "pos x"; if (jsValue.isMember(strName.c_str()) && jsValue[strName.c_str()].isInt()) { m_nPosX = jsValue[strName.c_str()].asInt(); } //9. pos y strName = "pos y"; if (jsValue.isMember(strName.c_str()) && jsValue[strName.c_str()].isInt()) { m_nPosY = jsValue[strName.c_str()].asInt(); } //10. inc strName = "inc"; if (jsValue.isMember(strName.c_str()) && jsValue[strName.c_str()].isInt()) { m_nInc = jsValue[strName.c_str()].asInt(); } //11. min strName = "min"; if (jsValue.isMember(strName.c_str()) && jsValue[strName.c_str()].isInt()) { m_nMin = jsValue[strName.c_str()].asInt(); } //12. max strName = "max"; if (jsValue.isMember(strName.c_str()) && jsValue[strName.c_str()].isInt()) { m_nMax = jsValue[strName.c_str()].asInt(); } //14. end thres strName = "end thres"; if (jsValue.isMember(strName.c_str()) && jsValue[strName.c_str()].isInt()) { m_nEndThres = jsValue[strName.c_str()].asInt(); } //15. std dist strName = "std dist"; if (jsValue.isMember(strName.c_str()) && jsValue[strName.c_str()].isInt()) { m_nStdDist = jsValue[strName.c_str()].asInt(); } }