|
|
|
|
@ -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;
|
|
|
|
|
}
|