优化程序,top相机增加二维码识别定位,底部相机增加标定系数参与计算偏移

master
xiewenji 1 week ago
parent f1b4ee142b
commit a50a2c1c6a

@ -24,17 +24,11 @@ public:
// 更新参数 pconfig 参数指针nConfigType 需要更新的参数类型 返回0 成功 其他异常
int UpdateConfig(void *pconfig, int nConfigType);
public:
private:
Top_Detect top_1_detect;
Top_Detect top_2_detect;
Side_Detect side_1_detect;
Side_Detect side_2_detect;
Down_Detect down_detect;
Down_Angle_Detect down_angle_detect;
std::shared_ptr<ImgCheckBase> m_checkBase = nullptr;
std::shared_ptr<Down_Angle_Detect> m_down_angle_detect = nullptr;
Cam_Param m_cam_param;
private:
};
#endif

@ -25,44 +25,51 @@ int ALL_Detect::RunStart(void *pconfig1)
// 初始化
m_cam_param.copy(*(Cam_Param *)pconfig1);
RunInfoST runconfig;
runconfig.flag0 = m_cam_param.cam_position;
switch (m_cam_param.cam_position)
{
case CAMERA_TOP_1:
if (!m_checkBase)
m_checkBase = std::make_shared<Top_Detect>();
runconfig.str_AIModelJson = m_cam_param.AIModel_param_path + "AIModel_Top.json";
runconfig.str_RunJson = m_cam_param.check_param_path + "param_Top-1.json";
this->top_1_detect.RunStart((void *)&runconfig);
break;
case CAMERA_TOP_2:
if (!m_checkBase)
m_checkBase = std::make_shared<Top_Detect>();
runconfig.str_AIModelJson = m_cam_param.AIModel_param_path + "AIModel_Top.json";
runconfig.str_RunJson = m_cam_param.check_param_path + "param_Top-2.json";
this->top_2_detect.RunStart((void *)&runconfig);
break;
case CAMERA_SIDE_1:
if (!m_checkBase)
m_checkBase = std::make_shared<Side_Detect>();
runconfig.str_AIModelJson = m_cam_param.AIModel_param_path + "AIModel_Side.json";
runconfig.str_RunJson = m_cam_param.check_param_path + "param_Side-1.json";
this->side_1_detect.RunStart((void *)&runconfig);
break;
case CAMERA_SIDE_2:
if (!m_checkBase)
m_checkBase = std::make_shared<Side_Detect>();
runconfig.str_AIModelJson = m_cam_param.AIModel_param_path + "AIModel_Side.json";
runconfig.str_RunJson = m_cam_param.check_param_path + "param_Side-2.json";
this->side_2_detect.RunStart((void *)&runconfig);
break;
case CAMERA_DOWN_1:
if (!m_checkBase)
m_checkBase = std::make_shared<Down_Detect>();
if (!m_down_angle_detect)
m_down_angle_detect = std::make_shared<Down_Angle_Detect>();
runconfig.str_AIModelJson = m_cam_param.AIModel_param_path + "AIModel_Down.json";
runconfig.str_RunJson = m_cam_param.check_param_path + "param_Down.json";
this->down_detect.RunStart((void *)&runconfig);
this->down_angle_detect.RunStart((void *)&runconfig);
this->m_down_angle_detect->RunStart((void *)&runconfig);
break;
default:
break;
}
this->m_checkBase->RunStart((void *)&runconfig);
return 0;
}
int ALL_Detect::CheckImg(std::shared_ptr<shareImage> p, std::shared_ptr<CheckResult> &pResult)
{
// DetImgInfo_shareP = p;
// printf("%d DetImgInfo_shareP count %ld \n", m_RunConfig.nThreadIdx, DetImgInfo_shareP.use_count());
if (m_cam_param.cam_position != p->cam_position)
{
std::cout << "ERROR: ALL_Detect cam_position not match, expect: " << m_cam_param.cam_position
@ -72,41 +79,18 @@ int ALL_Detect::CheckImg(std::shared_ptr<shareImage> p, std::shared_ptr<CheckRes
if (p->detect_type == DETECT_TYPE_ANGLE)
{
if (p->cam_position != CAMERA_DOWN_1) {
if (p->cam_position != CAMERA_DOWN_1)
{
std::cout << "ERROR: Down_Angle_Detect only support CAMERA_DOWN_1" << std::endl;
return -2;
}
this->down_angle_detect.CheckImg(p, pResult);
}
else
{
switch (p->cam_position)
{
case CAMERA_TOP_1:
this->top_1_detect.CheckImg(p, pResult);
break;
case CAMERA_TOP_2:
this->top_2_detect.CheckImg(p, pResult);
break;
case CAMERA_SIDE_1:
this->side_1_detect.CheckImg(p, pResult);
break;
case CAMERA_SIDE_2:
this->side_2_detect.CheckImg(p, pResult);
break;
case CAMERA_DOWN_1:
this->down_detect.CheckImg(p, pResult);
break;
default:
break;
}
return this->m_down_angle_detect->CheckImg(p, pResult);
} else {
return this->m_checkBase->CheckImg(p, pResult);
}
return 0;
}
int ALL_Detect::UpdateConfig(void *pconfig, int nConfigType)
{
return 0;
return this->m_checkBase->UpdateConfig(pconfig, nConfigType);
}

@ -15,6 +15,7 @@ enum AI_Model_Type_
AI_Model_Type_Seg,
AI_Model_Type_Reconstruct,
AI_Model_Type_EdgeAngle,
AI_Model_Type_CodeAlign,
AI_Model_Type_Count,
};
enum AI_MODEL_TYPE_

@ -130,6 +130,8 @@ struct Base_Function_DetConfig
int chip_height_mm; // 芯片高度 mm 1107-add
int chip_width_offset_mm; // 芯片宽度偏差 mm
int chip_height_offset_mm; // 芯片高度偏差 mm 1107-add
double calibration_coeff_x; // 标定系数x mm/pixel
double calibration_coeff_y; // 标定系数y mm/pixel
Base_Function_DetConfig()
{
Init();
@ -144,6 +146,10 @@ struct Base_Function_DetConfig
pointArry.shrink_to_fit(); // 1107-add
chip_width_mm = 0; // 1107-add
chip_height_mm = 0; // 1107-add
chip_width_offset_mm = 0;
chip_height_offset_mm = 0;
calibration_coeff_x = 1.0; // 1107-add
calibration_coeff_y = 1.0; // 1107-add
}
void copy(Base_Function_DetConfig tem)
@ -155,6 +161,10 @@ struct Base_Function_DetConfig
this->LabelPolygonBoundingRect = tem.LabelPolygonBoundingRect; // 1107-add
this->chip_width_mm = tem.chip_width_mm; // 1107-add
this->chip_height_mm = tem.chip_height_mm; // 1107
this->chip_width_offset_mm = tem.chip_width_offset_mm;
this->chip_height_offset_mm = tem.chip_height_offset_mm;
this->calibration_coeff_x = tem.calibration_coeff_x; // 1107-add
this->calibration_coeff_y = tem.calibration_coeff_y; // 1107-add
}
void print(std::string str)
{

@ -452,9 +452,9 @@ int CheckBaseParamJson::GetFunction(Json::Value value)
}
// 芯片尺寸
pdetConfig->chip_width_mm = value_f["form"]["Chip_Size"]["ChipWidth"].asInt(); // 1020-add
pdetConfig->chip_height_mm = value_f["form"]["Chip_Size"]["ChipHeight"].asInt(); // 1020-add
pdetConfig->chip_width_offset_mm = value_f["form"]["Chip_Size"]["ChipWOffset"].asInt(); // 1020-add
pdetConfig->chip_width_mm = value_f["form"]["Chip_Size"]["ChipWidth"].asInt(); // 1020-add
pdetConfig->chip_height_mm = value_f["form"]["Chip_Size"]["ChipHeight"].asInt(); // 1020-add
pdetConfig->chip_width_offset_mm = value_f["form"]["Chip_Size"]["ChipWOffset"].asInt(); // 1020-add
pdetConfig->chip_height_offset_mm = value_f["form"]["Chip_Size"]["ChipHOffset"].asInt(); // 1020-add
// 旋转角度
@ -541,6 +541,18 @@ int CheckBaseParamJson::GetFunction(Json::Value value)
}
pdetConfig->LabelPolygonBoundingRect = cv::boundingRect(pdetConfig->pointArry); // 获取芯片区域的标记多边形最大外接矩形
}
// 标定系数
pdetConfig->calibration_coeff_x = value_f["form"]["Camera_Cali"]["x_coefficient"].asDouble(); // 1107-add
pdetConfig->calibration_coeff_y = value_f["form"]["Camera_Cali"]["y_coefficient"].asDouble(); // 1107-add
if (pdetConfig->calibration_coeff_x < 0)
{
pdetConfig->calibration_coeff_x = 0;
}
if (pdetConfig->calibration_coeff_y < 0)
{
pdetConfig->calibration_coeff_y = 0;
}
}
// else
// {

@ -47,6 +47,7 @@ public:
static cv::RotatedRect UpdataRotatedRect(cv::RotatedRect oldRrect, int start_x, int start_y, float fscale_x, float fscale_y);
static int adjustRectToBounds(cv::Rect &rect, const cv::Size &imgSize);
static double point2fDistance(const cv::Point2f &p1, const cv::Point2f &p2); // 1107-add
static cv::Point getCenterPoint(cv::Rect rect);//0922-add
};
template <typename... Args>
static std::string str_Format(const std::string &format, Args... args)

@ -515,3 +515,11 @@ double CheckUtil::point2fDistance(const cv::Point2f &p1, const cv::Point2f &p2)
double distance=std::sqrt(static_cast<double>(dx*dx+dy*dy));
return distance;
}
cv::Point CheckUtil::getCenterPoint(cv::Rect rect)
{
cv::Point cpt;
cpt.x=rect.x+cvRound(rect.width/2.0);
cpt.y=rect.y+cvRound(rect.height/2.0);
return cpt;
}

@ -22,6 +22,7 @@ Down_Angle_Detect::Down_Angle_Detect()
}
Down_Angle_Detect::~Down_Angle_Detect()
{
printf("----------------~Down_Angle_Detect \n");
}
int Down_Angle_Detect::RunStart(void *pconfig1)
@ -316,6 +317,11 @@ int Down_Angle_Detect::CheckRun()
Base_Function_DetConfig *pdetConfig = &m_CheckBaseConfig->baseCheckFunction.detconfig;
bool openFlag = pdetConfig->bOpen;
if (DetImgInfo_shareP->bdebugSaveImg)
{
bwriteImg = true;
}
// cv::Rect detROI = pdetConfig->cropROI;//检测ROI
// 获取产品ROI区域
auto t110 = CheckUtil::getcurTime();
@ -407,80 +413,21 @@ int Down_Angle_Detect::CheckRun()
// getchar();
}
// if ((LeftDownP.x < 0) || (LeftDownP.x > inputROIimg.cols - 1))
// {
// re = 1;
// }
// if ((LeftDownP.y < 0) || (LeftDownP.y > inputROIimg.rows - 1))
// {
// re = 2; // 1104-add
// }
cv::Point2f detROi2f{detROI.x, detROI.y};
cv::Point2f BigImgChipCenter = CenterP + detROi2f; // 1105
cv::Point2f CenterOffsetP = BigImgChipCenter - LabelCenterP;
std::cout << "OffsetXOut=" << CenterOffsetP.x << std::endl;
std::cout << "OffsetYOut=" << CenterOffsetP.y << std::endl;
// float offsetAngle=abs(angleOut-InputBaseAngle);//这里选择从界面读取的angle-可能不准
float offsetAngle = angleOut - LabelAngle; // //角度偏差
std::cout << "Offsetangle=" << offsetAngle << std::endl; // 1027-add
m_CheckResult_shareP->CenterOffsetX = CenterOffsetP.x; // 最终结果输出
m_CheckResult_shareP->CenterOffsetY = CenterOffsetP.y; // 最终结果输出
m_CheckResult_shareP->OffsetAngle = offsetAngle; // 最终结果输出 -此时取绝对值到下面来纠正正负1105
if (0 != re)
{
// 1013-添加画ERROR--
if (bwriteImg)
{
std::string str = "1after_DetImgInfo_shareP-img.png";
cv::imwrite(str, DetImgInfo_shareP->img);
}
// GetShowSrcImg(detimg, m_CheckResult_shareP->resultImg); //这样结果图在打开存图开关时会有红色矩形框
GetShowSrcImg(DetImgInfo_shareP->img, m_CheckResult_shareP->resultImg); // 这样也有
// 这里可以根据返回的int数字来决定返回的是"ERROR"还是"Param_ERROR"还是"Image_mohu"----
AddResultErrorImg(m_CheckResult_shareP->resultImg); // 画ERROR -1013-add 拿到外面来
// AddResultErrorImg(m_CheckResult_shareP->resultImg,"ERROR"); //1014-add
if (bwriteImg)
{
std::string str = "2after_DetImgInfo_shareP-img2.png";
cv::imwrite(str, DetImgInfo_shareP->img);
}
std::cout << "AddResultError-----------------Img------ERROR" << std::endl; // 1013-add
return re;
}
// cv::Point s2offsetPoint = LeftDownP - s2_LabelLineP1;
// cv::Point s2LabelOffsetRightDownP = s2_LabelLineP2 + s2offsetPoint; // 标记的点-相对右边偏移后的点
// // 此时标记的底边线段1和求得的底边线段2在左下角重合形成角度可以根据两线段右端点纵坐标Y的值来判断角度正负-1105
// // 如果s2RightDownP_out.y<s2LabelOffsetRightDownP.y,说明计算的标记点线段在上面,角度为负,
// // 如果大于则角度为正angle-90也可以计算得到旋转的角度保证旋转角度范围在(-90,0]之间
// if (RightDownP.y < s2LabelOffsetRightDownP.y)
// {
// m_CheckResult_shareP->OffsetAngle = -offsetAngle; // 负角度 顺时针
// std::cout << "up--------------------------------up" << std::endl;
// //std::cout << "m_CheckResult_shareP->Angle=" << m_CheckResult_shareP->Angle << std::endl;
// }
// else if (RightDownP.y > s2LabelOffsetRightDownP.y)
// {
// // m_CheckResult_shareP->Angle = offsetAngle - 90;
// m_CheckResult_shareP->OffsetAngle = offsetAngle; // 正角度 逆时针
// std::cout << "down--------------------------------down" << std::endl;
// //std::cout << "m_CheckResult_shareP->Angle=" << m_CheckResult_shareP->Angle << std::endl;
// }
bool drawLabelLineFlag = false;
re = Draw3(m_resultImg, m_CheckResult_shareP->resultImg, s2StartP, CenterP,
LabelCenterP, s2_LabelLineP1, s2_LabelLineP2, LeftDownP, RightDownP, drawLabelLineFlag);
double x_coeff = pdetConfig->calibration_coeff_x; // 1107-add
double y_coeff = pdetConfig->calibration_coeff_y; // 1107-add
m_CheckResult_shareP->CenterOffsetX = CenterOffsetP.x * x_coeff; // 最终结果输出
m_CheckResult_shareP->CenterOffsetY = CenterOffsetP.y * y_coeff; // 最终结果输出
m_CheckResult_shareP->OffsetAngle = offsetAngle;
std::cout << "OffsetXOut=" << CenterOffsetP.x << " resultMove" << m_CheckResult_shareP->CenterOffsetX << std::endl;
std::cout << "OffsetYOut=" << CenterOffsetP.y << " resultMove" << m_CheckResult_shareP->CenterOffsetY << std::endl;
std::cout << "Offsetangle=" << offsetAngle << std::endl;
if (0 != re)
{
// 这里其实没有返回由于画图错误导致的图像异常-返回的是ChipRoiImg -1014-add
return re;
}
t2 = CheckUtil::getcurTime();
m_CheckResult_shareP->UseTimeMS = t2 - t1;
// printf("Check time %ld \n", t2 - t1);
@ -767,7 +714,7 @@ int Down_Angle_Detect::AI_Run(const cv::Mat &img, cv::Point s2StartP, double Lab
{
continue;
}
//二次定位
// 二次定位
const int h = 360;
cv::Point start{MaxRoi.x, MaxRoi.y + MaxRoi.height - h / 2};
cv::Rect SecondAlignRoi{start.x, start.y, MaxRoi.width, h};
@ -827,7 +774,7 @@ int Down_Angle_Detect::AI_Run(const cv::Mat &img, cv::Point s2StartP, double Lab
cv::imwrite(str1, src_mask);
}
//取中间300宽度搜边
// 取中间300宽度搜边
const int w = 300;
cv::Rect roiRect{(outimg.cols - 300) / 2, 0, w, outimg.rows};
cv::Mat Roi_mask = outimg(roiRect);
@ -1067,65 +1014,73 @@ int Down_Angle_Detect::Draw3(const cv::Mat &img, cv::Mat &resultimg, cv::Point s
}
// 计算二值图像中分割线的角度
double Down_Angle_Detect::calculateSplitLineAngle(const cv::Mat& binaryImage) {
double Down_Angle_Detect::calculateSplitLineAngle(const cv::Mat &binaryImage)
{
// 检查图像是否有效
if (binaryImage.empty()) {
if (binaryImage.empty())
{
cerr << "img is empty" << endl;
return 0.0;
}
// 获取图像尺寸
int height = binaryImage.rows;
int width = binaryImage.cols;
// 存储边界点
vector<Point> boundaryPoints;
// 遍历每一列,找到白黑边界
for (int x = 0; x < width; x++) {
for (int y = 0; y < height - 1; y++) {
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height - 1; y++)
{
// 检查当前像素是白色(255)且下一个像素是黑色(0)
if (binaryImage.at<uchar>(y, x) == 255 &&
binaryImage.at<uchar>(y + 1, x) == 0) {
if (binaryImage.at<uchar>(y, x) == 255 &&
binaryImage.at<uchar>(y + 1, x) == 0)
{
boundaryPoints.push_back(Point(x, y));
break; // 找到该列的边界点后跳出内层循环
}
}
}
// 检查是否找到足够的边界点
if (boundaryPoints.size() < 2) {
if (boundaryPoints.size() < 2)
{
cerr << "edge point not Enough" << endl;
return 0.0;
}
// 使用最小二乘法拟合直线 y = mx + b
double sumX = 0.0, sumY = 0.0, sumXY = 0.0, sumX2 = 0.0;
int n = boundaryPoints.size();
for (const auto& point : boundaryPoints) {
for (const auto &point : boundaryPoints)
{
double x = point.x;
double y = point.y;
sumX += x;
sumY += y;
sumXY += x * y;
sumX2 += x * x;
}
// 计算斜率 m 和截距 b
double denominator = n * sumX2 - sumX * sumX;
if (fabs(denominator) < 1e-10) {
if (fabs(denominator) < 1e-10)
{
// 垂直线情况
return 90.0;
}
double m = (n * sumXY - sumX * sumY) / denominator;
double b = (sumY - m * sumX) / n;
// 计算角度(弧度转角度)
double angleRad = atan(m);
double angleDeg = angleRad * 180.0 / CV_PI;
return angleDeg;
}

@ -39,6 +39,8 @@ private:
int DetectImg(const cv::Mat &img);
std::tuple<double, cv::Point> templateMatchBasic(const cv::Mat& src, const cv::Mat& templ, int method = cv::TM_CCOEFF_NORMED);
private:
int m_nErrorCode; // 错误代码
std::shared_ptr<shareImage> DetImgInfo_shareP;

@ -505,23 +505,41 @@ int Down_Detect::ImgAlinRotate(const cv::Mat &img, cv::Mat &alignImg)
return 1;
}
DetRotateType ratio = m_CheckBaseConfig->baseCheckFunction.detconfig.rotate;
std::cout << "rotate ratio : " << ratio << std::endl;
if (ratio == Ratio_0)
{
}
else if (ratio == Ratio_90)
{
cv::rotate(alignImg, alignImg, cv::ROTATE_90_COUNTERCLOCKWISE);
}
else if (ratio == Ratio_180)
{
cv::rotate(alignImg, alignImg, cv::ROTATE_180);
}
else if (ratio == Ratio_270)
{
cv::rotate(alignImg, alignImg, cv::ROTATE_90_CLOCKWISE); // 270° 逆时针 == 90° 顺时针
}
// DetRotateType ratio = m_CheckBaseConfig->baseCheckFunction.detconfig.rotate;
// std::cout << "rotate ratio : " << ratio << std::endl;
// if (ratio == Ratio_0)
// {
// }
// else if (ratio == Ratio_90)
// {
// cv::rotate(alignImg, alignImg, cv::ROTATE_90_COUNTERCLOCKWISE);
// }
// else if (ratio == Ratio_180)
// {
// cv::rotate(alignImg, alignImg, cv::ROTATE_180);
// }
// else if (ratio == Ratio_270)
// {
// cv::rotate(alignImg, alignImg, cv::ROTATE_90_CLOCKWISE); // 270° 逆时针 == 90° 顺时针
// }
// // 模板匹配定位
// cv::Mat alignImg_copy = alignImg.clone();
// cv::resize(alignImg_copy, alignImg_copy, cv::Size(800, 600));
// cv::imwrite("alignImg_copy.png", alignImg_copy);
// cv::Mat templ1 = cv::imread("/home/aidlux/zhangzhi/ZYWL/AJX-ZYWL/data/Down_Det/dt1.png", cv::IMREAD_COLOR);//正
// cv::Mat templ2 = cv::imread("/home/aidlux/zhangzhi/ZYWL/AJX-ZYWL/data/Down_Det/dt2.png", cv::IMREAD_COLOR);//倒
// auto [maxVal1, matchPoint1] = templateMatchBasic(alignImg_copy, templ1, cv::TM_CCOEFF_NORMED);
// auto [maxVal2, matchPoint2] = templateMatchBasic(alignImg_copy, templ2, cv::TM_CCOEFF_NORMED);
// // cv::rectangle(alignImg_copy, matchPoint1,
// // cv::Point(matchPoint1.x + templ1.cols, matchPoint1.y + templ1.rows),
// // cv::Scalar(0, 255, 0), 2); // 绿色矩形
// // cv::imwrite("alignImg_temMatch.png", alignImg_copy);
// if (maxVal2 > maxVal1)
// {
// // 需要旋转
// cv::rotate(alignImg, alignImg, cv::ROTATE_180);
// }
return 0;
}
@ -739,3 +757,35 @@ int Down_Detect::DetectImg(const cv::Mat &img)
// getchar();
return 0;
}
std::tuple<double, cv::Point> Down_Detect::templateMatchBasic(const Mat &src, const Mat &templ, int method)
{
Mat result;
// 检查图像和模板大小
if (src.cols < templ.cols || src.rows < templ.rows)
{
cerr << "template size > src size" << endl;
return std::make_tuple(0, cv::Point(-1, -1));
}
// 执行模板匹配
matchTemplate(src, templ, result, method);
// 寻找最佳匹配位置
double minVal, maxVal;
Point minLoc, maxLoc;
minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);
// 根据匹配方法返回最佳位置
Point bestMatch;
if (method == TM_SQDIFF || method == TM_SQDIFF_NORMED)
{
bestMatch = minLoc;
}
else
{
bestMatch = maxLoc;
}
return std::make_tuple(maxVal, bestMatch);
}

@ -20,7 +20,6 @@ public:
// 更新参数 pconfig 参数指针nConfigType 需要更新的参数类型 返回0 成功 其他异常
int UpdateConfig(void *pconfig, int nConfigType);
public:
private:
// 检测
int CheckRun();

@ -492,34 +492,151 @@ int Top_Detect::ImgAlinRotate(const cv::Mat &img, cv::Mat &alignImg)
}
// 判断尺寸
int w = m_CheckBaseConfig->baseCheckFunction.detconfig.chip_width_mm / m_CheckBaseConfig->imageScaleParam.fScale_X;
int h = m_CheckBaseConfig->baseCheckFunction.detconfig.chip_height_mm / m_CheckBaseConfig->imageScaleParam.fScale_Y;
auto w_offset = std::abs(w - m_AlignMaxRoi.width);
auto h_offset = std::abs(h - m_AlignMaxRoi.height);
int param_w_offset = m_CheckBaseConfig->baseCheckFunction.detconfig.chip_width_offset_mm / m_CheckBaseConfig->imageScaleParam.fScale_X;
int param_h_offset = m_CheckBaseConfig->baseCheckFunction.detconfig.chip_height_offset_mm / m_CheckBaseConfig->imageScaleParam.fScale_Y;
if (w_offset > param_w_offset || h_offset > param_h_offset)
{
printf("Align error, no product\n");
return 1;
}
DetRotateType ratio = m_CheckBaseConfig->baseCheckFunction.detconfig.rotate;
std::cout << "rotate ratio : " << ratio << std::endl;
if (ratio == Ratio_0)
{
int w = m_CheckBaseConfig->baseCheckFunction.detconfig.chip_width_mm / m_CheckBaseConfig->imageScaleParam.fScale_X;
int h = m_CheckBaseConfig->baseCheckFunction.detconfig.chip_height_mm / m_CheckBaseConfig->imageScaleParam.fScale_Y;
auto w_offset = std::abs(w - m_AlignMaxRoi.width);
auto h_offset = std::abs(h - m_AlignMaxRoi.height);
int param_w_offset = m_CheckBaseConfig->baseCheckFunction.detconfig.chip_width_offset_mm / m_CheckBaseConfig->imageScaleParam.fScale_X;
int param_h_offset = m_CheckBaseConfig->baseCheckFunction.detconfig.chip_height_offset_mm / m_CheckBaseConfig->imageScaleParam.fScale_Y;
if (w_offset > param_w_offset || h_offset > param_h_offset)
{
printf("Align error, no product\n");
return 1;
}
else if (ratio == Ratio_90)
// DetRotateType ratio = m_CheckBaseConfig->baseCheckFunction.detconfig.rotate;
// std::cout << "rotate ratio : " << ratio << std::endl;
// if (ratio == Ratio_0)
// {
// }
// else if (ratio == Ratio_90)
// {
// cv::rotate(alignImg, alignImg, cv::ROTATE_90_COUNTERCLOCKWISE);
// }
// else if (ratio == Ratio_180)
// {
// cv::rotate(alignImg, alignImg, cv::ROTATE_180);
// }
// else if (ratio == Ratio_270)
// {
// cv::rotate(alignImg, alignImg, cv::ROTATE_90_CLOCKWISE); // 270° 逆时针 == 90° 顺时针
// }
// 二维码定位处理
long t12, t13;
t12 = CheckUtil::getcurTime();
cv::Mat ColorCodeImg;
if (alignImg.channels() == 1)
{
cv::rotate(alignImg, alignImg, cv::ROTATE_90_COUNTERCLOCKWISE);
cv::cvtColor(alignImg, ColorCodeImg, cv::COLOR_GRAY2BGR);
}
else if (ratio == Ratio_180)
else
{
cv::rotate(alignImg, alignImg, cv::ROTATE_180);
ColorCodeImg = alignImg;
}
else if (ratio == Ratio_270)
for (int i = 0; i < m_AIModelConfigList->AIModelConfigList.size(); i++)
{
cv::rotate(alignImg, alignImg, cv::ROTATE_90_CLOCKWISE); // 270° 逆时针 == 90° 顺时针
AI_Model_Param *p = &m_AIModelConfigList->AIModelConfigList.at(i);
std::cout << "p->name=" << p->strAIModelName << std::endl; // 0924-add
std::cout << "p->strModelPath=" << p->strModelPath << std::endl; // 0924-add
std::cout << "p->type=" << p->type << std::endl; // 1015-add
// getchar();//0924-add
// 定位类型
if (p->type != AI_Model_Type_CodeAlign)
{
continue;
}
long t1, t2, t3;
t1 = CheckUtil::getcurTime();
cv::Size sz;
sz.width = p->in_img.width;
sz.height = p->in_img.height;
cv::Mat temimg2;
cv::resize(ColorCodeImg, temimg2, sz);
AlignToSrc.setResize(ColorCodeImg, temimg2);
if (bwriteImg)
{
std::string str = p->strAIModelName + "_AI_in.png";
cv::imwrite(str, temimg2);
}
cv::Mat outimg;
if ((p->pdetect->run(temimg2, outimg, false)) == 0) // 加载加密后的.bin.aidem文件
{
std::cout << "CodeAlign----p->pdetect->run--success---" << std::endl;
}
else
{
std::cout << "CodeAlign----p->pdetect->run--failed--- return 5" << std::endl;
return 5; // 返回5
}
t2 = CheckUtil::getcurTime();
std::cout << "1.2 codeLoc model-run-----time cost -----------" << t2 - t1 << "ms" << std::endl;
if (bwriteImg)
{
std::string str = p->strAIModelName + "_AI_out.png";
cv::imwrite(str, outimg);
}
cv::Mat src_mask;
cv::resize(outimg, src_mask, cv::Size(ColorCodeImg.cols, ColorCodeImg.rows));
if (bwriteImg)
{
std::string str = p->strAIModelName + "_AI_mask.png";
cv::imwrite(str, src_mask);
}
// 求取二维码位置
cv::Rect codeLocRoi = CheckUtil::findMaxBoundingBox(outimg); // 直接在输入模型图像上找-更节省时间
if (codeLocRoi.empty())
{
std::cout << "CodeAlign---no--Product" << std::endl;
return 6; // 返回6
}
if (bwriteImg)
{
cv::Mat codeLocShowImg;
if (1 == outimg.channels())
{
cvtColor(outimg, codeLocShowImg, cv::COLOR_GRAY2BGR);
}
else if (3 == outimg.channels())
{
codeLocShowImg = outimg.clone();
}
cv::rectangle(codeLocShowImg, codeLocRoi, cv::Scalar(0, 0, 255), 2, 8);
std::string str = p->strAIModelName + "_CodeLocShow.png";
cv::imwrite(str, codeLocShowImg);
}
cv::Point codeCenterPt = CheckUtil::getCenterPoint(codeLocRoi); // CheckUtil::getCenterPoint
if (m_pRunConfig.flag0 == CAMERA_TOP_1)
{
if (codeCenterPt.x < outimg.cols / 2)
{
// 二维码在左侧则旋转90°逆时针
cv::rotate(alignImg, alignImg, cv::ROTATE_90_COUNTERCLOCKWISE);
}
else if(codeCenterPt.x > outimg.cols / 2)
{
// 二维码在右侧则旋转90°顺时针
cv::rotate(alignImg, alignImg, cv::ROTATE_90_CLOCKWISE);
}
}
else if (m_pRunConfig.flag0 == CAMERA_TOP_2)
{
// 二维码在上方则旋转180°
if (codeCenterPt.y < outimg.rows / 2)
{
cv::rotate(alignImg, alignImg, cv::ROTATE_180);
}
}
}
return 0;
@ -739,3 +856,4 @@ int Top_Detect::DetectImg(const cv::Mat &img)
// getchar();
return 0;
}

Loading…
Cancel
Save