feat 模板参数传递,完成模板对齐

dev_lsy
xiewenji 1 month ago
parent 874a531076
commit 3dba31a9b4

@ -65,6 +65,11 @@ public:
std::string GetErrorInfo();
// 获取模板外接矩形
const cv::RotatedRect &GetTplOuterRect() const { return m_tplOuterRect; }
// 获取模板 pin blob 轮廓点集
const std::vector<std::vector<cv::Point>> &GetTplPinContours() const { return m_tplPinContours; }
private:
// 加载运行参数
int LoadRunConfig(void *p);

@ -133,6 +133,10 @@ public:
int Init(std::string strcameraName);
int StartCheck(std::shared_ptr<CameraResult> pCamera_Check_Result);
// 设置模板信息并转发给各个检测核心
void SetTplInfo(const cv::RotatedRect &outerRect,
const std::vector<std::vector<cv::Point>> &pinContours);
private:
// 开启线程
int StartThread();

@ -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<cv::Point2f> sort_vertices(cv::RotatedRect rrect);
// 找图片的最大外轮廓
static std::vector<cv::Point> getLargestContourROI(const cv::Mat &binaryImg, bool &found);

@ -80,6 +80,10 @@ public:
int creatsavedir();
// 设置模板信息(模板外接矩形 + 模板 pin blob 轮廓点集)
void SetTplInfo(const cv::RotatedRect &outerRect,
const std::vector<std::vector<cv::Point>> &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<AIFactory> AI_Factory;
@ -287,6 +291,10 @@ private:
cv::Point m_old_cur_markLine_mark1;
cv::Point m_old_cur_markLine_mark2;
std::vector<RegionConfigST> m_old_cur_regionConfigArr;
// 模板信息
cv::RotatedRect m_tplOuterRect; // 模板外接矩形
std::vector<std::vector<cv::Point>> m_tplPinContours; // 模板 pin blob 轮廓点集
};
#endif

@ -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");

@ -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<std::vector<cv::Point>> &pinContours)
{
for (int i = 0; i < IMGCHECKANALYSISY_NUM; i++)
{
auto *p = static_cast<ImgCheckAnalysisy *>(m_pImgCheckAnalysisy[i]);
if (p)
{
p->SetTplInfo(outerRect, pinContours);
}
}
}
int CameraCheckAnalysisy::StartCheck(std::shared_ptr<CameraResult> pCamera_Check_Result)
{
if (m_bHaveImgeDet)

@ -419,6 +419,26 @@ float CheckUtil::getLongAxisAngle(cv::RotatedRect rect) {
return long_axis_angle;
}
std::vector<cv::Point2f> CheckUtil::sort_vertices(cv::RotatedRect rrect) {
cv::Point2f pts[4];
rrect.points(pts);
std::vector<cv::Point2f> 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<cv::Point> CheckUtil::getLargestContourROI(const cv::Mat &binaryImg, bool &found)
{
std::vector<std::vector<cv::Point>> contours;

@ -210,6 +210,13 @@ int ImgCheckAnalysisy::creatsavedir()
return 0;
}
void ImgCheckAnalysisy::SetTplInfo(const cv::RotatedRect &outerRect,
const std::vector<std::vector<cv::Point>> &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<std::vector<cv::Point>> 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<float>(img_mat.cols - 1)));
new_point.y = std::max(0.0f, std::min(new_point.y, static_cast<float>(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<int>(img.cols / scale_x);
int resize_height = static_cast<int>(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<std::vector<cv::Point>> 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<int>(small_roi.x * scale_x);
roi.y = static_cast<int>(small_roi.y * scale_y);
roi.width = static_cast<int>(small_roi.width * scale_x);
roi.height = static_cast<int>(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<cv::Point>& cur_edgeDet_region = m_AnalysisyConfig.baseFunction.edgeDet.region;
std::vector<cv::Point>& 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<RegionConfigST>& 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<cv::Point2f> cur_vertices = CheckUtil::sort_vertices(curOuterRect);
vector<cv::Point2f> 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;

@ -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)

Loading…
Cancel
Save