|
|
|
@ -31,7 +31,7 @@ static bool compareContourAreas(const vector<Point> &contour1, const vector<Poin
|
|
|
|
return (i > j);
|
|
|
|
return (i > j);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 2x3 仿射矩阵小工具:变换点、矩形外接、组合矩阵(检测图摆正用)
|
|
|
|
// 2x3 仿射矩阵小工具:变换点、矩形外接、组合矩阵(检测图裁剪坐标映射用)
|
|
|
|
static cv::Point2f MatAffinePoint(const cv::Mat &mat32, const cv::Point2f &pt)
|
|
|
|
static cv::Point2f MatAffinePoint(const cv::Mat &mat32, const cv::Point2f &pt)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (mat32.empty() || mat32.rows != 2 || mat32.cols != 3)
|
|
|
|
if (mat32.empty() || mat32.rows != 2 || mat32.cols != 3)
|
|
|
|
@ -482,63 +482,6 @@ int ImgCheckAnalysisy::Adapt_Config(RotatedRect tplOuterRect, RotatedRect curOut
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 应用内 OpenCV 线程池随首个调用线程(通常为先绑核的检测线程)初始化成单线程,parallel_for 实际串行,
|
|
|
|
|
|
|
|
// 全分辨率 warp 要 150~200ms;这里把输出按行切条、用独立线程并行 warp,
|
|
|
|
|
|
|
|
// 结果与整图 warpAffine 逐像素一致(已离线验证 maxdiff=0),耗时降到约 1/3
|
|
|
|
|
|
|
|
static void WarpAffineBandParallel(const cv::Mat &src, cv::Mat &dst, const cv::Mat &affine,
|
|
|
|
|
|
|
|
const cv::Size &size, int nThreads = 8, int interp = cv::INTER_LINEAR,
|
|
|
|
|
|
|
|
int borderType = cv::BORDER_REPLICATE)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
dst.create(size, src.type());
|
|
|
|
|
|
|
|
nThreads = std::max(1, std::min(nThreads, size.height));
|
|
|
|
|
|
|
|
int bandH = (size.height + nThreads - 1) / nThreads;
|
|
|
|
|
|
|
|
int nBands = (size.height + bandH - 1) / bandH;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto warpBand = [&](int b)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// 新建线程默认继承调用线程的 CPU 亲和性(检测线程已绑单核),这里放开到全核,让条带真正并行
|
|
|
|
|
|
|
|
cpu_set_t cpus;
|
|
|
|
|
|
|
|
CPU_ZERO(&cpus);
|
|
|
|
|
|
|
|
long ncpu = sysconf(_SC_NPROCESSORS_ONLN);
|
|
|
|
|
|
|
|
for (long i = 0; i < ncpu; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
CPU_SET(i, &cpus);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
pthread_setaffinity_np(pthread_self(), sizeof(cpus), &cpus);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int y0 = b * bandH;
|
|
|
|
|
|
|
|
int h = std::min(bandH, size.height - y0);
|
|
|
|
|
|
|
|
// warpAffine 默认接收正向矩阵(src->dst)并内部求逆;条带只把输出平移项减去 y0
|
|
|
|
|
|
|
|
cv::Mat matBand = affine.clone();
|
|
|
|
|
|
|
|
matBand.at<double>(1, 2) -= y0;
|
|
|
|
|
|
|
|
cv::warpAffine(src, dst(cv::Rect(0, y0, size.width, h)), matBand,
|
|
|
|
|
|
|
|
cv::Size(size.width, h), interp, borderType);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<std::thread> threads;
|
|
|
|
|
|
|
|
threads.reserve(nBands);
|
|
|
|
|
|
|
|
int b = 0;
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for (; b < nBands; b++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
threads.emplace_back(warpBand, b);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
catch (const std::system_error &)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// 线程资源不足:剩余条带留在本线程串行补完
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for (auto &t : threads)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
t.join();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for (; b < nBands; b++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
warpBand(b);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 暗场复用明场定位:把字符串里的 "dark"(大小写不敏感)替换为 "bright";未命中返回空串
|
|
|
|
// 暗场复用明场定位:把字符串里的 "dark"(大小写不敏感)替换为 "bright";未命中返回空串
|
|
|
|
static std::string ReplaceDarkWithBright(const std::string &strIn)
|
|
|
|
static std::string ReplaceDarkWithBright(const std::string &strIn)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -854,76 +797,60 @@ int ImgCheckAnalysisy::CheckRun()
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_0, "2、pre detect", "-------------------------AI_Edge------------succ---time %ld----\n", time_edge_e - time_edge_s);
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_0, "2、pre detect", "-------------------------AI_Edge------------succ---time %ld----\n", time_edge_e - time_edge_s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*生成检测图:用 m_outer_rroi(旋转矩形)确定产品区域,并把该区域旋转摆正后输出;
|
|
|
|
/*生成检测图:用 m_outer_rroi(旋转矩形)的外接区域直接从原图裁剪(不再旋转摆正,省掉旋转重采样耗时);
|
|
|
|
原图坐标 -> 检测图坐标 的映射存入 m_matSrc2Det / m_matDet2Src,后续坐标换算都走这对矩阵*/
|
|
|
|
原图坐标 -> 检测图坐标 的映射为纯平移,存入 m_matSrc2Det / m_matDet2Src,后续坐标换算仍走这对矩阵*/
|
|
|
|
cv::Mat image = m_CheckResult_shareP->in_shareImage->img;
|
|
|
|
cv::Mat image = m_CheckResult_shareP->in_shareImage->img;
|
|
|
|
cv::Rect imgRect(0, 0, image.cols, image.rows);
|
|
|
|
cv::Rect imgRect(0, 0, image.cols, image.rows);
|
|
|
|
|
|
|
|
|
|
|
|
// 1、旋转矩形四角 -> 轴对齐矩形四角 的仿射(把产品摆正;用顶点计算,避开 RotatedRect 角度约定的歧义)
|
|
|
|
// 1、检测图裁剪区域 = 旋转矩形外接区域(与原图求交,防越界)
|
|
|
|
std::vector<cv::Point2f> vtx = CheckUtil::sort_vertices(m_outer_rroi); // 近似 左上/右上/左下/右下
|
|
|
|
|
|
|
|
int detW = std::max(1, cvRound(cv::norm(vtx[1] - vtx[0])));
|
|
|
|
|
|
|
|
int detH = std::max(1, cvRound(cv::norm(vtx[2] - vtx[0])));
|
|
|
|
|
|
|
|
cv::Point2f srcTri[3] = {vtx[0], vtx[1], vtx[2]};
|
|
|
|
|
|
|
|
cv::Point2f dstTri[3] = {cv::Point2f(0, 0), cv::Point2f((float)detW, 0), cv::Point2f(0, (float)detH)};
|
|
|
|
|
|
|
|
m_matSrc2Det = cv::getAffineTransform(srcTri, dstTri);
|
|
|
|
|
|
|
|
cv::invertAffineTransform(m_matSrc2Det, m_matDet2Src);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 2、只对旋转矩形附近区域做 warp,提高效率;先裁到该区域,warp 矩阵同步做平移补偿
|
|
|
|
|
|
|
|
cv::Rect padRoi = m_outer_rroi.boundingRect() & imgRect;
|
|
|
|
cv::Rect padRoi = m_outer_rroi.boundingRect() & imgRect;
|
|
|
|
if (padRoi.width <= 0 || padRoi.height <= 0)
|
|
|
|
if (padRoi.width <= 0 || padRoi.height <= 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_1, "Error", "deskew roi error [%d %d %d %d]", padRoi.x, padRoi.y, padRoi.width, padRoi.height);
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_1, "Error", "crop roi error [%d %d %d %d]", padRoi.x, padRoi.y, padRoi.width, padRoi.height);
|
|
|
|
m_nErrorCode = CHECK_ERROR_CheckImg_Empty;
|
|
|
|
m_nErrorCode = CHECK_ERROR_CheckImg_Empty;
|
|
|
|
m_nCheckResultErrorCode = m_nErrorCode;
|
|
|
|
m_nCheckResultErrorCode = m_nErrorCode;
|
|
|
|
return m_nErrorCode;
|
|
|
|
return m_nErrorCode;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cv::Mat matPad = m_matSrc2Det.clone();
|
|
|
|
int detW = padRoi.width;
|
|
|
|
matPad.at<double>(0, 2) += matPad.at<double>(0, 0) * padRoi.x + matPad.at<double>(0, 1) * padRoi.y;
|
|
|
|
int detH = padRoi.height;
|
|
|
|
matPad.at<double>(1, 2) += matPad.at<double>(1, 0) * padRoi.x + matPad.at<double>(1, 1) * padRoi.y;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 3、检测图:单通道灰度(彩色原图按 BGR 顺序转灰度,与 imread(path,0) 的亮度一致),按摆正矩阵重采样;
|
|
|
|
// 2、原图 -> 检测图 为纯平移(无旋转):检测图坐标 = 原图坐标 - 裁剪原点
|
|
|
|
// 彩色结果图在 ResizeImg 里按显示尺寸直接 warp(比全分辨率彩色 warp 省很多)
|
|
|
|
m_matSrc2Det = (cv::Mat_<double>(2, 3) << 1, 0, -(double)padRoi.x, 0, 1, -(double)padRoi.y);
|
|
|
|
|
|
|
|
m_matDet2Src = (cv::Mat_<double>(2, 3) << 1, 0, (double)padRoi.x, 0, 1, (double)padRoi.y);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 3、检测图:单通道灰度(彩色原图按 BGR 顺序转灰度,与 imread(path,0) 的亮度一致),直接裁剪;
|
|
|
|
|
|
|
|
// 彩色原图时再输出一张同样裁剪的彩色检测图,供裁剪图(_RE_CutImg)保存时保留原图通道
|
|
|
|
|
|
|
|
// (检测算法仍只用灰度 detImg)
|
|
|
|
m_deskewPadRoi = padRoi;
|
|
|
|
m_deskewPadRoi = padRoi;
|
|
|
|
cv::Mat colorPatch = image(padRoi);
|
|
|
|
cv::Mat colorPatch = image(padRoi);
|
|
|
|
cv::Mat grayPatch;
|
|
|
|
|
|
|
|
if (colorPatch.channels() == 1)
|
|
|
|
if (colorPatch.channels() == 1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
grayPatch = colorPatch;
|
|
|
|
colorPatch.copyTo(m_pImageAllResult->detImg);
|
|
|
|
|
|
|
|
m_pImageAllResult->detColorImg.release();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (colorPatch.channels() == 3)
|
|
|
|
else if (colorPatch.channels() == 3)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
cv::cvtColor(colorPatch, grayPatch, cv::COLOR_BGR2GRAY);
|
|
|
|
cv::cvtColor(colorPatch, m_pImageAllResult->detImg, cv::COLOR_BGR2GRAY);
|
|
|
|
}
|
|
|
|
colorPatch.copyTo(m_pImageAllResult->detColorImg);
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
cv::cvtColor(colorPatch, grayPatch, cv::COLOR_BGRA2GRAY);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
WarpAffineBandParallel(grayPatch, m_pImageAllResult->detImg, matPad, cv::Size(detW, detH));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 彩色原图时再输出一张同样摆正的彩色检测图:供裁剪图(_RE_CutImg)保存时保留原图通道
|
|
|
|
|
|
|
|
// (检测算法仍只用灰度 detImg)
|
|
|
|
|
|
|
|
if (colorPatch.channels() == 3 || colorPatch.channels() == 4)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
WarpAffineBandParallel(colorPatch, m_pImageAllResult->detColorImg, matPad, cv::Size(detW, detH));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
m_pImageAllResult->detColorImg.release();
|
|
|
|
cv::cvtColor(colorPatch, m_pImageAllResult->detImg, cv::COLOR_BGRA2GRAY);
|
|
|
|
|
|
|
|
colorPatch.copyTo(m_pImageAllResult->detColorImg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 4、检测图坐标系下 m_outer_roi 即整张检测图;原图坐标系下 CutRoi 仍取旋转矩形外接区域(兼容旧语义/JSON)
|
|
|
|
// 4、检测图坐标系下 m_outer_roi 即整张检测图;原图坐标系下 CutRoi 仍取旋转矩形外接区域(兼容旧语义/JSON)
|
|
|
|
m_outer_roi = cv::Rect(0, 0, detW, detH);
|
|
|
|
m_outer_roi = cv::Rect(0, 0, detW, detH);
|
|
|
|
m_Crop_Roi_paramImg = m_outer_rroi.boundingRect() & imgRect;
|
|
|
|
m_Crop_Roi_paramImg = padRoi;
|
|
|
|
m_pImageAllResult->pDetResult->CutRoi = m_Crop_Roi_paramImg;
|
|
|
|
m_pImageAllResult->pDetResult->CutRoi = m_Crop_Roi_paramImg;
|
|
|
|
m_pImageAllResult->pDetResult->Param_CropRoi = m_Crop_Roi_paramImg;
|
|
|
|
m_pImageAllResult->pDetResult->Param_CropRoi = m_Crop_Roi_paramImg;
|
|
|
|
// 检测图坐标 -> 原图坐标 的映射,供结果解析时取回缺陷小图/换算坐标
|
|
|
|
// 检测图坐标 -> 原图坐标 的映射,供结果解析时取回缺陷小图/换算坐标
|
|
|
|
m_pImageAllResult->pDetResult->detToSrcMat = m_matDet2Src.clone();
|
|
|
|
m_pImageAllResult->pDetResult->detToSrcMat = m_matDet2Src.clone();
|
|
|
|
|
|
|
|
|
|
|
|
// 5、参数(模板)坐标 -> 检测图坐标 的映射:
|
|
|
|
// 5、参数(模板)坐标 -> 检测图坐标 的映射:
|
|
|
|
// 有对齐时先把参数点映射到原图再摆正;无对齐时参数按产品坐标系处理(与摆正后的检测图同向),
|
|
|
|
// 有对齐时先把参数点映射到原图再平移到检测图;无对齐时参数按原图坐标系处理,
|
|
|
|
// 直接按旋转矩形中心平移(θ=0 时与旧的裁剪平移完全一致,旋转/平移变化时区域跟随产品)
|
|
|
|
// 直接按裁剪原点平移(与旧的裁剪平移完全一致)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
cv::RotatedRect &rroi = m_outer_rroi;
|
|
|
|
|
|
|
|
if (m_pEdge_Align_Result && m_pEdge_Align_Result->buseOfft)
|
|
|
|
if (m_pEdge_Align_Result && m_pEdge_Align_Result->buseOfft)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (!m_pEdge_Align_Result->H.empty())
|
|
|
|
if (!m_pEdge_Align_Result->H.empty())
|
|
|
|
@ -938,11 +865,11 @@ int ImgCheckAnalysisy::CheckRun()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
m_matParam2Det = (cv::Mat_<double>(2, 3) << 1, 0, -rroi.center.x + detW * 0.5, 0, 1, -rroi.center.y + detH * 0.5);
|
|
|
|
m_matParam2Det = m_matSrc2Det.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
long time_calan_e = CheckUtil::getcurTime();
|
|
|
|
long time_calan_e = CheckUtil::getcurTime();
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_0, "2.1、pre detect", "-------------------------deskew--------------succ--- det [%d %d] src bbox [%d %d %d %d] time %ld----\n",
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_0, "2.1、pre detect", "-------------------------crop--------------succ--- det [%d %d] src bbox [%d %d %d %d] time %ld----\n",
|
|
|
|
detW, detH, m_Crop_Roi_paramImg.x, m_Crop_Roi_paramImg.y, m_Crop_Roi_paramImg.width, m_Crop_Roi_paramImg.height,
|
|
|
|
detW, detH, m_Crop_Roi_paramImg.x, m_Crop_Roi_paramImg.y, m_Crop_Roi_paramImg.width, m_Crop_Roi_paramImg.height,
|
|
|
|
time_calan_e - time_edge_s);
|
|
|
|
time_calan_e - time_edge_s);
|
|
|
|
/*多线程开启 AI 推理检测*/
|
|
|
|
/*多线程开启 AI 推理检测*/
|
|
|
|
@ -988,7 +915,7 @@ int ImgCheckAnalysisy::CheckRun()
|
|
|
|
QX_ERROR_INFO_ temerror;
|
|
|
|
QX_ERROR_INFO_ temerror;
|
|
|
|
temerror.Idx = m_pDetResult->pQx_ErrorList->size();
|
|
|
|
temerror.Idx = m_pDetResult->pQx_ErrorList->size();
|
|
|
|
|
|
|
|
|
|
|
|
// roi 在原图坐标系,按摆正仿射转换到检测图(detImg)坐标系
|
|
|
|
// roi 在原图坐标系,按坐标映射转换到检测图(detImg)坐标系
|
|
|
|
cv::Rect roi = MatAffineRect(m_matSrc2Det, inner.boundingRect());
|
|
|
|
cv::Rect roi = MatAffineRect(m_matSrc2Det, inner.boundingRect());
|
|
|
|
roi &= cv::Rect(0, 0, m_pImageAllResult->detImg.cols, m_pImageAllResult->detImg.rows);
|
|
|
|
roi &= cv::Rect(0, 0, m_pImageAllResult->detImg.cols, m_pImageAllResult->detImg.rows);
|
|
|
|
temerror.roi = roi;
|
|
|
|
temerror.roi = roi;
|
|
|
|
@ -1106,7 +1033,7 @@ int ImgCheckAnalysisy::CheckRun()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (const auto &tagRoi : m_tag_roiList)
|
|
|
|
for (const auto &tagRoi : m_tag_roiList)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// tag roi 在原图坐标系,按摆正仿射转换到检测图(detImg)坐标系
|
|
|
|
// tag roi 在原图坐标系,按坐标映射转换到检测图(detImg)坐标系
|
|
|
|
cv::Rect roi = MatAffineRect(m_matSrc2Det, tagRoi.boundingRect());
|
|
|
|
cv::Rect roi = MatAffineRect(m_matSrc2Det, tagRoi.boundingRect());
|
|
|
|
roi &= cv::Rect(0, 0, m_pImageAllResult->detImg.cols, m_pImageAllResult->detImg.rows);
|
|
|
|
roi &= cv::Rect(0, 0, m_pImageAllResult->detImg.cols, m_pImageAllResult->detImg.rows);
|
|
|
|
if (roi.width <= 0 || roi.height <= 0)
|
|
|
|
if (roi.width <= 0 || roi.height <= 0)
|
|
|
|
@ -2212,27 +2139,15 @@ int ImgCheckAnalysisy::ResizeImg()
|
|
|
|
float fw = RESIZE_IMAGE_WIDTH * 1.0f / m_pImageAllResult->detImg.cols;
|
|
|
|
float fw = RESIZE_IMAGE_WIDTH * 1.0f / m_pImageAllResult->detImg.cols;
|
|
|
|
sz.height = int(m_pImageAllResult->detImg.rows * fw);
|
|
|
|
sz.height = int(m_pImageAllResult->detImg.rows * fw);
|
|
|
|
|
|
|
|
|
|
|
|
// 结果图画布在显示尺寸上按摆正矩阵直接从原图重采样(保持原图通道 -> 真实彩色,不再灰度转假彩);
|
|
|
|
// 结果图画布取自原图裁剪区(平移映射),保持原图通道(彩色原图 -> 真实彩色,不再灰度转假彩);
|
|
|
|
// 异常情况(如未走摆正流程)直接用检测图兜底
|
|
|
|
// 异常情况(如未走裁剪流程)直接用检测图兜底
|
|
|
|
const cv::Mat &srcImg = m_CheckResult_shareP->in_shareImage->img;
|
|
|
|
const cv::Mat &srcImg = m_CheckResult_shareP->in_shareImage->img;
|
|
|
|
if (m_CheckResult_shareP->in_shareImage->Det_Mode != DET_MODE_ReJson &&
|
|
|
|
if (m_CheckResult_shareP->in_shareImage->Det_Mode != DET_MODE_ReJson &&
|
|
|
|
!srcImg.empty() && !m_matSrc2Det.empty() &&
|
|
|
|
!srcImg.empty() &&
|
|
|
|
m_deskewPadRoi.width > 0 && m_deskewPadRoi.height > 0 &&
|
|
|
|
m_deskewPadRoi.width > 0 && m_deskewPadRoi.height > 0 &&
|
|
|
|
CheckUtil::RoiInImg(m_deskewPadRoi, srcImg))
|
|
|
|
CheckUtil::RoiInImg(m_deskewPadRoi, srcImg))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// M_disp = 显示缩放 ∘ M_src2det,并把输入平移到原图裁剪区(padRoi)的局部坐标
|
|
|
|
cv::resize(srcImg(m_deskewPadRoi), m_pImageAllResult->resultImg, sz);
|
|
|
|
cv::Mat matDisp = m_matSrc2Det.clone();
|
|
|
|
|
|
|
|
double fsx = sz.width * 1.0 / m_pImageAllResult->detImg.cols;
|
|
|
|
|
|
|
|
double fsy = sz.height * 1.0 / m_pImageAllResult->detImg.rows;
|
|
|
|
|
|
|
|
matDisp.at<double>(0, 0) *= fsx;
|
|
|
|
|
|
|
|
matDisp.at<double>(0, 1) *= fsx;
|
|
|
|
|
|
|
|
matDisp.at<double>(0, 2) *= fsx;
|
|
|
|
|
|
|
|
matDisp.at<double>(1, 0) *= fsy;
|
|
|
|
|
|
|
|
matDisp.at<double>(1, 1) *= fsy;
|
|
|
|
|
|
|
|
matDisp.at<double>(1, 2) *= fsy;
|
|
|
|
|
|
|
|
matDisp.at<double>(0, 2) += matDisp.at<double>(0, 0) * m_deskewPadRoi.x + matDisp.at<double>(0, 1) * m_deskewPadRoi.y;
|
|
|
|
|
|
|
|
matDisp.at<double>(1, 2) += matDisp.at<double>(1, 0) * m_deskewPadRoi.x + matDisp.at<double>(1, 1) * m_deskewPadRoi.y;
|
|
|
|
|
|
|
|
cv::warpAffine(srcImg(m_deskewPadRoi), m_pImageAllResult->resultImg, matDisp, sz, cv::INTER_LINEAR, cv::BORDER_REPLICATE);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -2281,7 +2196,7 @@ int ImgCheckAnalysisy::Update_DetRoiList()
|
|
|
|
float fx = m_pImageAllResult->fscale_detToresult_x;
|
|
|
|
float fx = m_pImageAllResult->fscale_detToresult_x;
|
|
|
|
float fy = m_pImageAllResult->fscale_detToresult_y;
|
|
|
|
float fy = m_pImageAllResult->fscale_detToresult_y;
|
|
|
|
|
|
|
|
|
|
|
|
// 参数多边形 -> 检测图(摆正坐标系) 的映射在摆正时已算好(m_matParam2Det)
|
|
|
|
// 参数多边形 -> 检测图(裁剪坐标系) 的映射在裁剪时已算好(m_matParam2Det)
|
|
|
|
for (const auto ®ion : m_pCommonAnalysisyConfig->regionConfigArr)
|
|
|
|
for (const auto ®ion : m_pCommonAnalysisyConfig->regionConfigArr)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
m_DetRoiList.Update_Mat(region.basicInfo.pointArry, m_matParam2Det, fx, fy);
|
|
|
|
m_DetRoiList.Update_Mat(region.basicInfo.pointArry, m_matParam2Det, fx, fy);
|
|
|
|
@ -2324,7 +2239,7 @@ int ImgCheckAnalysisy::DrawResult_Step_1()
|
|
|
|
float fs_resize_y = m_pImageAllResult->resultImg.rows * 1.0f / m_pImageAllResult->detImg.rows;
|
|
|
|
float fs_resize_y = m_pImageAllResult->resultImg.rows * 1.0f / m_pImageAllResult->detImg.rows;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 绘制m_inner_rroi(蓝色),原图坐标 -> 检测图(摆正) -> 结果图
|
|
|
|
// 绘制m_inner_rroi(蓝色),原图坐标 -> 检测图(裁剪) -> 结果图
|
|
|
|
{
|
|
|
|
{
|
|
|
|
cv::Point2f vertices[4];
|
|
|
|
cv::Point2f vertices[4];
|
|
|
|
m_inner_rroi.points(vertices);
|
|
|
|
m_inner_rroi.points(vertices);
|
|
|
|
@ -2345,7 +2260,7 @@ int ImgCheckAnalysisy::DrawResult_Step_1()
|
|
|
|
std::vector<cv::Point> product_roi_show;
|
|
|
|
std::vector<cv::Point> product_roi_show;
|
|
|
|
for (const auto &pt : m_pbaseCheckFunction->markLine.region)
|
|
|
|
for (const auto &pt : m_pbaseCheckFunction->markLine.region)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// 参数(模板)坐标 -> 检测图(摆正) -> 结果图
|
|
|
|
// 参数(模板)坐标 -> 检测图(裁剪) -> 结果图
|
|
|
|
cv::Point2f detPt = MatAffinePoint(m_matParam2Det, cv::Point2f((float)pt.x, (float)pt.y));
|
|
|
|
cv::Point2f detPt = MatAffinePoint(m_matParam2Det, cv::Point2f((float)pt.x, (float)pt.y));
|
|
|
|
cv::Point draw_pt;
|
|
|
|
cv::Point draw_pt;
|
|
|
|
draw_pt.x = cvRound(detPt.x * fs_resize_x);
|
|
|
|
draw_pt.x = cvRound(detPt.x * fs_resize_x);
|
|
|
|
@ -2945,7 +2860,7 @@ int ImgCheckAnalysisy::ImgPreDet()
|
|
|
|
creatsavedir();
|
|
|
|
creatsavedir();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 裁剪图(_RE_CutImg)保留原图通道:源图为彩色时用彩色摆正图,否则回退灰度检测图
|
|
|
|
// 裁剪图(_RE_CutImg)保留原图通道:源图为彩色时用彩色裁剪图,否则回退灰度检测图
|
|
|
|
m_CheckResult_shareP->cutSrcimg = m_pImageAllResult->detColorImg.empty()
|
|
|
|
m_CheckResult_shareP->cutSrcimg = m_pImageAllResult->detColorImg.empty()
|
|
|
|
? m_pImageAllResult->detImg
|
|
|
|
? m_pImageAllResult->detImg
|
|
|
|
: m_pImageAllResult->detColorImg;
|
|
|
|
: m_pImageAllResult->detColorImg;
|
|
|
|
|