update 结果图不修改为灰度图

dev_lsy
liusiyang 1 month ago
parent 43bd675b80
commit 25319d34a2

@ -96,6 +96,23 @@ public:
static void PrintRect(cv::Rect roi, std::string str = "");
static int cutSmallImg(cv::Mat img, std::vector<cv::Rect> &samllRoiList, cv::Rect config_roi, int config_SmallImg_Width, int config_SmallImg_Height, int config_MinOverlap_Width, int config_MinOverlap_Height);
static cv::Point2f transformPoint(const cv::Point2f &point, const cv::Mat &transform_matrix);
// 依目标图像通道数返回可用的绘制颜色:
// 1 通道(灰度) -> 统一白色,保证可见
// 4 通道(BGRA) -> 补 alpha = 255
// 3 通道 -> 原样返回
static inline cv::Scalar GetDrawColor(const cv::Mat &img, const cv::Scalar &color)
{
if (img.channels() == 1)
{
return cv::Scalar(255);
}
if (img.channels() == 4)
{
return cv::Scalar(color[0], color[1], color[2], 255);
}
return color;
}
};
// 无参数重载:直接返回原字符串,避免 -Wformat-security 警告
static inline std::string str_Format(const std::string &format)

@ -385,9 +385,14 @@ int AI_Edge_Algin::Get_Edge(int AIModel_type, const cv::Mat &img, DetConfig *pDe
cv::resize(img, detImg, sz);
int re = 0;
cv::Mat mask;
if (detImg.channels() != 1)
// 模型输入要求单通道;原图为彩色时按 BGR 顺序转灰度(与 imread(path,0) 的亮度一致)
if (detImg.channels() == 3)
{
cv::cvtColor(detImg, detImg, cv::COLOR_RGB2GRAY);
cv::cvtColor(detImg, detImg, cv::COLOR_BGR2GRAY);
}
else if (detImg.channels() == 4)
{
cv::cvtColor(detImg, detImg, cv::COLOR_BGRA2GRAY);
}
re = pBackPlate_Align->AIDet(detImg, mask);

@ -68,9 +68,19 @@ int CameraCheckAnalysisy::WaitDetImg()
// 判断物料在左还是在右
string JudgeMaterialPosition(Mat img) {
if (img.empty() || img.channels() != 1) {
cerr << "Error: Input image is empty or not grayscale!" << endl;
if (img.empty()) {
cerr << "Error: Input image is empty!" << endl;
return "Unknown";
}
// 原图可能是彩色,内部统一转灰度计算(形参为副本,不会改动调用方图像)
if (img.channels() != 1) {
cv::Mat grayImg;
if (img.channels() == 4) {
cv::cvtColor(img, grayImg, cv::COLOR_BGRA2GRAY);
} else {
cv::cvtColor(img, grayImg, cv::COLOR_BGR2GRAY);
}
img = grayImg;
}
resize(img, img, Size(img.cols, img.rows * 0.001), 0, 0);
int rows = img.rows;
@ -353,8 +363,23 @@ int CameraCheckAnalysisy::GetRectAndPoint(const cv::Mat &img, cv::Rect &roi, cv:
// printf("DirectSign_UP::111111111111111111 re123 %d\n", re123);
// getchar();
// 阈值化 + 轮廓提取只支持单通道,彩色原图内部转灰度(不改动调用方图像)
cv::Mat grayImg;
if (img.channels() != 1)
{
if (img.channels() == 4)
{
cv::cvtColor(img, grayImg, cv::COLOR_BGRA2GRAY);
}
else
{
cv::cvtColor(img, grayImg, cv::COLOR_BGR2GRAY);
}
}
const cv::Mat &workImg = (img.channels() == 1) ? img : grayImg;
cv::Mat small, smallbin;
cv::resize(img, small, cv::Size(600, 1500));
cv::resize(workImg, small, cv::Size(600, 1500));
cv::threshold(small, smallbin, 15, 255,
cv::THRESH_BINARY);
@ -387,8 +412,8 @@ int CameraCheckAnalysisy::GetRectAndPoint(const cv::Mat &img, cv::Rect &roi, cv:
cv::Rect rSmall = cv::boundingRect(contours[idx]);
/* 5. map to original */
float sx = (float)img.cols / smallbin.cols;
float sy = (float)img.rows / smallbin.rows;
float sx = (float)workImg.cols / smallbin.cols;
float sy = (float)workImg.rows / smallbin.rows;
cv::Rect rectInSrc;
rectInSrc.x = int(rSmall.x * sx) - 50;
@ -409,17 +434,17 @@ int CameraCheckAnalysisy::GetRectAndPoint(const cv::Mat &img, cv::Rect &roi, cv:
rectInSrc.x = 0;
if (rectInSrc.y < 0)
rectInSrc.y = 0;
if (rectInSrc.x + rectInSrc.width > img.cols)
rectInSrc.width = img.cols - rectInSrc.x;
if (rectInSrc.y + rectInSrc.height > img.rows)
if (rectInSrc.x + rectInSrc.width > workImg.cols)
rectInSrc.width = workImg.cols - rectInSrc.x;
if (rectInSrc.y + rectInSrc.height > workImg.rows)
{
rectInSrc.height = img.rows - rectInSrc.y;
rectInSrc.height = workImg.rows - rectInSrc.y;
}
merg_p_up.y = A_line_up;
merg_p_up.x = img.cols;
merg_p_up.x = workImg.cols;
merg_p_down.y = A_line_down;
merg_p_down.x = img.cols;
merg_p_down.x = workImg.cols;
roi = rectInSrc;
if (bshowimg)
@ -1093,20 +1118,28 @@ ImgCheckBase *CameraCheckAnalysisy::GetDealResult(int idx)
return NULL;
}
int CameraCheckAnalysisy::GetEdgePoint(const cv::Mat &img, Edge_Search_Config *pEdge_Search_Config, int &outP)
int CameraCheckAnalysisy::GetEdgePoint(const cv::Mat &imgSrc, Edge_Search_Config *pEdge_Search_Config, int &outP)
{
bool bdbuge = false;
bdbuge = bshowimg;
if (img.empty())
if (imgSrc.empty())
{
return -11;
}
if (img.channels() != 1)
// 边缘搜索仅支持单通道;彩色/BGRA 原图在此内部转灰度(不改动调用方图像)
cv::Mat grayImg;
if (imgSrc.channels() != 1)
{
// printf("*****************************channels\n");
return -12;
if (imgSrc.channels() == 4)
{
cv::cvtColor(imgSrc, grayImg, cv::COLOR_BGRA2GRAY);
}
else
{
cv::cvtColor(imgSrc, grayImg, cv::COLOR_BGR2GRAY);
}
}
const cv::Mat &img = (imgSrc.channels() == 1) ? imgSrc : grayImg;
// 检查roi;
if (!CheckUtil::RoiInImg(pEdge_Search_Config->roi, img))
{

@ -94,11 +94,8 @@ int ImageAllResult::AddDetImage(std::shared_ptr<shareImage> p)
float fw = RESIZE_IMAGE_WIDTH * 1.0f / detImg.cols;
sz.height = int(detImg.rows * fw);
// 保持原图通道(ReJson 模式下 detImg 本身就是裁剪图),不再灰度转假彩
cv::resize(detImg, resultImg, sz);
if (resultImg.channels() == 1)
{
cv::cvtColor(resultImg, resultImg, cv::COLOR_GRAY2BGR);
}
result->resultimg = resultImg;

@ -510,13 +510,20 @@ int ImageResultJudge::ResultJudge(std::shared_ptr<ImageAllResult> pImageResult)
// CheckUtil::printROI(CutRoi, "CutRoi");
cv::Size sz = cv::Size(QX_SAMLLIMG_WIDTH, QX_SAMLLIMG_HEIGHT);
if (pImageResult->detImg.channels() == 1)
// 缺陷小图直接取自原图裁剪区(保持原图通道 -> 真实彩色),ReJson/异常时退回检测图
{
cv::cvtColor(pImageResult->detImg(CutRoi), tem.srcImg, cv::COLOR_GRAY2BGR);
}
else
{
tem.srcImg = pImageResult->detImg(CutRoi).clone();
const cv::Mat &srcImg = pImageResult->result->in_shareImage->img;
int nOffsetX = (pImageResult->result->in_shareImage->Det_Mode != DET_MODE_ReJson) ? pDetResult->CutRoi.x : 0;
int nOffsetY = (pImageResult->result->in_shareImage->Det_Mode != DET_MODE_ReJson) ? pDetResult->CutRoi.y : 0;
cv::Rect srcCanvasRoi(CutRoi.x + nOffsetX, CutRoi.y + nOffsetY, CutRoi.width, CutRoi.height);
if (!srcImg.empty() && CheckUtil::RoiInImg(srcCanvasRoi, srcImg))
{
tem.srcImg = srcImg(srcCanvasRoi).clone();
}
else
{
tem.srcImg = pImageResult->detImg(CutRoi).clone();
}
}
cv::resize(tem.srcImg, tem.resizeImg, sz);
@ -627,13 +634,20 @@ int ImageResultJudge::ResultJudge(std::shared_ptr<ImageAllResult> pImageResult)
// CheckUtil::printROI(CutRoi, "CutRoi");
cv::Size sz = cv::Size(QX_SAMLLIMG_WIDTH, QX_SAMLLIMG_HEIGHT);
if (pImageResult->detImg.channels() == 1)
// 缺陷小图直接取自原图裁剪区(保持原图通道 -> 真实彩色),ReJson/异常时退回检测图
{
cv::cvtColor(pImageResult->detImg(CutRoi), tem.srcImg, cv::COLOR_GRAY2BGR);
}
else
{
tem.srcImg = pImageResult->detImg(CutRoi).clone();
const cv::Mat &srcImg = pImageResult->result->in_shareImage->img;
int nOffsetX = (pImageResult->result->in_shareImage->Det_Mode != DET_MODE_ReJson) ? pDetResult->CutRoi.x : 0;
int nOffsetY = (pImageResult->result->in_shareImage->Det_Mode != DET_MODE_ReJson) ? pDetResult->CutRoi.y : 0;
cv::Rect srcCanvasRoi(CutRoi.x + nOffsetX, CutRoi.y + nOffsetY, CutRoi.width, CutRoi.height);
if (!srcImg.empty() && CheckUtil::RoiInImg(srcCanvasRoi, srcImg))
{
tem.srcImg = srcImg(srcCanvasRoi).clone();
}
else
{
tem.srcImg = pImageResult->detImg(CutRoi).clone();
}
}
cv::resize(tem.srcImg, tem.resizeImg, sz);
@ -1141,7 +1155,7 @@ int ImageResultJudge::DrawResultTask(std::shared_ptr<ImageResultJudge::DrawInfo>
if (task->type == Draw_circle)
{
cv::circle(task->drawImg, task->cp, task->dr, task->color);
cv::circle(task->drawImg, task->cp, task->dr, CheckUtil::GetDrawColor(task->drawImg, task->color));
if (task->txtbackgroundk)
{
task->txtbackgroundk->txtDrawRoi.push_back(task->roi);
@ -1149,7 +1163,7 @@ int ImageResultJudge::DrawResultTask(std::shared_ptr<ImageResultJudge::DrawInfo>
}
if (task->type == Draw_rect)
{
cv::rectangle(task->drawImg, task->roi, task->color);
cv::rectangle(task->drawImg, task->roi, CheckUtil::GetDrawColor(task->drawImg, task->color));
if (task->txtbackgroundk)
{
task->txtbackgroundk->txtDrawRoi.push_back(task->roi);
@ -1213,7 +1227,7 @@ int ImageResultJudge::DrawResultTask(std::shared_ptr<ImageResultJudge::DrawInfo>
// 画文字
cv::putText(task->drawImg, txt, cv::Point(r.x, r.y + height),
fontFace, fontScale, task->color, thickness);
fontFace, fontScale, CheckUtil::GetDrawColor(task->drawImg, task->color), thickness);
height += lineHeight; // 下一行
}
// cv::rectangle(task->drawImg, rtxt, cv::Scalar(255, 0, 0));
@ -1221,7 +1235,7 @@ int ImageResultJudge::DrawResultTask(std::shared_ptr<ImageResultJudge::DrawInfo>
cv::Point p(r.x, r.y);
if (task->cp.x - r.x > 30 || task->cp.y - r.y > 30)
{
cv::line(task->drawImg, p, task->cp, cv::Scalar(80, 0, 200));
cv::line(task->drawImg, p, task->cp, CheckUtil::GetDrawColor(task->drawImg, cv::Scalar(80, 0, 200)));
}
// cv::circle(task->drawImg, task->cp, 3, task->color);

@ -503,12 +503,16 @@ int ImgCheckAnalysisy::CheckRun()
long time_calan_e = CheckUtil::getcurTime();
m_pdetlog->AddCheckstr(PrintLevel_0, "2.1、pre detect", "-------------------------Adapt_Config------------succ---time %ld----\n", time_calan_e - time_edge_s);
/*生成 检测的图片*/
/*生成 检测的图片(检测用图固定为单通道灰度;彩色原图按 BGR 顺序转灰度,与 imread(path,0) 的亮度一致)*/
cv::Mat image;
image = m_CheckResult_shareP->in_shareImage->img;
if (image.channels() == 3)
{
cv::cvtColor(image(m_outer_roi), m_pImageAllResult->detImg, cv::COLOR_RGB2GRAY);
cv::cvtColor(image(m_outer_roi), m_pImageAllResult->detImg, cv::COLOR_BGR2GRAY);
}
else if (image.channels() == 4)
{
cv::cvtColor(image(m_outer_roi), m_pImageAllResult->detImg, cv::COLOR_BGRA2GRAY);
}
else
{
@ -1269,8 +1273,7 @@ int ImgCheckAnalysisy::GetALLBlob()
int thickness = 1;
m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, "Save Tem Img");
cv::Mat tm;
cv::cvtColor(m_pImageAllResult->AIMaskImg, tm, cv::COLOR_GRAY2RGB); // 彩色 可选项
cv::Mat tm = m_pImageAllResult->AIMaskImg.clone(); // 保持 mask 单通道,不再灰度转假彩
for (int i = 0; i < blobs.blobCount; i++)
{
cv::Rect roi;
@ -1281,18 +1284,18 @@ int ImgCheckAnalysisy::GetALLBlob()
if (blobs.blobTab[i].ErrType == 0)
{
cv::rectangle(tm, roi, cv::Scalar(0, 0, 255));
cv::rectangle(tm, roi, CheckUtil::GetDrawColor(tm, cv::Scalar(0, 0, 255)));
}
else
{
cv::rectangle(tm, roi, cv::Scalar(0, 255, 255));
cv::rectangle(tm, roi, CheckUtil::GetDrawColor(tm, cv::Scalar(0, 255, 255)));
}
char buffer[128];
sprintf(buffer, "id:%d type:%d m %0.1f", i,blobs.blobTab[i].ErrType, blobs.blobTab[i].density);
std::string text = buffer;
cv::Point origin = cv::Point(roi.x, roi.y);
cv::putText(tm, text, origin, font_face, font_scale, cv::Scalar(0, 255, 0), thickness, 1, 0);
cv::putText(tm, text, origin, font_face, font_scale, CheckUtil::GetDrawColor(tm, cv::Scalar(0, 255, 0)), thickness, 1, 0);
// printf("type: %d %d %d %d %d %d %d\n", blobs.blobTab[i].ErrType, blobs.blobTab[i].area, blobs.blobTab[i].energy, roi.x, roi.y, roi.width, roi.height);
}
@ -1510,18 +1513,10 @@ int ImgCheckAnalysisy::AI_Detect_Thread(const cv::Mat &img, cv::Mat &ResultImg)
if (DetImgInfo_shareP->bsaveProcessImg)
{
cv::Mat imshow;
if (img.channels() == 1)
{
cv::cvtColor(img, imshow, cv::COLOR_GRAY2RGB); // 彩色 可选项
}
else
{
imshow = img.clone();
}
cv::Mat imshow = img.clone(); // 保持输入通道,不再灰度转假彩
for (int i = 0; i < SmallRoiList.size(); i++)
{
cv::rectangle(imshow, SmallRoiList.at(i), cv::Scalar(0, 0, 255), 3);
cv::rectangle(imshow, SmallRoiList.at(i), CheckUtil::GetDrawColor(imshow, cv::Scalar(0, 0, 255)), 3);
}
cv::imwrite(DetImgInfo_shareP->strChannel + "_AI_Det_ROI.jpg", imshow);
}
@ -1791,11 +1786,21 @@ int ImgCheckAnalysisy::ResizeImg()
float fw = RESIZE_IMAGE_WIDTH * 1.0f / m_pImageAllResult->detImg.cols;
sz.height = int(m_pImageAllResult->detImg.rows * fw);
cv::resize(m_pImageAllResult->detImg, m_pImageAllResult->resultImg, sz);
if (m_pImageAllResult->resultImg.channels() == 1)
// 结果图画布取自"原图裁剪区",保持原图通道(彩色原图 -> 真实彩色,不再灰度转假彩);
// ReJson 复测模式下 in_shareImage->img 本身就是裁剪图,直接用检测图兜底
cv::Mat srcCanvas;
const cv::Mat &srcImg = m_CheckResult_shareP->in_shareImage->img;
if (m_CheckResult_shareP->in_shareImage->Det_Mode != DET_MODE_ReJson &&
!srcImg.empty() && CheckUtil::RoiInImg(m_outer_roi, srcImg))
{
cv::cvtColor(m_pImageAllResult->resultImg, m_pImageAllResult->resultImg, cv::COLOR_GRAY2BGR);
srcCanvas = srcImg(m_outer_roi);
}
else
{
srcCanvas = m_pImageAllResult->detImg;
}
cv::resize(srcCanvas, m_pImageAllResult->resultImg, sz);
m_CheckResult_shareP->resultimg = m_pImageAllResult->resultImg;
m_pdetlog->AddCheckstr(PrintLevel_1, "showImg size", " [w %d,h %d]-> show img [w %d,h %d] ",
m_outer_roi.width, m_outer_roi.height, sz.width, sz.height);
@ -1892,8 +1897,9 @@ int ImgCheckAnalysisy::DrawResult_Step_1()
// std::cout << polygon << std::endl;
// 绘制多边形的边界(不填充),使用绿色线条,线宽为2
cv::polylines(m_CheckResult_shareP->resultimg, polygon, true, cv::Scalar(128, 128, 255), 1); // true表示闭合多边形
// 绘制多边形的边界(不填充),线宽为1;颜色按画布通道自适应
cv::polylines(m_CheckResult_shareP->resultimg, polygon, true,
CheckUtil::GetDrawColor(m_CheckResult_shareP->resultimg, cv::Scalar(128, 128, 255)), 1); // true表示闭合多边形
}
// cv::imwrite(DetImgInfo_shareP->strChannel + "roi_src.png", m_pdetlog->temImgList[TEM_IMG_IDX_DrawSrc]);
// cv::imwrite(DetImgInfo_shareP->strChannel + "roi_ss.png", m_pdetlog->temImgList[TEM_IMG_IDX_Result]);
@ -1916,7 +1922,8 @@ int ImgCheckAnalysisy::DrawResult_Step_1()
draw_pts.emplace_back(cvRound((vertices[i].x - m_Crop_Roi_paramImg.x) * fs_resize_x),
cvRound((vertices[i].y - m_Crop_Roi_paramImg.y) * fs_resize_y));
}
cv::polylines(m_CheckResult_shareP->resultimg, draw_pts, true, cv::Scalar(255, 0, 0), 1);
cv::polylines(m_CheckResult_shareP->resultimg, draw_pts, true,
CheckUtil::GetDrawColor(m_CheckResult_shareP->resultimg, cv::Scalar(255, 0, 0)), 1);
}
if (m_pbaseCheckFunction && m_pbaseCheckFunction->markLine.region.size() > 1)
@ -1934,7 +1941,7 @@ int ImgCheckAnalysisy::DrawResult_Step_1()
m_CheckResult_shareP->resultimg,
product_roi_show,
true,
cv::Scalar(0, 255, 0),
CheckUtil::GetDrawColor(m_CheckResult_shareP->resultimg, cv::Scalar(0, 255, 0)),
1);
}
if (m_pEdge_Align_Result.get() != NULL)
@ -1949,7 +1956,8 @@ int ImgCheckAnalysisy::DrawResult_Step_1()
cv::Point p;
p.x = m_pEdge_Align_Result->markresulList[i].det_Local_DetImg.x * fs_resize_x;
p.y = m_pEdge_Align_Result->markresulList[i].det_Local_DetImg.y * fs_resize_y;
cv::circle(m_CheckResult_shareP->resultimg, p, 5, cv::Scalar(0, 255, 0));
cv::circle(m_CheckResult_shareP->resultimg, p, 5,
CheckUtil::GetDrawColor(m_CheckResult_shareP->resultimg, cv::Scalar(0, 255, 0)));
}
}
}

@ -1262,7 +1262,7 @@ int deal::ReJson_product(std::vector<Json_Det_Path> &jsonList, std::string strPr
std::string json_str = buffer.str(); // 获取 JSON 文件的内容作为字符串
// 显示读取到的 JSON 字符串
// std::cout << "JSON content: " << json_str << std::endl;
cv::Mat cutimg = cv::imread(strimg, 0);
cv::Mat cutimg = cv::imread(strimg, cv::IMREAD_UNCHANGED);
int f0 = strJson.rfind('_');
int f1 = strJson.rfind('.');
int f2 = strJson.rfind('/');
@ -1518,12 +1518,12 @@ void deal::Thread_ReadImg(int id)
printf("pImageInfo == nullptr=================id %d=============\n", id);
return;
}
// pImageInfo->img = cv::imread(pImageInfo->strPath, 0);
pImageInfo->img = cv::imread(pImageInfo->strPath, 0);
// 原图保持原始通道(彩色图不再强制转灰度),结果图/缺陷小图才能显示真实色彩
pImageInfo->img = cv::imread(pImageInfo->strPath, cv::IMREAD_UNCHANGED);
// cv::imwrite(pImageInfo->strchannelName + "_A_ssssde.png", pImageInfo->img);
if (pImageInfo->strPath_B != "")
{
pImageInfo->img_B = cv::imread(pImageInfo->strPath_B, 0);
pImageInfo->img_B = cv::imread(pImageInfo->strPath_B, cv::IMREAD_UNCHANGED);
// cv::imwrite(pImageInfo->strchannelName + "_B_sssde.png", pImageInfo->img_B);
}

Loading…
Cancel
Save