diff --git a/AlgorithmModule/include/ALLImgCheckAnalysisy.hpp b/AlgorithmModule/include/ALLImgCheckAnalysisy.hpp index bce3078..877c505 100644 --- a/AlgorithmModule/include/ALLImgCheckAnalysisy.hpp +++ b/AlgorithmModule/include/ALLImgCheckAnalysisy.hpp @@ -65,6 +65,11 @@ public: std::string GetErrorInfo(); + // 获取模板外接矩形 + const cv::RotatedRect &GetTplOuterRect() const { return m_tplOuterRect; } + // 获取模板 pin blob 轮廓点集 + const std::vector> &GetTplPinContours() const { return m_tplPinContours; } + private: // 加载运行参数 int LoadRunConfig(void *p); diff --git a/AlgorithmModule/include/CameraCheckAnalysisy.hpp b/AlgorithmModule/include/CameraCheckAnalysisy.hpp index 5321767..10429e1 100644 --- a/AlgorithmModule/include/CameraCheckAnalysisy.hpp +++ b/AlgorithmModule/include/CameraCheckAnalysisy.hpp @@ -133,6 +133,10 @@ public: int Init(std::string strcameraName); int StartCheck(std::shared_ptr pCamera_Check_Result); + // 设置模板信息并转发给各个检测核心 + void SetTplInfo(const cv::RotatedRect &outerRect, + const std::vector> &pinContours); + private: // 开启线程 int StartThread(); diff --git a/AlgorithmModule/include/CheckUtil.hpp b/AlgorithmModule/include/CheckUtil.hpp index 3df5b2d..237b064 100644 --- a/AlgorithmModule/include/CheckUtil.hpp +++ b/AlgorithmModule/include/CheckUtil.hpp @@ -51,6 +51,9 @@ public: static float Cal2PointAngle(cv::Point p_left, cv::Point p_right); // 获取 RotatedRect 长轴的方向角(归一化到 [0, 180) 度) static float getLongAxisAngle(const cv::RotatedRect rect); + // 排序RotatedRect的四个顶点 + static std::vector sort_vertices(cv::RotatedRect rrect); + // 找图片的最大外轮廓 static std::vector getLargestContourROI(const cv::Mat &binaryImg, bool &found); diff --git a/AlgorithmModule/include/ImgCheckAnalysisy.hpp b/AlgorithmModule/include/ImgCheckAnalysisy.hpp index 8ab1107..01c0ad2 100644 --- a/AlgorithmModule/include/ImgCheckAnalysisy.hpp +++ b/AlgorithmModule/include/ImgCheckAnalysisy.hpp @@ -80,6 +80,10 @@ public: int creatsavedir(); + // 设置模板信息(模板外接矩形 + 模板 pin blob 轮廓点集) + void SetTplInfo(const cv::RotatedRect &outerRect, + const std::vector> &pinContours); + private: // 加载运行参数 int LoadRunConfig(void *p); @@ -195,7 +199,7 @@ private: int BLobToDetResult(); //自适应参数区域更新 - int Adapt_Config(Mat img, Rect roi, bool b_update); + int Adapt_Config(cv::RotatedRect tplOuterRect, cv::RotatedRect curOuterRect, cv::Mat& det_img); std::shared_ptr AI_Factory; @@ -287,6 +291,10 @@ private: cv::Point m_old_cur_markLine_mark1; cv::Point m_old_cur_markLine_mark2; std::vector m_old_cur_regionConfigArr; + + // 模板信息 + cv::RotatedRect m_tplOuterRect; // 模板外接矩形 + std::vector> m_tplPinContours; // 模板 pin blob 轮廓点集 }; #endif \ No newline at end of file diff --git a/AlgorithmModule/src/ALLImgCheckAnalysisy.cpp b/AlgorithmModule/src/ALLImgCheckAnalysisy.cpp index 5aef7c5..f90277f 100644 --- a/AlgorithmModule/src/ALLImgCheckAnalysisy.cpp +++ b/AlgorithmModule/src/ALLImgCheckAnalysisy.cpp @@ -187,6 +187,14 @@ int ALLImgCheckAnalysisy::RunStart(void *pconfig1) m_nErrorCode = re; return m_nErrorCode; } + // 把模板信息下发到各个相机检测实例 + for (auto &item : m_pCameraCheckAnalysisyList) + { + if (item.second) + { + item.second->SetTplInfo(m_tplOuterRect, m_tplPinContours); + } + } m_nErrorCode = CHECK_OK; printf(">>>> ALLImgCheckAnalysisy Start Succ \n"); diff --git a/AlgorithmModule/src/CameraCheckAnalysisy.cpp b/AlgorithmModule/src/CameraCheckAnalysisy.cpp index bc36188..bca4451 100644 --- a/AlgorithmModule/src/CameraCheckAnalysisy.cpp +++ b/AlgorithmModule/src/CameraCheckAnalysisy.cpp @@ -7,6 +7,7 @@ * @FilePath: /ZCXD_MonitorPlatform/src/CoreLogicModule/src/CamDeal.cpp */ #include "CameraCheckAnalysisy.hpp" +#include "ImgCheckAnalysisy.hpp" #include "CheckUtil.hpp" #include "Define.h" @@ -601,6 +602,19 @@ int CameraCheckAnalysisy::Init(std::string strcameraName) return 0; } +void CameraCheckAnalysisy::SetTplInfo(const cv::RotatedRect &outerRect, + const std::vector> &pinContours) +{ + for (int i = 0; i < IMGCHECKANALYSISY_NUM; i++) + { + auto *p = static_cast(m_pImgCheckAnalysisy[i]); + if (p) + { + p->SetTplInfo(outerRect, pinContours); + } + } +} + int CameraCheckAnalysisy::StartCheck(std::shared_ptr pCamera_Check_Result) { if (m_bHaveImgeDet) diff --git a/AlgorithmModule/src/CheckUtil.cpp b/AlgorithmModule/src/CheckUtil.cpp index 1945c10..87e78de 100644 --- a/AlgorithmModule/src/CheckUtil.cpp +++ b/AlgorithmModule/src/CheckUtil.cpp @@ -419,6 +419,26 @@ float CheckUtil::getLongAxisAngle(cv::RotatedRect rect) { return long_axis_angle; } +std::vector CheckUtil::sort_vertices(cv::RotatedRect rrect) { + cv::Point2f pts[4]; + rrect.points(pts); + std::vector vertices(pts, pts + 4); + + // 按 y 坐标升序排序 + std::sort(vertices.begin(), vertices.end(), + [](const cv::Point2f& a, const cv::Point2f& b) { + return a.y < b.y; + }); + + if (vertices[0].x > vertices[1].x) + std::swap(vertices[0], vertices[1]); + + if (vertices[2].x > vertices[3].x) + std::swap(vertices[2], vertices[3]); + + return vertices; +} + std::vector CheckUtil::getLargestContourROI(const cv::Mat &binaryImg, bool &found) { std::vector> contours; diff --git a/AlgorithmModule/src/ImgCheckAnalysisy.cpp b/AlgorithmModule/src/ImgCheckAnalysisy.cpp index 4ebc40d..92e1ca5 100644 --- a/AlgorithmModule/src/ImgCheckAnalysisy.cpp +++ b/AlgorithmModule/src/ImgCheckAnalysisy.cpp @@ -210,6 +210,13 @@ int ImgCheckAnalysisy::creatsavedir() return 0; } +void ImgCheckAnalysisy::SetTplInfo(const cv::RotatedRect &outerRect, + const std::vector> &pinContours) +{ + m_tplOuterRect = outerRect; + m_tplPinContours = pinContours; +} + int ImgCheckAnalysisy::LoadRunConfig(void *p) { if (p == NULL) @@ -363,241 +370,26 @@ cv::Scalar ImgCheckAnalysisy::calc_blob_info_withstats(cv::Mat &img, const cv::M return cv::Scalar(worb, energy, hj); } -Point2f GetCoorPoint(Point2f point, Mat img_mat) -{ - // 越界判定 - int coor_img_rect_x = point.x-400; - int coor_img_rect_y = point.y-400; - int coor_img_rect_w = 800; - int coor_img_rect_h = 800; - if (coor_img_rect_x < 0) - { - coor_img_rect_x = 0; - coor_img_rect_w = min(400, img_mat.cols); - } - if (coor_img_rect_y < 0) - { - coor_img_rect_y = 0; - coor_img_rect_h = min(400, img_mat.rows); - } - if (coor_img_rect_x + coor_img_rect_w > img_mat.cols) - { - coor_img_rect_w = img_mat.cols - coor_img_rect_x; - } - if (coor_img_rect_y + coor_img_rect_h > img_mat.rows) - { - coor_img_rect_h = img_mat.rows - coor_img_rect_y; - } - if (coor_img_rect_x < 0 || coor_img_rect_y < 0 || coor_img_rect_x + coor_img_rect_w > img_mat.cols || coor_img_rect_y + coor_img_rect_h > img_mat.rows) - { - return point; - } - - Mat coor_img_mat = img_mat(Rect(coor_img_rect_x, coor_img_rect_y, coor_img_rect_w, coor_img_rect_h)); - Mat coor_img_bin; - threshold(coor_img_mat, coor_img_bin, 50, 255, THRESH_BINARY); - - // 6. 查找轮廓 - std::vector> contours; - cv::findContours(coor_img_bin, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); - if (contours.empty()) - { - return point; - } - double maxArea = 0; - int maxAreaIdx = -1; - for (size_t i = 0; i < contours.size(); ++i) - { - double area = cv::contourArea(contours[i]); - if (area > maxArea) - { - maxArea = area; - maxAreaIdx = i; - } - } - if (maxAreaIdx < 0 || maxArea < 100) - { - return point; - } - cv::RotatedRect rect = cv::minAreaRect(contours[maxAreaIdx]); - Point2f vertices[4]; - rect.points(vertices); - - int cornerIdx = 0; - float minDist = FLT_MAX; - for (int i = 0; i < 4; i++) - { - float dist = std::pow(vertices[i].x - 400, 2) + std::pow(vertices[i].y - 400, 2); - if (dist < minDist) - { - minDist = dist; - cornerIdx = i; - } - } - - Point2f new_point; - new_point.x = vertices[cornerIdx].x + coor_img_rect_x; - new_point.y = vertices[cornerIdx].y + coor_img_rect_y; - - new_point.x = std::max(0.0f, std::min(new_point.x, static_cast(img_mat.cols - 1))); - new_point.y = std::max(0.0f, std::min(new_point.y, static_cast(img_mat.rows - 1))); - - return new_point; -} - -int GetEdgeRoi(Mat img, Rect &new_roi, float scale_x, float scale_y){ - if (img.empty()) - { - return 1; - } - // 缩小,减少耗时 - Mat r_img; - - int resize_width = static_cast(img.cols / scale_x); - int resize_height = static_cast(img.rows / scale_y); - resize(img, r_img, Size(resize_width, resize_height), 0, 0, INTER_LINEAR); - - // 二值化找最大连通域 - Mat r_img_bin; - threshold(r_img, r_img_bin, 15, 255, THRESH_BINARY); - std::vector> contours; - cv::findContours(r_img_bin, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); - if (contours.empty()) - { - return 2; - } - double maxArea = 0; - int maxAreaIdx = -1; - for (size_t i = 0; i < contours.size(); ++i) - { - double area = cv::contourArea(contours[i]); - if (area > maxArea) - { - maxArea = area; - maxAreaIdx = i; - } - } - - if (maxAreaIdx < 0) - { - return 3; - } - - cv::Rect small_roi = cv::boundingRect(contours[maxAreaIdx]); - Rect roi; - roi.x = static_cast(small_roi.x * scale_x); - roi.y = static_cast(small_roi.y * scale_y); - roi.width = static_cast(small_roi.width * scale_x); - roi.height = static_cast(small_roi.height * scale_y); - roi.x = std::max(0, roi.x); - roi.y = std::max(0, roi.y); - roi.width = std::min(roi.width, img.cols - roi.x); - roi.height = std::min(roi.height, img.rows - roi.y); - - new_roi = roi; - - return 0; -} - -int ImgCheckAnalysisy::Adapt_Config(Mat img, Rect cur_roi, bool b_update){ - if (img.empty()) { - std::cerr << "Error: Input image 'img' is empty!" << std::endl; - return -1; - } - if(!b_update){ - return 1; - } - int get_edge_roi = GetEdgeRoi(img, cur_roi, 20, 20); - if(get_edge_roi != 0){ - return 2; - } - m_pdetlog->AddCheckstr(PrintLevel_0, "Adapt_Config", "-------------------start--------------"); - - /*计算xy偏移,缩放比例*/ - // 拷贝原始数据 - if(m_old_productROI.width == 0 || m_old_productROI.height == 0){ - m_old_productROI = m_AnalysisyConfig.baseFunction.markLine.productROI; - m_old_cur_edgeDet_region = m_AnalysisyConfig.baseFunction.edgeDet.region; - m_old_cur_markLine_region = m_AnalysisyConfig.baseFunction.markLine.region; - m_old_cur_markLine_mark1 = m_AnalysisyConfig.baseFunction.markLine.mark_local_1; - m_old_cur_markLine_mark2 = m_AnalysisyConfig.baseFunction.markLine.mark_local_2; - m_old_cur_regionConfigArr = m_AnalysisyConfig.commonCheckConfig.nodeConfigArr[0].regionConfigArr; - } - Rect old_roi = m_old_productROI; - Point old_center(old_roi.x + old_roi.width / 2, old_roi.y + old_roi.height / 2); - Point new_center(cur_roi.x + cur_roi.width / 2, cur_roi.y + cur_roi.height / 2); - - int x_offset = new_center.x - old_center.x; - int y_offset = new_center.y - old_center.y; - float scale_x = (float)cur_roi.width / (float)old_roi.width; - float scale_y = (float)cur_roi.height / (float)old_roi.height; - - m_pdetlog->AddCheckstr(PrintLevel_0, "Adapt_Config", "old_roi = %d %d %d %d", old_roi.x, old_roi.y, old_roi.width, old_roi.height); - m_pdetlog->AddCheckstr(PrintLevel_0, "Adapt_Config", "cur_roi = %d %d %d %d", cur_roi.x, cur_roi.y, cur_roi.width, cur_roi.height); - m_pdetlog->AddCheckstr(PrintLevel_0, "Adapt_Config", "x_offset = %d y_offset = %d", x_offset, y_offset); - m_pdetlog->AddCheckstr(PrintLevel_0, "Adapt_Config", "scale_x = %f scale_y = %f", scale_x, scale_y); - - if(abs(x_offset) < 50 && abs(y_offset) < 50 && abs(scale_x - 1) < 0.0001 && abs(scale_y - 1) < 0.0001 ){ - return 3; - } - - /*获取待修改的region引用*/ - std::vector& cur_edgeDet_region = m_AnalysisyConfig.baseFunction.edgeDet.region; - std::vector& cur_markLine_region = m_AnalysisyConfig.baseFunction.markLine.region; - cv::Point& cur_markLine_mark1 = m_AnalysisyConfig.baseFunction.markLine.mark_local_1; - cv::Point& cur_markLine_mark2 = m_AnalysisyConfig.baseFunction.markLine.mark_local_2; - std::vector& cur_regionConfigArr = m_AnalysisyConfig.commonCheckConfig.nodeConfigArr[0].regionConfigArr; - - /*进行修改*/ - // rect - m_AnalysisyConfig.baseFunction.markLine.productROI = cur_roi; - // point - cur_markLine_mark1.x = m_old_cur_markLine_mark1.x + x_offset; - cur_markLine_mark1.y = m_old_cur_markLine_mark1.y + y_offset; - cur_markLine_mark1 = Point((cur_markLine_mark1.x - new_center.x) * scale_x + new_center.x, (cur_markLine_mark1.y - new_center.y) * scale_y + new_center.y); - cur_markLine_mark2.x = m_old_cur_markLine_mark2.x + x_offset; - cur_markLine_mark2.y = m_old_cur_markLine_mark2.y + y_offset; - cur_markLine_mark2 = Point((cur_markLine_mark2.x - new_center.x) * scale_x + new_center.x, (cur_markLine_mark2.y - new_center.y) * scale_y + new_center.y); - // region - for(int i = 0; i < cur_edgeDet_region.size(); i++){ - cur_edgeDet_region[i].x = m_old_cur_edgeDet_region[i].x + x_offset; - cur_edgeDet_region[i].y = m_old_cur_edgeDet_region[i].y + y_offset; - cur_edgeDet_region[i] = Point((cur_edgeDet_region[i].x - new_center.x) * scale_x + new_center.x, (cur_edgeDet_region[i].y - new_center.y) * scale_y + new_center.y); - } - for(int i = 0; i < cur_markLine_region.size(); i++){ - cur_markLine_region[i].x = m_old_cur_markLine_region[i].x + x_offset; - cur_markLine_region[i].y = m_old_cur_markLine_region[i].y + y_offset; - cur_markLine_region[i] = Point((cur_markLine_region[i].x - new_center.x) * scale_x + new_center.x, (cur_markLine_region[i].y - new_center.y) * scale_y + new_center.y); - } - for(int i = 0 ; i < cur_regionConfigArr.size(); i++){ - for(int j = 0; j < cur_regionConfigArr[i].basicInfo.pointArry.size(); j++){ - cur_regionConfigArr[i].basicInfo.pointArry[j].x = m_old_cur_regionConfigArr[i].basicInfo.pointArry[j].x + x_offset; - cur_regionConfigArr[i].basicInfo.pointArry[j].y = m_old_cur_regionConfigArr[i].basicInfo.pointArry[j].y + y_offset; - cur_regionConfigArr[i].basicInfo.pointArry[j] = Point((cur_regionConfigArr[i].basicInfo.pointArry[j].x - new_center.x) * scale_x + new_center.x, (cur_regionConfigArr[i].basicInfo.pointArry[j].y - new_center.y) * scale_y + new_center.y); - } - } - - /*show*/ - // Mat show_img = img.clone(); - // cv::rectangle(show_img, m_AnalysisyConfig.baseFunction.markLine.productROI, Scalar(255), 5); - // if(cur_edgeDet_region.size() >=2){ - // for(int i = 0 ; i < cur_edgeDet_region.size() - 1; i++){ - // cv::line(show_img, cur_edgeDet_region[i], cur_edgeDet_region[i+1], Scalar(255), 20); - // } - // } - // if(cur_markLine_region.size() >=2){ - // for(int i = 0 ; i < cur_markLine_region.size() - 1; i++){ - // cv::line(show_img, cur_markLine_region[i], cur_markLine_region[i+1], Scalar(255), 20); - // } - // } - // if(cur_regionConfigArr.size() >=2){ - // for(int i = 0 ; i < cur_regionConfigArr.size(); i++){ - // for(int j = 0; j < cur_regionConfigArr[i].basicInfo.pointArry.size()-1; j++){ - // cv::line(show_img, cur_regionConfigArr[i].basicInfo.pointArry[j], cur_regionConfigArr[i].basicInfo.pointArry[j+1], Scalar(255), 20); - // } - // } - // } - // imwrite(m_AnalysisyConfig.commonCheckConfig.baseConfig.strCamearName +"_show_img.tiff", show_img); +int ImgCheckAnalysisy::Adapt_Config(RotatedRect tplOuterRect, RotatedRect curOuterRect, Mat& det_img){ + vector cur_vertices = CheckUtil::sort_vertices(curOuterRect); + vector tpl_vertices = CheckUtil::sort_vertices(tplOuterRect); + + cv::Point2f src_pts[3] = { + cur_vertices[0], // 对应左上 + cur_vertices[1], // 对应右上 + cur_vertices[2] // 对应左下 + }; + cv::Point2f dst_pts[3] = { + tpl_vertices[0], // 左上 + tpl_vertices[1], // 右上 + tpl_vertices[2] // 左下 + }; + cv::Mat affine_mat = cv::getAffineTransform(src_pts, dst_pts); + + // 仿射变换 + cv::warpAffine(det_img, det_img, affine_mat, det_img.size()); + + // imwrite("det_img.png", det_img); return 0; } @@ -669,7 +461,7 @@ int ImgCheckAnalysisy::CheckRun() diff_align = std::fmod(diff_align, 180.0f); // 模 180 度 /*投影对齐模板*/ - Adapt_Config(m_CheckResult_shareP->in_shareImage->img, m_outer_roi, m_pbaseCheckFunction->markLine.badapt_region); + Adapt_Config(m_tplOuterRect, outer_roi, m_CheckResult_shareP->in_shareImage->img); m_Crop_Roi_paramImg = m_outer_roi; m_pImageAllResult->pDetResult->CutRoi = m_outer_roi; diff --git a/AlgorithmModule/src/Pin_QX_Det.cpp b/AlgorithmModule/src/Pin_QX_Det.cpp index 84a833b..3805e42 100644 --- a/AlgorithmModule/src/Pin_QX_Det.cpp +++ b/AlgorithmModule/src/Pin_QX_Det.cpp @@ -94,7 +94,7 @@ int Pin_QX_Det::Detect(const cv::Mat &img, DetConfigResult *pDetConfig) Mat pin_mask; int re = GetPinMask(img, pDetConfig, pin_mask); - // 获取pin模板mask + // 获取pin模板blob信息 if (m_bshowimg)