|
|
|
|
@ -29,29 +29,29 @@ int Chip_Detect::RunStart(void *pconfig1)
|
|
|
|
|
m_pRunConfig.copy(*(RunInfoST *)pconfig1);
|
|
|
|
|
m_bInitSucc = false;
|
|
|
|
|
|
|
|
|
|
LoadAIModelParm(m_pRunConfig.str_AIModelJson, m_AIModelConfigList);
|
|
|
|
|
if (m_AIModelConfigList.get() == nullptr)
|
|
|
|
|
{
|
|
|
|
|
std::cout << "m_AIModelConfigList is null\n";
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_AIModelConfigList->print("m_AIModelConfigList");
|
|
|
|
|
|
|
|
|
|
// LoadCheckBaseConfig(m_pRunConfig.str_RunJson, m_CheckBaseConfig);
|
|
|
|
|
// if (m_CheckBaseConfig.get() == nullptr)
|
|
|
|
|
// LoadAIModelParm(m_pRunConfig.str_AIModelJson, m_AIModelConfigList);
|
|
|
|
|
// if (m_AIModelConfigList.get() == nullptr)
|
|
|
|
|
// {
|
|
|
|
|
// std::cout << "m_CheckBaseConfig is null\n";
|
|
|
|
|
// std::cout << "m_AIModelConfigList is null\n";
|
|
|
|
|
// return 1;
|
|
|
|
|
// }
|
|
|
|
|
// m_CheckBaseConfig->print("m_CheckBaseConfig");
|
|
|
|
|
|
|
|
|
|
int re = InitModel();
|
|
|
|
|
if (0 != re)
|
|
|
|
|
// m_AIModelConfigList->print("m_AIModelConfigList");
|
|
|
|
|
|
|
|
|
|
LoadCheckBaseConfig(m_pRunConfig.str_RunJson, m_CheckBaseConfig);
|
|
|
|
|
if (m_CheckBaseConfig.get() == nullptr)
|
|
|
|
|
{
|
|
|
|
|
printf("AI_DetModel Init Fail\n");
|
|
|
|
|
return re;
|
|
|
|
|
std::cout << "m_CheckBaseConfig is null\n";
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
m_CheckBaseConfig->print("m_CheckBaseConfig");
|
|
|
|
|
|
|
|
|
|
// int re = InitModel();
|
|
|
|
|
// if (0 != re)
|
|
|
|
|
// {
|
|
|
|
|
// printf("AI_DetModel Init Fail\n");
|
|
|
|
|
// return re;
|
|
|
|
|
// }
|
|
|
|
|
printf("init end \n");
|
|
|
|
|
m_bInitSucc = true;
|
|
|
|
|
return 0;
|
|
|
|
|
@ -87,22 +87,26 @@ int Chip_Detect::CheckRun()
|
|
|
|
|
t1 = CheckUtil::getcurTime();
|
|
|
|
|
CheckImgInit();
|
|
|
|
|
cv::Mat detimg = DetImgInfo_shareP->img;
|
|
|
|
|
|
|
|
|
|
if (detimg.empty())
|
|
|
|
|
{
|
|
|
|
|
std::cout << "detimg is empty\n";
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
// if (!CheckUtil::RoiInImg(m_CheckBaseConfig->crop, detimg))
|
|
|
|
|
// {
|
|
|
|
|
// return 1;
|
|
|
|
|
// }
|
|
|
|
|
// if (m_Update_config)
|
|
|
|
|
// {
|
|
|
|
|
// LoadCheckBaseConfig(m_pRunConfig.str_RunJson, m_CheckBaseConfig);
|
|
|
|
|
// m_Update_config = false;
|
|
|
|
|
// }
|
|
|
|
|
// Base_Function_DetConfig *pdetConfig = &m_CheckBaseConfig->baseCheckFunction.detconfig;
|
|
|
|
|
// // detimg = DetImgInfo_shareP->img(pdetConfig->cropROI);
|
|
|
|
|
Base_Function_DetConfig *pdetConfig = &m_CheckBaseConfig->baseCheckFunction.detconfig;
|
|
|
|
|
auto rec1 = pdetConfig->chipDetConfig1.rect;
|
|
|
|
|
auto rec2 = pdetConfig->chipDetConfig2.rect;
|
|
|
|
|
if (!CheckUtil::RoiInImg(rec1, detimg) || !CheckUtil::RoiInImg(rec2, detimg))
|
|
|
|
|
{
|
|
|
|
|
std::cout << "crop roi is invalid\n";
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
if (m_Update_config)
|
|
|
|
|
{
|
|
|
|
|
LoadCheckBaseConfig(m_pRunConfig.str_RunJson, m_CheckBaseConfig);
|
|
|
|
|
m_Update_config = false;
|
|
|
|
|
}
|
|
|
|
|
// detimg = DetImgInfo_shareP->img(pdetConfig->cropROI);
|
|
|
|
|
if (DetImgInfo_shareP->bdebugSaveImg)
|
|
|
|
|
{
|
|
|
|
|
bwriteImg = true;
|
|
|
|
|
@ -178,114 +182,6 @@ int Chip_Detect::InitModel()
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int Chip_Detect::Thread_Run(const cv::Mat &img)
|
|
|
|
|
{
|
|
|
|
|
cv::Size windowSize(512, 512); // 每个区域大小
|
|
|
|
|
cv::Size stride(450, 450); // 步长(小于区域大小就是重叠)
|
|
|
|
|
|
|
|
|
|
cv::Mat img_gray;
|
|
|
|
|
if (img.channels() != 1)
|
|
|
|
|
{
|
|
|
|
|
cv::cvtColor(img, img_gray, cv::COLOR_BGR2GRAY);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
img_gray = img;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cv::Mat blurred;
|
|
|
|
|
cv::GaussianBlur(img_gray, blurred, cv::Size(21, 21), 5.5);
|
|
|
|
|
|
|
|
|
|
cv::Mat showimg = blurred.clone();
|
|
|
|
|
|
|
|
|
|
cv::Mat maskimg = cv::Mat::zeros(img.size(), CV_8U);
|
|
|
|
|
|
|
|
|
|
for (int y = 0; y < img.rows; y += stride.height)
|
|
|
|
|
{
|
|
|
|
|
for (int x = 0; x < img.cols; x += stride.width)
|
|
|
|
|
{
|
|
|
|
|
int width = std::min(windowSize.width, img.cols - x);
|
|
|
|
|
int height = std::min(windowSize.height, img.rows - y);
|
|
|
|
|
cv::Rect roi(x, y, width, height);
|
|
|
|
|
|
|
|
|
|
cv::rectangle(showimg, roi, cv::Scalar(255, 0, 50));
|
|
|
|
|
|
|
|
|
|
cv::Mat patch = blurred(roi);
|
|
|
|
|
|
|
|
|
|
double meanVal = cv::mean(patch)[0];
|
|
|
|
|
|
|
|
|
|
cv::Mat mean, stddev;
|
|
|
|
|
|
|
|
|
|
cv::meanStdDev(patch, mean, stddev);
|
|
|
|
|
double sd = stddev.at<double>(0, 0);
|
|
|
|
|
|
|
|
|
|
double lowerThresh = m_CheckBaseConfig->det_ratio_min * meanVal;
|
|
|
|
|
double upperThresh = m_CheckBaseConfig->det_ratio_max * meanVal;
|
|
|
|
|
// 创建二值图
|
|
|
|
|
cv::Mat maskLow, maskHigh, resultMask;
|
|
|
|
|
|
|
|
|
|
// 低于下限
|
|
|
|
|
cv::threshold(patch, maskLow, lowerThresh, 255, cv::THRESH_BINARY_INV);
|
|
|
|
|
|
|
|
|
|
// 高于上限
|
|
|
|
|
cv::threshold(patch, maskHigh, upperThresh, 255, cv::THRESH_BINARY);
|
|
|
|
|
|
|
|
|
|
// 合并两个条件:低或高
|
|
|
|
|
cv::bitwise_or(maskLow, maskHigh, resultMask);
|
|
|
|
|
resultMask.copyTo(maskimg(roi), resultMask);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cv::Mat m_element;
|
|
|
|
|
m_element = getStructuringElement(cv::MORPH_RECT, cv::Size(17, 17));
|
|
|
|
|
cv::Mat m12322;
|
|
|
|
|
// 增加闭运算
|
|
|
|
|
cv::morphologyEx(maskimg, m12322, cv::MORPH_CLOSE, m_element);
|
|
|
|
|
|
|
|
|
|
GetBlob(m12322);
|
|
|
|
|
for (int i = 0; i < m_blob.blobCount; i++)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
BlobResult tem;
|
|
|
|
|
cv::Rect roi;
|
|
|
|
|
roi.x = m_blob.blobTab[i].minx;
|
|
|
|
|
roi.y = m_blob.blobTab[i].miny;
|
|
|
|
|
roi.width = m_blob.blobTab[i].maxx - m_blob.blobTab[i].minx + 1;
|
|
|
|
|
roi.height = m_blob.blobTab[i].maxy - m_blob.blobTab[i].miny + 1;
|
|
|
|
|
|
|
|
|
|
tem.roi = roi;
|
|
|
|
|
cv::Point pCenter;
|
|
|
|
|
pCenter.x = roi.x + roi.width * 0.5;
|
|
|
|
|
pCenter.y = roi.y + roi.height * 0.5;
|
|
|
|
|
double result = cv::pointPolygonTest(m_CheckBaseConfig->pointArry, pCenter, false);
|
|
|
|
|
if (result < 0)
|
|
|
|
|
{
|
|
|
|
|
printf("Not in region \n");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CheckUtil::printROI(roi, "roi");
|
|
|
|
|
CheckUtil::printROI(tem.roi, "tem.roi ");
|
|
|
|
|
tem.area_piexl = m_blob.blobTab[i].area;
|
|
|
|
|
tem.hj = m_blob.blobTab[i].grayDis;
|
|
|
|
|
tem.type = m_blob.blobTab[i].UserErrorType;
|
|
|
|
|
|
|
|
|
|
tem.area_mm2 = m_blob.blobTab[i].area * m_CheckBaseConfig->imageScaleParam.fScale_X * m_CheckBaseConfig->imageScaleParam.fScale_Y;
|
|
|
|
|
if (tem.area_mm2 > m_CheckBaseConfig->qxSegParam.Area)
|
|
|
|
|
{
|
|
|
|
|
tem.nresult = 1;
|
|
|
|
|
m_CheckResult_shareP->nresult = 1;
|
|
|
|
|
}
|
|
|
|
|
printf("tem.nresult %d = %f %f \n", tem.nresult, tem.area_mm2, m_CheckBaseConfig->qxSegParam.Area);
|
|
|
|
|
m_resultList.push_back(tem);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// cv::imwrite("feeee.png", showimg);
|
|
|
|
|
// cv::imwrite("feeeemask.png", maskimg);
|
|
|
|
|
// cv::imwrite("feeeemask123.png", m12322);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int Chip_Detect::Draw(const cv::Mat &img, cv::Mat &resultimg)
|
|
|
|
|
{
|
|
|
|
|
if (img.channels() == 1)
|
|
|
|
|
@ -639,123 +535,84 @@ int Chip_Detect::ImgAlinRotate(const cv::Mat &img, cv::Mat &alignImg)
|
|
|
|
|
int Chip_Detect::DetectImg(const cv::Mat &img)
|
|
|
|
|
{
|
|
|
|
|
printf("AI_Run>>>>>>>>>>> start \n");
|
|
|
|
|
|
|
|
|
|
cv::Mat ColorImg;
|
|
|
|
|
if (img.channels() == 1)
|
|
|
|
|
{
|
|
|
|
|
cv::cvtColor(img, ColorImg, cv::COLOR_GRAY2BGR);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ColorImg = img;
|
|
|
|
|
}
|
|
|
|
|
int re = 0;
|
|
|
|
|
cv::Mat AlignImg = img;
|
|
|
|
|
|
|
|
|
|
printf("start --- seg \n");
|
|
|
|
|
cv::Mat detSrcMask = cv::Mat(AlignImg.rows, AlignImg.cols, CV_8U, cv::Scalar(0));
|
|
|
|
|
ROI2ROI_SCALE SegImgToSrcImg;
|
|
|
|
|
// 2、分割
|
|
|
|
|
for (int i = 0; i < m_AIModelConfigList->AIModelConfigList.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
AI_Model_Param *p = &m_AIModelConfigList->AIModelConfigList.at(i);
|
|
|
|
|
// 分割类型
|
|
|
|
|
if (p->type != AI_Model_Type_Seg)
|
|
|
|
|
auto basecheckconfig = m_CheckBaseConfig->baseCheckFunction.detconfig;
|
|
|
|
|
// 区域1
|
|
|
|
|
std::vector<cv::Rect> smallRoiList1;
|
|
|
|
|
int re = CutChipDetRoi(img, basecheckconfig.chipDetConfig1.rect, smallRoiList1);
|
|
|
|
|
if (re != 0)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
std::cout << "CutChipDetRoi region1 fail \n";
|
|
|
|
|
return re;
|
|
|
|
|
}
|
|
|
|
|
long t1, t2, t3;
|
|
|
|
|
t1 = CheckUtil::getcurTime();
|
|
|
|
|
|
|
|
|
|
cv::Size sz;
|
|
|
|
|
sz.width = p->in_img.width;
|
|
|
|
|
sz.height = p->in_img.height;
|
|
|
|
|
cv::Mat temimg;
|
|
|
|
|
cv::resize(AlignImg, temimg, sz);
|
|
|
|
|
SegImgToSrcImg.setResize(AlignImg, temimg);
|
|
|
|
|
|
|
|
|
|
if (bwriteImg)
|
|
|
|
|
if (smallRoiList1.size() != CHIP_SIZE / 2)
|
|
|
|
|
{
|
|
|
|
|
std::string str = p->strAIModelName + "_cut_AI_in.png";
|
|
|
|
|
cv::imwrite(str, temimg);
|
|
|
|
|
std::cout << "CutChipDetRoi region1 size error size=" << smallRoiList1.size() << "\n";
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
cv::Mat SegmaskImg;
|
|
|
|
|
int re = p->pdetect->run(temimg, SegmaskImg, false);
|
|
|
|
|
// 区域2
|
|
|
|
|
std::vector<cv::Rect> smallRoiList2;
|
|
|
|
|
re = CutChipDetRoi(img, basecheckconfig.chipDetConfig2.rect, smallRoiList2);
|
|
|
|
|
if (re != 0)
|
|
|
|
|
{
|
|
|
|
|
printf("AI_Run seg run fail \n");
|
|
|
|
|
std::cout << "CutChipDetRoi region2 fail \n";
|
|
|
|
|
return re;
|
|
|
|
|
}
|
|
|
|
|
SegmaskImg *= 255;
|
|
|
|
|
if (bwriteImg)
|
|
|
|
|
if (smallRoiList2.size() != CHIP_SIZE / 2)
|
|
|
|
|
{
|
|
|
|
|
std::string str = p->strAIModelName + "_cut_AI_out_.png";
|
|
|
|
|
cv::imwrite(str, SegmaskImg);
|
|
|
|
|
std::cout << "CutChipDetRoi region2 size error size=" << smallRoiList2.size() << "\n";
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cv::Size srcsz;
|
|
|
|
|
srcsz.width = AlignImg.cols;
|
|
|
|
|
srcsz.height = AlignImg.rows;
|
|
|
|
|
cv::Mat temmask;
|
|
|
|
|
cv::resize(SegmaskImg, detSrcMask, srcsz);
|
|
|
|
|
if (bwriteImg)
|
|
|
|
|
// 转换为原图rec
|
|
|
|
|
for (auto &r : smallRoiList1)
|
|
|
|
|
{
|
|
|
|
|
std::string str = p->strAIModelName + "_detSrcMask_res.png";
|
|
|
|
|
cv::imwrite(str, detSrcMask);
|
|
|
|
|
r.x += basecheckconfig.chipDetConfig1.rect.x;
|
|
|
|
|
r.y += basecheckconfig.chipDetConfig1.rect.y;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
printf("End --- seg \n");
|
|
|
|
|
|
|
|
|
|
if (detSrcMask.empty())
|
|
|
|
|
for (auto &r : smallRoiList2)
|
|
|
|
|
{
|
|
|
|
|
printf("Seg is Error exit \n");
|
|
|
|
|
return 1;
|
|
|
|
|
r.x += basecheckconfig.chipDetConfig2.rect.x;
|
|
|
|
|
r.y += basecheckconfig.chipDetConfig2.rect.y;
|
|
|
|
|
}
|
|
|
|
|
m_resultImg = AlignImg;
|
|
|
|
|
// 合并两个list
|
|
|
|
|
smallRoiList1.insert(smallRoiList1.end(), smallRoiList2.begin(), smallRoiList2.end());
|
|
|
|
|
|
|
|
|
|
if (bwriteImg)
|
|
|
|
|
{
|
|
|
|
|
// 定义腐蚀操作的内核
|
|
|
|
|
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
|
|
|
|
|
cv::erode(detSrcMask, detSrcMask, kernel);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<cv::Vec4i> hierarchy;
|
|
|
|
|
std::vector<std::vector<cv::Point>> contours; // 0929-add
|
|
|
|
|
cv::findContours(detSrcMask, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
|
|
|
|
|
if (contours.size() != CHIP_SIZE)
|
|
|
|
|
auto test = img.clone();
|
|
|
|
|
for (auto &r : smallRoiList1)
|
|
|
|
|
{
|
|
|
|
|
std::cout << "contours size != " << CHIP_SIZE << ", actual size: " << contours.size() << std::endl;
|
|
|
|
|
return 1;
|
|
|
|
|
cv::rectangle(test, r, cv::Scalar(0, 255, 0), 1);
|
|
|
|
|
}
|
|
|
|
|
std::vector<cv::Rect> boundRect;
|
|
|
|
|
for (const auto &contour : contours)
|
|
|
|
|
{
|
|
|
|
|
boundRect.emplace_back(cv::boundingRect(contour));
|
|
|
|
|
}
|
|
|
|
|
if (boundRect.empty())
|
|
|
|
|
{
|
|
|
|
|
std::cout << "boundRect is empty\n";
|
|
|
|
|
return 1;
|
|
|
|
|
cv::imwrite("tesssss.png", test); // 0929-add
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 按从上到下、从左到右排序
|
|
|
|
|
std::sort(boundRect.begin(), boundRect.end(), [](const cv::Rect &a, const cv::Rect &b) -> bool
|
|
|
|
|
// 排序
|
|
|
|
|
std::sort(smallRoiList1.begin(), smallRoiList1.end(), [&](const cv::Rect &a, const cv::Rect &b) -> bool
|
|
|
|
|
{
|
|
|
|
|
int rowTolerance = 50;
|
|
|
|
|
// 如果在同一行(y坐标相近)
|
|
|
|
|
if (abs(a.y - b.y) <= rowTolerance)
|
|
|
|
|
{
|
|
|
|
|
return a.x < b.x; // 从左到右
|
|
|
|
|
// CAMERA_Feeding从左到右, CAMERA_Blanking从右到左
|
|
|
|
|
return m_pRunConfig.flag0 == CAMERA_Feeding ? a.x < b.x : a.x > b.x;
|
|
|
|
|
}
|
|
|
|
|
// 否则从下到上排序
|
|
|
|
|
return a.y > b.y; });
|
|
|
|
|
|
|
|
|
|
//初始化存图
|
|
|
|
|
if (img.channels() == 1)
|
|
|
|
|
{
|
|
|
|
|
cv::cvtColor(img, m_CheckResult_shareP->resultImg, cv::COLOR_GRAY2BGR);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_CheckResult_shareP->resultImg = img.clone();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int j = 0;
|
|
|
|
|
auto showimg = AlignImg.clone();
|
|
|
|
|
for (const auto &rect : boundRect)
|
|
|
|
|
for (const auto &rect : smallRoiList1)
|
|
|
|
|
{
|
|
|
|
|
auto smallImg = AlignImg(rect);
|
|
|
|
|
auto smallImg = img(rect);
|
|
|
|
|
cv::Mat gray;
|
|
|
|
|
if (smallImg.channels() == 3)
|
|
|
|
|
{
|
|
|
|
|
@ -772,29 +629,227 @@ int Chip_Detect::DetectImg(const cv::Mat &img)
|
|
|
|
|
int totalPixels = binaryImg.rows * binaryImg.cols;
|
|
|
|
|
double nonZeroRatio = static_cast<double>(nonZeroCount) / totalPixels;
|
|
|
|
|
int res = 0;
|
|
|
|
|
if (nonZeroRatio >= 0.1)
|
|
|
|
|
if (nonZeroRatio >= basecheckconfig.chipThr)
|
|
|
|
|
{
|
|
|
|
|
res = 1;
|
|
|
|
|
}
|
|
|
|
|
m_CheckResult_shareP->chipDataList.emplace_back(res);
|
|
|
|
|
|
|
|
|
|
auto ts = CheckUtil::getcurTime();
|
|
|
|
|
// 绘制
|
|
|
|
|
// if (bwriteImg)
|
|
|
|
|
{
|
|
|
|
|
if (bwriteImg)
|
|
|
|
|
{
|
|
|
|
|
std::string chipBinaryImgName = "chip_binary_" + std::to_string(j) + ".png";
|
|
|
|
|
cv::imwrite(chipBinaryImgName, binaryImg); // 0929-add
|
|
|
|
|
cv::rectangle(showimg, rect, cv::Scalar(0, 255, 0), 1);
|
|
|
|
|
cv::putText(showimg, std::to_string(j), cv::Point(rect.x + rect.width / 2, rect.y + rect.height / 2), cv::FONT_HERSHEY_SIMPLEX, 0.6, cv::Scalar(255, 0, 0), 1);
|
|
|
|
|
cv::putText(showimg, std::to_string(res) + "::" + std::to_string(nonZeroRatio), cv::Point(rect.x + rect.width / 2 - 50, rect.y + rect.height / 2 + 30), cv::FONT_HERSHEY_SIMPLEX, 0.6, cv::Scalar(0, 0, 255), 1);
|
|
|
|
|
}
|
|
|
|
|
cv::rectangle(m_CheckResult_shareP->resultImg, rect, cv::Scalar(0, 255, 0), 1);
|
|
|
|
|
cv::putText(m_CheckResult_shareP->resultImg, std::to_string(j), cv::Point(rect.x + rect.width / 2, rect.y + rect.height / 2), cv::FONT_HERSHEY_SIMPLEX, 0.6, cv::Scalar(255, 0, 0), 1);
|
|
|
|
|
cv::putText(m_CheckResult_shareP->resultImg, std::to_string(res) + "::" + std::to_string(nonZeroRatio), cv::Point(rect.x + rect.width / 2 - 50, rect.y + rect.height / 2 + 30), cv::FONT_HERSHEY_SIMPLEX, 0.6, cv::Scalar(0, 0, 255), 1);
|
|
|
|
|
j++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf("AI_Run>>>>>>>>>>> End \n");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int Chip_Detect::CutChipDetRoi(const cv::Mat &img, cv::Rect &Roi, std::vector<cv::Rect> &smallRoiList)
|
|
|
|
|
{
|
|
|
|
|
if (!CheckUtil::RoiInImg(Roi, img))
|
|
|
|
|
{
|
|
|
|
|
std::cout << "CutChipDetRoi --- crop roi is invalid\n";
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
auto detimg1 = img(Roi);
|
|
|
|
|
cv::Rect cutRoi;
|
|
|
|
|
cutRoi.x = 0;
|
|
|
|
|
cutRoi.y = 0;
|
|
|
|
|
cutRoi.width = detimg1.cols - 0;
|
|
|
|
|
cutRoi.height = detimg1.rows - 0;
|
|
|
|
|
auto basecheckconfig = m_CheckBaseConfig->baseCheckFunction.detconfig;
|
|
|
|
|
int re = CheckUtil::cutSmallImg(detimg1, smallRoiList, cutRoi, basecheckconfig.chipDetConfig1.detWidth, basecheckconfig.chipDetConfig1.detHeight, 0, 0);
|
|
|
|
|
if (re != 0)
|
|
|
|
|
{
|
|
|
|
|
return re;
|
|
|
|
|
}
|
|
|
|
|
if (smallRoiList.size() <= 0)
|
|
|
|
|
{
|
|
|
|
|
std::cout << "CutChipDetRoi --- smallRoiList <= 0\n";
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
if (bwriteImg)
|
|
|
|
|
{
|
|
|
|
|
cv::imwrite("chip_res.png", showimg); // 0929-add
|
|
|
|
|
auto test = detimg1.clone();
|
|
|
|
|
for (auto &r : smallRoiList)
|
|
|
|
|
{
|
|
|
|
|
cv::rectangle(test, r, cv::Scalar(0, 255, 0), 1);
|
|
|
|
|
}
|
|
|
|
|
cv::imwrite("chip_detect_cutroi.png", test); // 0929-add
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf("AI_Run>>>>>>>>>>> End \n");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// int Chip_Detect::DetectImg(const cv::Mat &img)
|
|
|
|
|
// {
|
|
|
|
|
// printf("AI_Run>>>>>>>>>>> start \n");
|
|
|
|
|
|
|
|
|
|
// cv::Mat ColorImg;
|
|
|
|
|
// if (img.channels() == 1)
|
|
|
|
|
// {
|
|
|
|
|
// cv::cvtColor(img, ColorImg, cv::COLOR_GRAY2BGR);
|
|
|
|
|
// }
|
|
|
|
|
// else
|
|
|
|
|
// {
|
|
|
|
|
// ColorImg = img;
|
|
|
|
|
// }
|
|
|
|
|
// int re = 0;
|
|
|
|
|
// cv::Mat AlignImg = img;
|
|
|
|
|
|
|
|
|
|
// printf("start --- seg \n");
|
|
|
|
|
// cv::Mat detSrcMask = cv::Mat(AlignImg.rows, AlignImg.cols, CV_8U, cv::Scalar(0));
|
|
|
|
|
// ROI2ROI_SCALE SegImgToSrcImg;
|
|
|
|
|
// // 2、分割
|
|
|
|
|
// for (int i = 0; i < m_AIModelConfigList->AIModelConfigList.size(); i++)
|
|
|
|
|
// {
|
|
|
|
|
// AI_Model_Param *p = &m_AIModelConfigList->AIModelConfigList.at(i);
|
|
|
|
|
// // 分割类型
|
|
|
|
|
// if (p->type != AI_Model_Type_Seg)
|
|
|
|
|
// {
|
|
|
|
|
// 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 temimg;
|
|
|
|
|
// cv::resize(AlignImg, temimg, sz);
|
|
|
|
|
// SegImgToSrcImg.setResize(AlignImg, temimg);
|
|
|
|
|
|
|
|
|
|
// if (bwriteImg)
|
|
|
|
|
// {
|
|
|
|
|
// std::string str = p->strAIModelName + "_cut_AI_in.png";
|
|
|
|
|
// cv::imwrite(str, temimg);
|
|
|
|
|
// }
|
|
|
|
|
// cv::Mat SegmaskImg;
|
|
|
|
|
// int re = p->pdetect->run(temimg, SegmaskImg, false);
|
|
|
|
|
// if (re != 0)
|
|
|
|
|
// {
|
|
|
|
|
// printf("AI_Run seg run fail \n");
|
|
|
|
|
// return re;
|
|
|
|
|
// }
|
|
|
|
|
// SegmaskImg *= 255;
|
|
|
|
|
// if (bwriteImg)
|
|
|
|
|
// {
|
|
|
|
|
// std::string str = p->strAIModelName + "_cut_AI_out_.png";
|
|
|
|
|
// cv::imwrite(str, SegmaskImg);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// cv::Size srcsz;
|
|
|
|
|
// srcsz.width = AlignImg.cols;
|
|
|
|
|
// srcsz.height = AlignImg.rows;
|
|
|
|
|
// cv::Mat temmask;
|
|
|
|
|
// cv::resize(SegmaskImg, detSrcMask, srcsz);
|
|
|
|
|
// if (bwriteImg)
|
|
|
|
|
// {
|
|
|
|
|
// std::string str = p->strAIModelName + "_detSrcMask_res.png";
|
|
|
|
|
// cv::imwrite(str, detSrcMask);
|
|
|
|
|
// }
|
|
|
|
|
// break;
|
|
|
|
|
// }
|
|
|
|
|
// printf("End --- seg \n");
|
|
|
|
|
|
|
|
|
|
// if (detSrcMask.empty())
|
|
|
|
|
// {
|
|
|
|
|
// printf("Seg is Error exit \n");
|
|
|
|
|
// return 1;
|
|
|
|
|
// }
|
|
|
|
|
// m_resultImg = AlignImg;
|
|
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
// // 定义腐蚀操作的内核
|
|
|
|
|
// cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
|
|
|
|
|
// cv::erode(detSrcMask, detSrcMask, kernel);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// std::vector<cv::Vec4i> hierarchy;
|
|
|
|
|
// std::vector<std::vector<cv::Point>> contours; // 0929-add
|
|
|
|
|
// cv::findContours(detSrcMask, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
|
|
|
|
|
// if (contours.size() != CHIP_SIZE)
|
|
|
|
|
// {
|
|
|
|
|
// std::cout << "contours size != " << CHIP_SIZE << ", actual size: " << contours.size() << std::endl;
|
|
|
|
|
// return 1;
|
|
|
|
|
// }
|
|
|
|
|
// std::vector<cv::Rect> boundRect;
|
|
|
|
|
// for (const auto &contour : contours)
|
|
|
|
|
// {
|
|
|
|
|
// boundRect.emplace_back(cv::boundingRect(contour));
|
|
|
|
|
// }
|
|
|
|
|
// if (boundRect.empty())
|
|
|
|
|
// {
|
|
|
|
|
// std::cout << "boundRect is empty\n";
|
|
|
|
|
// return 1;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// // 按从上到下、从左到右排序
|
|
|
|
|
// std::sort(boundRect.begin(), boundRect.end(), [](const cv::Rect &a, const cv::Rect &b) -> bool
|
|
|
|
|
// {
|
|
|
|
|
// int rowTolerance = 50;
|
|
|
|
|
// // 如果在同一行(y坐标相近)
|
|
|
|
|
// if (abs(a.y - b.y) <= rowTolerance)
|
|
|
|
|
// {
|
|
|
|
|
// return a.x < b.x; // 从左到右
|
|
|
|
|
// }
|
|
|
|
|
// // 否则从下到上排序
|
|
|
|
|
// return a.y > b.y; });
|
|
|
|
|
|
|
|
|
|
// int j = 0;
|
|
|
|
|
// auto showimg = AlignImg.clone();
|
|
|
|
|
// for (const auto &rect : boundRect)
|
|
|
|
|
// {
|
|
|
|
|
// auto smallImg = AlignImg(rect);
|
|
|
|
|
// cv::Mat gray;
|
|
|
|
|
// if (smallImg.channels() == 3)
|
|
|
|
|
// {
|
|
|
|
|
// cv::cvtColor(smallImg, gray, cv::COLOR_BGR2GRAY);
|
|
|
|
|
// }
|
|
|
|
|
// else
|
|
|
|
|
// {
|
|
|
|
|
// gray = smallImg.clone();
|
|
|
|
|
// }
|
|
|
|
|
// cv::Mat binaryImg;
|
|
|
|
|
// // cv::threshold(gray, binaryImg, 0, 255, cv::THRESH_BINARY_INV | cv::THRESH_OTSU);
|
|
|
|
|
// cv::threshold(gray, binaryImg, 128, 255, cv::THRESH_BINARY_INV);
|
|
|
|
|
// int nonZeroCount = cv::countNonZero(binaryImg);
|
|
|
|
|
// int totalPixels = binaryImg.rows * binaryImg.cols;
|
|
|
|
|
// double nonZeroRatio = static_cast<double>(nonZeroCount) / totalPixels;
|
|
|
|
|
// int res = 0;
|
|
|
|
|
// if (nonZeroRatio >= 0.1)
|
|
|
|
|
// {
|
|
|
|
|
// res = 1;
|
|
|
|
|
// }
|
|
|
|
|
// m_CheckResult_shareP->chipDataList.emplace_back(res);
|
|
|
|
|
|
|
|
|
|
// // 绘制
|
|
|
|
|
// if (bwriteImg)
|
|
|
|
|
// {
|
|
|
|
|
// std::string chipBinaryImgName = "chip_binary_" + std::to_string(j) + ".png";
|
|
|
|
|
// cv::imwrite(chipBinaryImgName, binaryImg); // 0929-add
|
|
|
|
|
// cv::rectangle(showimg, rect, cv::Scalar(0, 255, 0), 1);
|
|
|
|
|
// cv::putText(showimg, std::to_string(j), cv::Point(rect.x + rect.width / 2, rect.y + rect.height / 2), cv::FONT_HERSHEY_SIMPLEX, 0.6, cv::Scalar(255, 0, 0), 1);
|
|
|
|
|
// cv::putText(showimg, std::to_string(res) + "::" + std::to_string(nonZeroRatio), cv::Point(rect.x + rect.width / 2 - 50, rect.y + rect.height / 2 + 30), cv::FONT_HERSHEY_SIMPLEX, 0.6, cv::Scalar(0, 0, 255), 1);
|
|
|
|
|
// j++;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// if (bwriteImg)
|
|
|
|
|
// {
|
|
|
|
|
// cv::imwrite("chip_res.png", showimg); // 0929-add
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// printf("AI_Run>>>>>>>>>>> End \n");
|
|
|
|
|
// return 0;
|
|
|
|
|
// }
|
|
|
|
|
|