diff --git a/ALL_Det/CMakeLists.txt b/ALL_Det/CMakeLists.txt index c22eeeb..89c2617 100644 --- a/ALL_Det/CMakeLists.txt +++ b/ALL_Det/CMakeLists.txt @@ -17,6 +17,7 @@ ${PROJECT_SOURCE_DIR}/TOP_Det/include ${PROJECT_SOURCE_DIR}/Side_Det/include ${PROJECT_SOURCE_DIR}/Down_Det/include ${PROJECT_SOURCE_DIR}/Down_Angle_Det/include +${PROJECT_SOURCE_DIR}/Chip_Det/include ) # link_directories( @@ -35,6 +36,7 @@ file(GLOB SRC_LISTS ${PROJECT_SOURCE_DIR}/Side_Det/src/*.cpp ${PROJECT_SOURCE_DIR}/Down_Det/src/*.cpp ${PROJECT_SOURCE_DIR}/Down_Angle_Det/src/*.cpp + ${PROJECT_SOURCE_DIR}/Chip_Det/src/*.cpp ) add_library(ALL_Det SHARED ${SRC_LISTS}) diff --git a/ALL_Det/example/test_example.cpp b/ALL_Det/example/test_example.cpp index e0e4cee..8fab4b0 100644 --- a/ALL_Det/example/test_example.cpp +++ b/ALL_Det/example/test_example.cpp @@ -95,10 +95,16 @@ int main(int argc, char *argv[]) // ReadSystemConfig("../data/Down_Det/System_Config.json", psystem_param); // CAMERA_POSITION cam_position = CAMERA_DOWN_1;//相机位置 - //测旋转 - ReadSystemConfig("../data/Down_Det/System_Config.json", psystem_param); - CAMERA_POSITION cam_position = CAMERA_DOWN_1;//相机位置 - detect_type = DETECT_TYPE_ANGLE; + // //测旋转 + // ReadSystemConfig("../data/Down_Det/System_Config.json", psystem_param); + // CAMERA_POSITION cam_position = CAMERA_DOWN_1;//相机位置 + // detect_type = DETECT_TYPE_ANGLE; + + //测试上下料芯片检测 + detect_type = DETECT_TYPE_CHIP; + ReadSystemConfig("../data/Chip_Det/System_Config.json", psystem_param); + CAMERA_POSITION cam_position = CAMERA_Feeding;//相机位置 + // CAMERA_POSITION cam_position = CAMERA_Blanking;//相机位置 std::shared_ptr pImgCount = ImgCheckBase::GetInstance(); printf("%s %s \n", pImgCount->GetVersion().c_str(), pImgCount->GetErrorInfo().c_str()); @@ -137,7 +143,7 @@ int main(int argc, char *argv[]) if (re != 0) { } - if (!result->resultImg.empty()) + if (result && !result->resultImg.empty()) { cv::imwrite("resultImg.png", result->resultImg); } diff --git a/ALL_Det/include/ALL_Detect.hpp b/ALL_Det/include/ALL_Detect.hpp index b2e5755..b79363b 100644 --- a/ALL_Det/include/ALL_Detect.hpp +++ b/ALL_Det/include/ALL_Detect.hpp @@ -8,6 +8,7 @@ #include "Side_Detect.hpp" #include "Down_Detect.hpp" #include "Down_Angle_Detect.h" +#include "Chip_Detect.hpp" class ALL_Detect : public ImgCheckBase { diff --git a/ALL_Det/src/ALL_Detect.cpp b/ALL_Det/src/ALL_Detect.cpp index 02c13ed..a1dde69 100644 --- a/ALL_Det/src/ALL_Detect.cpp +++ b/ALL_Det/src/ALL_Detect.cpp @@ -86,6 +86,15 @@ int ALL_Detect::RunStart(void *pconfig1) } break; } + case CAMERA_Feeding: + case CAMERA_Blanking: + { + if (!m_checkBase) + m_checkBase = std::make_shared(); + runconfig.str_AIModelJson = m_cam_param.AIModel_param_path + "AIModel_Chip.json"; + // runconfig.str_RunJson = m_cam_param.check_param_path + "param_Chip.json"; + break; + } default: break; } @@ -101,19 +110,35 @@ int ALL_Detect::CheckImg(std::shared_ptr p, std::shared_ptrdetect_type == DETECT_TYPE_ANGLE) + if (p->cam_position == CAMERA_DOWN_1) { - if (p->cam_position != CAMERA_DOWN_1) + if (p->detect_type != DETECT_TYPE_QX && p->detect_type != DETECT_TYPE_ANGLE) { - std::cout << "ERROR: Down_Angle_Detect only support CAMERA_DOWN_1" << std::endl; + std::cout << "ERROR: Down Detect only support DETECT_TYPE_QX and DETECT_TYPE_ANGLE" << std::endl; + return -2; + } + } + else if (p->cam_position == CAMERA_Feeding || p->cam_position == CAMERA_Blanking) + { + if (p->detect_type != DETECT_TYPE_CHIP) + { + std::cout << "ERROR: Chip_Detect only support DETECT_TYPE_CHIP" << std::endl; return -2; } - return this->m_down_angle_detect->CheckImg(p, pResult); } else { - return this->m_checkBase->CheckImg(p, pResult); + if (p->detect_type != DETECT_TYPE_QX) + { + std::cout << "ERROR: Top/Side Detect only support DETECT_TYPE_QX" << std::endl; + return -2; + } } + + if (p->detect_type == DETECT_TYPE_ANGLE) + return this->m_down_angle_detect->CheckImg(p, pResult); + else + return this->m_checkBase->CheckImg(p, pResult); } int ALL_Detect::UpdateConfig(void *pconfig, int nConfigType) diff --git a/CheckBase/include_base/ImgCheckConfig.h b/CheckBase/include_base/ImgCheckConfig.h index bca724a..8234ec1 100644 --- a/CheckBase/include_base/ImgCheckConfig.h +++ b/CheckBase/include_base/ImgCheckConfig.h @@ -33,14 +33,16 @@ enum CAMERA_POSITION CAMERA_DOWN_1 = 2, CAMERA_SIDE_1 = 3, CAMERA_SIDE_2 = 4, - CAMERA_POSITION_COUNT = 5, + CAMERA_Feeding = 5, //上料相机 + CAMERA_Blanking = 6, //下料相机 + CAMERA_POSITION_COUNT = 7, }; enum DETECT_TYPE { - DETECT_TYPE_QX = 0, // 缺陷检测 DETECT_TYPE_ANGLE = 1, // 角度检测 - DETECT_TYPE_COUNT = 2, + DETECT_TYPE_CHIP= 2, // 芯片检测 + DETECT_TYPE_COUNT = 3, }; struct Cam_Param @@ -127,6 +129,8 @@ struct CheckResult float CenterOffsetY; //1109-add 偏移标记中心点的Y坐标 float OffsetAngle; //1109-add + std::vector chipDataList; //1106-add 芯片数据列表 + cv::Mat rotatedROIimg; //1105-add cv::Mat chipRoiImg; //1106-add 芯片区域最大外接矩形-第3幅图 cv::Mat chipMaskBigImg; //1106-add @@ -152,6 +156,7 @@ struct CheckResult } resultList.clear(); UseTimeMS = 0; + chipDataList.clear(); } }; diff --git a/CheckBase/src/AI_Moudel.cpp b/CheckBase/src/AI_Moudel.cpp index dbff5bb..146b9e9 100644 --- a/CheckBase/src/AI_Moudel.cpp +++ b/CheckBase/src/AI_Moudel.cpp @@ -134,18 +134,31 @@ int DetectModel::init(AI_ConfigInfo AIconfig) config->accelerate_type = AccelerateType::TYPE_DSP; detect_interpreter = InterpreterBuilder::build_interpretper_from_model_and_config(model, config); + if (!detect_interpreter) + { + printf("build_interpretper_from_model_and_config failed !\n"); + return EXIT_FAILURE; + } int32_t re11 = detect_interpreter->init(); printf("----4---start detect_interpreter->init() = %d \n", re11); + if (re11 != EXIT_SUCCESS) + { + return re11; + } // printf("----5---start detect_interpreter->load_model() \n"); re11 = detect_interpreter->load_model(); printf("----5---start detect_interpreter->load_model() = %d \n", re11); + if (re11 != EXIT_SUCCESS) + { + return re11; + } // printf("detect_interpreter init-------end\n"); int datasize = AIconfig.dataArr_Out[AI_DATA_IDX_HEIGHT] * AIconfig.dataArr_Out[AI_DATA_IDX_WIDTH] * AIconfig.dataArr_Out[AI_DATA_IDX_CHANNELS]; m_DetectOutput = (uint8_t *)malloc(datasize * sizeof(uint8_t)); - return 0; + return EXIT_SUCCESS; } int DetectModel::init_reconstruct(AI_ConfigInfo AIconfig) { @@ -310,14 +323,29 @@ int DetectModel::run(const cv::Mat &frame, cv::Mat &maskimg, bool bmeandv) } float *pdata = (float *)frame_fp32.data; + int result = detect_interpreter->set_input_tensor(0, (void *)pdata); + if (result != EXIT_SUCCESS) + { + printf("interpreter->set_input_tensor() failed.\n"); + return EXIT_FAILURE; + } - detect_interpreter->set_input_tensor(0, (void *)pdata); - - detect_interpreter->invoke(); + result = detect_interpreter->invoke(); + if (result != EXIT_SUCCESS) + { + printf("interpreter->invoke() failed.\n"); + return EXIT_FAILURE; + } float *out_data0 = nullptr; + uint32_t output_tensor_length = 0; - detect_interpreter->get_output_tensor(0, (void **)&out_data0); + result = detect_interpreter->get_output_tensor(0, (void **)&out_data0, &output_tensor_length); + if (result != EXIT_SUCCESS) + { + printf("interpreter->get_output_tensor() failed.\n"); + return EXIT_FAILURE; + } int kk = 0; int positive_idx = 0; @@ -326,6 +354,12 @@ int DetectModel::run(const cv::Mat &frame, cv::Mat &maskimg, bool bmeandv) // printf("in img info %d %d %d \n", sizelen, m_AIconfig.dataArr_In[AI_DATA_IDX_HEIGHT], m_AIconfig.dataArr_In[AI_DATA_IDX_WIDTH]); // printf("out img info %d %d %d \n", sizelen, m_AIconfig.dataArr_Out[AI_DATA_IDX_HEIGHT], m_AIconfig.dataArr_Out[AI_DATA_IDX_WIDTH]); // uint8_t* predata = new uint8_t[sizelen]; + if (sizelen != output_tensor_length / sizeof(float)) + { + printf("output tensor and param temsor length not match, param: %d output: %d \n", sizelen, output_tensor_length); + return EXIT_FAILURE; + } + for (int i = 0; i < sizelen; i = i + nstep) { if (out_data0[i] > 0.5) diff --git a/Chip_Det/CMakeLists.txt b/Chip_Det/CMakeLists.txt new file mode 100644 index 0000000..5e94ec1 --- /dev/null +++ b/Chip_Det/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required (VERSION 3.5) + +set(ModuleName "Cam_Chip_Det") + +# set(CMAKE_CXX_FLAGS "-Wno-error=deprecated-declarations -Wno-deprecated-declarations") + +include_directories( +/usr/local/include +/usr/local/include/aidlux/aidlite +${CMAKE_CURRENT_SOURCE_DIR}/include +${PROJECT_SOURCE_DIR}/CheckBase/include +${PROJECT_SOURCE_DIR}/CheckBase/include_base +${PROJECT_SOURCE_DIR}/CheckBase/ConfigModule/include +${PROJECT_SOURCE_DIR}/Common/include +${PROJECT_SOURCE_DIR}/Jason/include +) + +# link_directories( +# /usr/local/lib/ +# ) + + +file(GLOB SRC_LISTS + ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp + ${PROJECT_SOURCE_DIR}/Common/src/*.cpp + ${PROJECT_SOURCE_DIR}/Jason/src/*.cpp + ${PROJECT_SOURCE_DIR}/CheckBase/src/*.cpp + ${PROJECT_SOURCE_DIR}/CheckBase/src/*.c + ${PROJECT_SOURCE_DIR}/CheckBase/ConfigModule/src/*.cpp +) +add_library(Chip_Det SHARED ${SRC_LISTS}) + +target_link_libraries(Chip_Det + curl + aidlite + ) + +set(ModuleName "") + +add_subdirectory(example) \ No newline at end of file diff --git a/Chip_Det/example/CMakeLists.txt b/Chip_Det/example/CMakeLists.txt new file mode 100644 index 0000000..3eac002 --- /dev/null +++ b/Chip_Det/example/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required (VERSION 3.5) +find_package( OpenCV REQUIRED ) + +message(STATUS "oPENCV Library status:") +message(STATUS ">version:${OpenCV_VERSION}") +message(STATUS "Include:${OpenCV_INCLUDE_DIRS}") +set(ModuleName "test_BOE_Det_POL") + + +set(CMAKE_CXX_FLAGS "-Wno-error=deprecated-declarations -Wno-deprecated-declarations") + +include_directories( +/usr/local/include +/usr/local/cuda-11.3/targets/x86_64-linux/include +${CMAKE_CURRENT_SOURCE_DIR}/include +${PROJECT_SOURCE_DIR}/Common/include +) + +link_directories( +/usr/local/lib/ +) +file(GLOB SRC_LISTS ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) + +add_executable(test_TOP_Det ${SRC_LISTS}) + +target_link_libraries(test_TOP_Det + pthread + TOP_Det + curl + ${OpenCV_LIBS} +) + +set(ModuleName "") \ No newline at end of file diff --git a/Chip_Det/example/test_example.cpp b/Chip_Det/example/test_example.cpp new file mode 100644 index 0000000..d89f911 --- /dev/null +++ b/Chip_Det/example/test_example.cpp @@ -0,0 +1,162 @@ +#include +#include +#include "json/json.h" +#include "ImgCheckBase.h" +#include "ImgCheckConfig.h" +#include +#include "CheckUtil.hpp" +#include "SaveImageFile.h" + +struct SystemConfigParam +{ + std::string str_CheckConfigJson; // 检测基础参数json文件 + std::string str_AIModelJson; // AI 模型 json文件 + std::string str_ProcessNodeJson; // 过程节点 json文件 + std::string str_detImgPath; // 测试图片路径; + std::string str_ImagesPath; // 批量测试 + std::string str_SaveImagesPath; // 批量保存测试 + SystemConfigParam() + { + str_AIModelJson = ""; + str_ProcessNodeJson = ""; + str_detImgPath = ""; + str_ImagesPath = ""; + str_SaveImagesPath = ""; + } + bool valid() + { + if (str_AIModelJson.size() && + str_ProcessNodeJson.size()) + { + return true; + } + return false; + } +}; + +bool ReadSystemConfig(const std::string &strPath, std::shared_ptr &pConfig) +{ + printf("Reading system config %s\n", strPath.c_str()); + Json::CharReaderBuilder builder; + builder["collectComments"] = true; + Json::Value root; + std::string err; + std::ifstream ifs(strPath); + if (!ifs.is_open()) + { + printf("error:file is open\n"); + return false; + } + if (!Json::parseFromStream(builder, ifs, &root, &err)) + { + printf("error:parseFromStream\n"); + return false; + } + pConfig = std::make_shared(); + // path + pConfig->str_detImgPath = root["detImgPath"].asString(); + pConfig->str_ImagesPath = root["ImagesPath"].asString(); + pConfig->str_SaveImagesPath = root["SaveImagesPath"].asString(); + pConfig->str_CheckConfigJson = root["CheckConfigJson"].asString(); + pConfig->str_AIModelJson = root["AIModelJson"].asString(); + pConfig->str_ProcessNodeJson = root["ProcessNodeJson"].asString(); + printf("str_AIModelJson %s ProcessNodeJson %s\n", pConfig->str_AIModelJson.c_str(), pConfig->str_ProcessNodeJson.c_str()); + return pConfig->valid(); +} + +int main(int argc, char *argv[]) +{ + bool bsave = false; + if (argc > 1 && string(argv[1]) != "-h") + { + + if (string(argv[1]) == "-s") + { + bsave = true; + } + } + + printf("test ImgMeasure Count >>>>>> start bsave %d\n",bsave); + std::shared_ptr psystem_param; + + ReadSystemConfig("../data/TOP_Det/System_Config.json", psystem_param); + std::shared_ptr pImgCount = ImgCheckBase::GetInstance(); + printf("%s %s \n", pImgCount->GetVersion().c_str(), pImgCount->GetErrorInfo().c_str()); + + cv::Mat img = cv::imread(psystem_param->str_detImgPath); + printf("img path %s \n",psystem_param->str_detImgPath.c_str()); + if (img.empty()) + { + printf(" det img is empty >> exit \n"); + return 1; + /* code */ + } + + printf("%d %d \n", img.cols, img.rows); + + RunInfoST runconfig; + runconfig.str_AIModelJson = psystem_param->str_AIModelJson; + runconfig.str_RunJson = psystem_param->str_CheckConfigJson; + + int re; + re = pImgCount->RunStart((void *)&runconfig); + if (re != 0) + { + printf("ImgMeasure Init Fail >>>>>>> \n"); + + return 1; + } + + std::shared_ptr tem = std::make_shared(); + tem->img = img; + tem->bdebugSaveImg = bsave; + std::shared_ptr result; + re = pImgCount->CheckImg(tem, result); + if (re != 0) + { + } + if (!result->resultImg.empty()) + { + cv::imwrite("resultImg.png", result->resultImg); + } + + std::string strImgPath = psystem_param->str_ImagesPath; + if (strImgPath != "") + { + std::cout << strImgPath << std::endl; + std::vector img_paths; + bool bgo = true; + try + { + cv::glob(strImgPath, img_paths, true); + } + catch (const std::exception &e) + { + bgo = false; + std::cout << "Invalid or non-existent directory: " << strImgPath << std::endl; + } + if (bgo) + { + SaveImageFile sv; + sv.SetSavePath(psystem_param->str_SaveImagesPath); + for (int i = 0; i < img_paths.size(); i++) + { + std::cout << img_paths[i] << std::endl; + std::string str = img_paths[i]; + std::string strName = CheckUtil::splitFilePath(str); + cv::Mat img = cv::imread(str); + // + + std::shared_ptr tem = std::make_shared(); + tem->img = img; + std::shared_ptr result; + re = pImgCount->CheckImg(tem, result); + printf("%d %d %s det time %f \n", img.cols, img.rows, strName.c_str(), result->UseTimeMS); + sv.saveImg(img, result->resultImg, strName, result->nresult); + } + } + } + + printf("test ImgMeasure Count >>>>>> End \n"); + return 0; +} \ No newline at end of file diff --git a/Chip_Det/include/Chip_Detect.hpp b/Chip_Det/include/Chip_Detect.hpp new file mode 100644 index 0000000..d0b3d0b --- /dev/null +++ b/Chip_Det/include/Chip_Detect.hpp @@ -0,0 +1,60 @@ +#ifndef Chip_Detect_H_ +#define Chip_Detect_H_ + +#include "BaseInclude.h" +#include "AI_Moudel.hpp" +#include "BlobBase.h" + +class Chip_Detect : public ImgCheckBase +{ +public: + Chip_Detect(); + ~Chip_Detect(); + + // 初始化参数 pconfig 参数指针 返回:0 成功 其他异常 + int RunStart(void *pconfig1 = NULL); + + // 阻塞式检测 + int CheckImg(std::shared_ptr p, std::shared_ptr &pResult); + + // 更新参数 pconfig 参数指针,nConfigType 需要更新的参数类型 返回:0 成功 其他异常 + int UpdateConfig(void *pconfig, int nConfigType); + +private: + // 检测 + int CheckRun(); + // 初始化数据 + int CheckImgInit(); + // 初始化模型 + int InitModel(); + + int Thread_Run(const cv::Mat &img); + + int Draw(const cv::Mat &img, cv::Mat &resultimg); + + int GetBlob(cv::Mat maskImg); + + int ImgAlinRotate(const cv::Mat &img, cv::Mat &alignImg); + + int DetectImg(const cv::Mat &img); + +private: + int m_nErrorCode; // 错误代码 + std::shared_ptr DetImgInfo_shareP; + std::shared_ptr m_CheckResult_shareP; + std::shared_ptr m_AIModelConfigList; + std::shared_ptr m_CheckBaseConfig; + RunInfoST m_pRunConfig; + + ERROR_DOTS_BLOBS m_blob; + bool bwriteImg; + + bool m_Update_config; + + std::vector m_resultList; + cv::Rect m_AlignMaxRoi; + cv::Mat m_resultImg; + cv::Mat m_reconstructImg; +}; + +#endif \ No newline at end of file diff --git a/Chip_Det/src/Chip_Detect.cpp b/Chip_Det/src/Chip_Detect.cpp new file mode 100644 index 0000000..e920821 --- /dev/null +++ b/Chip_Det/src/Chip_Detect.cpp @@ -0,0 +1,800 @@ +#include "Chip_Detect.hpp" +#include "CheckErrorCode.hpp" +#include "CheckUtil.hpp" +#include "DetCommonDefine.hpp" +using namespace cv; +using namespace std; +// 检测模型 单个小图 输入模型图片尺寸 +#define SRC_CUT_IMAGE_WIDTH 512 +#define SRC_CUT_IMAGE_HEIGHT 512 +#define CHIP_SIZE 140 +// std::shared_ptr ImgCheckBase::GetInstance() +// { +// return std::shared_ptr(new Chip_Detect()); +// } + +Chip_Detect::Chip_Detect() +{ + bwriteImg = false; + m_Update_config = false; +} + +Chip_Detect::~Chip_Detect() +{ + printf("----------------~Chip_Detect \n"); +} + +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) + // { + // 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; +} + +int Chip_Detect::CheckImg(std::shared_ptr p, std::shared_ptr &pResult) +{ + DetImgInfo_shareP = p; + // printf("%d DetImgInfo_shareP count %ld \n", m_RunConfig.nThreadIdx, DetImgInfo_shareP.use_count()); + int re = CheckRun(); + + pResult = m_CheckResult_shareP; + m_CheckResult_shareP.reset(); + DetImgInfo_shareP.reset(); + if (!m_resultImg.empty()) + { + m_resultImg.release(); + } + + return re; +} + +int Chip_Detect::UpdateConfig(void *pconfig, int nConfigType) +{ + m_Update_config = true; + return 0; +} + +int Chip_Detect::CheckRun() +{ + printf("CheckRun start \n"); + long t1, t2; + 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); + if (DetImgInfo_shareP->bdebugSaveImg) + { + bwriteImg = true; + } + + // 芯片检测 + int re = 0; + re = DetectImg(detimg); + if (0 != re) + { + // 失败NG + m_CheckResult_shareP->nresult = 1; + return re; + } + t2 = CheckUtil::getcurTime(); + m_CheckResult_shareP->UseTimeMS = t2 - t1; + + printf("Check time %ld \n", t2 - t1); + return 0; +} + +int Chip_Detect::CheckImgInit() +{ + m_CheckResult_shareP = std::make_shared(); + m_nErrorCode = CHECK_OK; + memset(&m_blob, 0, sizeof(ERROR_DOTS_BLOBS)); + m_resultList.erase(m_resultList.begin(), m_resultList.end()); + m_resultList.clear(); + m_AlignMaxRoi = cv::Rect(0, 0, 0, 0); + return 0; +} + +int Chip_Detect::InitModel() +{ + + printf("InitModel>>>>>>>>>>> start \n"); + int re = 0; + + for (int i = 0; i < m_AIModelConfigList->AIModelConfigList.size(); i++) + { + AI_Model_Param *p = &m_AIModelConfigList->AIModelConfigList.at(i); + p->pdetect = std::make_shared(); + std::string str = p->strModelPath; + AI_ConfigInfo config; + config.strdetect_model_path = str; + config.ai_Model_Type = AI_MODEL_TYPE_FLOAT16; + config.dataArr_In[AI_DATA_IDX_T] = 1; + config.dataArr_In[AI_DATA_IDX_HEIGHT] = p->in_img.height; + config.dataArr_In[AI_DATA_IDX_WIDTH] = p->in_img.width; + config.dataArr_In[AI_DATA_IDX_CHANNELS] = p->in_img.channels; + + config.dataArr_Out[AI_DATA_IDX_T] = 1; + config.dataArr_Out[AI_DATA_IDX_HEIGHT] = p->out_img.height; + config.dataArr_Out[AI_DATA_IDX_WIDTH] = p->out_img.width; + config.dataArr_Out[AI_DATA_IDX_CHANNELS] = p->out_img.channels; + config.userflag = 1; + + // if (p->type == AI_Model_Type_Reconstruct) + // { + // re = p->pdetect->init_reconstruct(config); + // } + // else + { + re = p->pdetect->init(config); + } + if (re != 0) + { + printf("InitModel>>>>>>>>>>> Fail \n"); + return re; + } + } + printf("InitModel>>>>>>>>>>> End \n"); + 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(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) + { + cv::cvtColor(img, resultimg, cv::COLOR_GRAY2BGR); + } + else + { + resultimg = img.clone(); + } + // //裁剪到包括产品(1600x1200) + // int w = 1600; + // int h = 1200; + // cv::Point center{this->m_AlignMaxRoi.x + this->m_AlignMaxRoi.width / 2, this->m_AlignMaxRoi.y + this->m_AlignMaxRoi.height / 2}; + + // int x = center.x - w / 2; + // int y = center.y - h / 2; + + // // 确保裁剪区域不超出图像边界 + // x = std::max(0, x); + // y = std::max(0, y); + // x = std::min(x, img.cols - w); + // y = std::min(y, img.rows - h); + + // // 创建裁剪区域 + // cv::Rect cropRoi(x, y, w, h); + // resultimg = resultimg(cropRoi); + + // cv::polylines(resultimg, m_CheckBaseConfig->pointArry, true, cv::Scalar(0, 255, 0), 2); + // auto regions = m_CheckBaseConfig->nodeConfigArr[0].regionConfigArr; + // for (int i = 0; i < regions.size(); i++) + // { + // cv::polylines(resultimg, regions[i].basicInfo.pointArry, true, cv::Scalar(0, 255, 0), 2); + // } + + int fontFace = cv::FONT_HERSHEY_SIMPLEX; // 字体样式 + double fontScale = 1; // 字体大小 + cv::Scalar color_NG(0, 0, 255); // 文本颜色 + cv::Scalar color_OK(0, 255, 0); // 文本颜色 + int thickness = 1; // 文本线条粗细 + for (int i = 0; i < m_resultList.size(); i++) + { + cv::Scalar color; + color = color_OK; + if (m_resultList.at(i).nresult == 0 && m_resultList.at(i).nYsresult == 0) + { + continue; + } + + if (m_resultList.at(i).nresult != 0) + { + color = color_NG; + } + else + { + color = cv::Scalar(0, 255, 255); + } + cv::Rect roi = m_resultList.at(i).roi; + cv::Point pc; + pc.x = roi.x + roi.width * 0.5; + pc.y = roi.y + roi.height * 0.5; + int rw = roi.width * 0.5; + int rh = roi.height * 0.5; + int r = std::sqrt(rw * rw + rh * rh) * 1.1 + 8; + + if (r < 20) + { + r = 20; + } + cv::circle(resultimg, pc, r, color); + char buffer[32]; + sprintf(buffer, " A %.3f HJ %d ", m_resultList.at(i).area_mm2, m_resultList.at(i).hj); + + string show_info = buffer; + + cv::Point p; + p.x = m_resultList.at(i).roi.x; + p.y = m_resultList.at(i).roi.y; + cv::putText(resultimg, show_info, p, fontFace, 1, color, 1); + } + // 裁剪 + cv::Size dstSize(RESULT_WIDTH, RESULT_HEIGHT); + cv::resize(resultimg, resultimg, dstSize); + return 0; +} + +int Chip_Detect::GetBlob(cv::Mat maskImg) +{ + + unsigned char *pimgdata = (unsigned char *)maskImg.data; + + int width = maskImg.cols; + int height = maskImg.rows; + if (maskImg.empty()) + { + return 1; + } + + long t1 = CheckUtil::getcurTime(); + GetImg_Blob(&m_blob, pimgdata, width, height); + + printf("blob num %d \n", m_blob.blobCount); + + if (bwriteImg) + { + cv::Mat tm; + cv::cvtColor(maskImg, tm, cv::COLOR_GRAY2RGB); // 彩色 可选项 + for (int i = 0; i < m_blob.blobCount; i++) + { + 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; + + cv::rectangle(tm, roi, cv::Scalar(0, 0, 255)); + } + cv::imwrite("image_resize_blob.png", tm); + + // getchar(); + } + + long t2 = CheckUtil::getcurTime(); + + return 0; +} + +int Chip_Detect::ImgAlinRotate(const cv::Mat &img, cv::Mat &alignImg) +{ + cv::Mat ColorImg; + if (img.channels() == 1) + { + cv::cvtColor(img, ColorImg, cv::COLOR_GRAY2BGR); + } + else + { + ColorImg = img; + } + ROI2ROI_SCALE AlignToSrc; + + 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_Align) + { + 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(ColorImg, temimg, sz); + AlignToSrc.setResize(ColorImg, temimg); + if (bwriteImg) + { + std::string str = p->strAIModelName + "_AI_in.png"; + cv::imwrite(str, temimg); + } + + cv::Mat outimg; + int re = p->pdetect->run(temimg, outimg, false); + if (re != 0) + { + printf("AI_Run Align run fail \n"); + return re; + } + if (bwriteImg) + { + std::string str = p->strAIModelName + "_AI_out.png"; + cv::imwrite(str, outimg); + } + + m_AlignMaxRoi = CheckUtil::findMaxBoundingBox(outimg); + AlignToSrc.UPdateRoi(m_AlignMaxRoi); + + CheckUtil::printROI(m_AlignMaxRoi, "maxroi"); + + alignImg = ColorImg(m_AlignMaxRoi); + if (bwriteImg) + { + cv::rectangle(ColorImg, m_AlignMaxRoi, cv::Scalar(255, 0, 0)); + std::string str = p->strAIModelName + "_AI_out_res.png"; + cv::imwrite(str, ColorImg); + } + + // printf("AI_Run  time  %ld \n", t2 - t1); + + break; + } + + if (alignImg.empty()) + { + printf("Align is Error exit \n"); + return 1; + } + + // 判断尺寸 + 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) + // { + // } + // 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::cvtColor(alignImg, ColorCodeImg, cv::COLOR_GRAY2BGR); + } + else + { + ColorCodeImg = alignImg; + } + + for (int i = 0; i < m_AIModelConfigList->AIModelConfigList.size(); i++) + { + 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; + int re = p->pdetect->run(temimg2, outimg, false); + if (re != 0) + { + printf("CodeAlign----p->pdetect->run--failed \n"); + return re; + } + + 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; +} + +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 hierarchy; + std::vector> 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 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(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; +} diff --git a/Down_Angle_Det/src/Down_Angle_Detect.cpp b/Down_Angle_Det/src/Down_Angle_Detect.cpp index 8032581..bb1e592 100644 --- a/Down_Angle_Det/src/Down_Angle_Detect.cpp +++ b/Down_Angle_Det/src/Down_Angle_Detect.cpp @@ -416,21 +416,21 @@ int Down_Angle_Detect::CheckRun() cv::Point2f detROi2f{detROI.x, detROI.y}; cv::Point2f BigImgChipCenter = CenterP + detROi2f; // 1105 cv::Point2f CenterOffsetP = BigImgChipCenter - LabelCenterP; - float offsetAngle = angleOut - LabelAngle; // //角度偏差 + float offsetAngle = angleOut - LabelAngle; // //角度偏差 double x_coeff = pdetConfig->calibration_coeff_x; // 1107-add double y_coeff = pdetConfig->calibration_coeff_y; // 1107-add - //基于图像坐标偏移 + // 基于图像坐标偏移 double x_pixel_offset = CenterOffsetP.x * x_coeff; double y_pixel_offset = CenterOffsetP.y * y_coeff; - //换算到基于机械臂的世界坐标系 - m_CheckResult_shareP->CenterOffsetX = y_pixel_offset; //机械手的x对应像素y偏移 - m_CheckResult_shareP->CenterOffsetY = -x_pixel_offset; //机械手的y对应像素x偏移取负 - m_CheckResult_shareP->OffsetAngle = offsetAngle; - + // 换算到基于机械臂的世界坐标系 + m_CheckResult_shareP->CenterOffsetX = y_pixel_offset; // 机械手的x对应像素y偏移 + m_CheckResult_shareP->CenterOffsetY = -x_pixel_offset; // 机械手的y对应像素x偏移取负 + m_CheckResult_shareP->OffsetAngle = offsetAngle; + std::cout << "OffsetXOut=" << CenterOffsetP.x << " resultMoveX=" << m_CheckResult_shareP->CenterOffsetX << std::endl; std::cout << "OffsetYOut=" << CenterOffsetP.y << " resultMoveY=" << m_CheckResult_shareP->CenterOffsetY << std::endl; - std::cout << "LabelAngle=" << LabelAngle << " Offsetangle=" << offsetAngle << std::endl; + std::cout << "LabelAngle=" << LabelAngle << " Offsetangle=" << offsetAngle << std::endl; t2 = CheckUtil::getcurTime(); m_CheckResult_shareP->UseTimeMS = t2 - t1; @@ -482,6 +482,11 @@ int Down_Angle_Detect::InitModel() { re = p->pdetect->init(config); } + if (re != 0) + { + printf("InitModel>>>>>>>>>>> Fail \n"); + return re; + } } printf("InitModel>>>>>>>>>>> End \n"); @@ -558,17 +563,14 @@ int Down_Angle_Detect::AI_Run(const cv::Mat &img, cv::Point s2StartP, double Lab } cv::Mat outimg; - // p->pdetect->run(temimg, outimg, true); - if (p->pdetect->run(temimg, outimg, false) == 0) - { - std::cout << "AI_Model_Type_Align---p->pdetect->run-success----" << std::endl; - } - else + int re = p->pdetect->run(temimg, outimg, false); + if (re != 0) { - std::cout << "AI_Model_Type_Align-------s1-Chip-Align----p->pdetect->run--failed--- return 1" << std::endl; + printf("AI_Model_Type_Align fail \n"); m_resultImg = ColorImg; - return 1; // 直接返回 -模型推理出错 + return re; } + t2 = CheckUtil::getcurTime(); std::cout << "1.0 chipLoc model runout---time cost -----------" << t2 - t1 << "ms" << std::endl; @@ -742,18 +744,13 @@ int Down_Angle_Detect::AI_Run(const cv::Mat &img, cv::Point s2StartP, double Lab } cv::Mat outimg; - // p->pdetect->run(temimg, outimg, true); - if (p->pdetect->run(temimg, outimg, false) == 0) + int re = p->pdetect->run(temimg, outimg, false); + if (re != 0) { - std::cout << "AI_Model_Type_Align---p->pdetect->run-success----" << std::endl; - } - else - { - std::cout << "AI_Model_Type_Align-------s1-Chip-Align----p->pdetect->run--failed--- return 1" << std::endl; + printf("AI_Model_Type_Align fail \n"); m_resultImg = ColorImg; - return 1; // 直接返回 -模型推理出错 + return re; } - if (bwriteImg) { std::string str = p->strAIModelName + "_AI_out.png"; diff --git a/Down_Det/include/Down_Detect.hpp b/Down_Det/include/Down_Detect.hpp index e364260..d584ac2 100644 --- a/Down_Det/include/Down_Detect.hpp +++ b/Down_Det/include/Down_Detect.hpp @@ -58,6 +58,8 @@ private: cv::Rect m_AlignMaxRoi; cv::Mat m_resultImg; cv::Mat m_reconstructImg; + cv::Mat m_dT_positive; + cv::Mat m_dT_reverse; }; #endif \ No newline at end of file diff --git a/Down_Det/src/Down_Detect.cpp b/Down_Det/src/Down_Detect.cpp index 2184251..d2d9272 100644 --- a/Down_Det/src/Down_Detect.cpp +++ b/Down_Det/src/Down_Detect.cpp @@ -11,6 +11,7 @@ using namespace std; // { // return std::shared_ptr(new Down_Detect()); // } +#define DOWN_TEMPLATE_PATH "/home/aidlux/ZYWL/" Down_Detect::Down_Detect() { @@ -52,6 +53,14 @@ int Down_Detect::RunStart(void *pconfig1) printf("AI_DetModel Init Fail\n"); return re; } + // // 初始化模板图 + // m_dT_positive = cv::imread(std::string(DOWN_TEMPLATE_PATH) + "dt_positive.png", cv::IMREAD_COLOR); // 正 + // m_dT_reverse = cv::imread(std::string(DOWN_TEMPLATE_PATH) + "dt_reverse.png", cv::IMREAD_COLOR); // 倒 + // if (m_dT_positive.empty() || m_dT_reverse.empty()) + // { + // std::cout << "Failed to load down template image!" << std::endl; + // return 1; + // } printf("init end \n"); m_bInitSucc = true; return 0; @@ -183,6 +192,11 @@ int Down_Detect::InitModel() { re = p->pdetect->init(config); } + if (re != 0) + { + printf("InitModel>>>>>>>>>>> Fail \n"); + return re; + } } printf("InitModel>>>>>>>>>>> End \n"); return 0; @@ -461,7 +475,12 @@ int Down_Detect::ImgAlinRotate(const cv::Mat &img, cv::Mat &alignImg) } cv::Mat outimg; - p->pdetect->run(temimg, outimg, false); + int re = p->pdetect->run(temimg, outimg, false); + if (re != 0) + { + printf("AI_Run Align run fail \n"); + return re; + } if (bwriteImg) { std::string str = p->strAIModelName + "_AI_out.png"; @@ -525,16 +544,27 @@ int Down_Detect::ImgAlinRotate(const cv::Mat &img, cv::Mat &alignImg) // // 模板匹配定位 // 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); + // cv::resize(alignImg_copy, alignImg_copy, cv::Size(RESULT_WIDTH, RESULT_HEIGHT)); + // if (bwriteImg) + // { + // cv::imwrite("alignImg_copy.png", alignImg_copy); + // } + // if (m_dT_positive.empty() || m_dT_reverse.empty()) + // { + // std::cout << "down template img is empty" << std::endl; + // return 1; + // } + + // auto [maxVal1, matchPoint1] = templateMatchBasic(alignImg_copy, m_dT_positive, cv::TM_CCOEFF_NORMED); + // auto [maxVal2, matchPoint2] = templateMatchBasic(alignImg_copy, m_dT_reverse, cv::TM_CCOEFF_NORMED); + // if (bwriteImg) + // { + // cv::rectangle(alignImg_copy, matchPoint1, + // cv::Point(matchPoint1.x + m_dT_positive.cols, matchPoint1.y + m_dT_positive.rows), + // cv::Scalar(0, 255, 0), 2); // 绿色矩形 + // cv::imwrite("alignImg_temMatch.png", alignImg_copy); + // } + // if (maxVal2 > maxVal1) // { // // 需要旋转 @@ -593,7 +623,12 @@ int Down_Detect::DetectImg(const cv::Mat &img) cv::imwrite(str, temimg); } cv::Mat SegmaskImg; - p->pdetect->run(temimg, SegmaskImg, false); + int re = p->pdetect->run(temimg, SegmaskImg, false); + if (re != 0) + { + printf("AI_Run seg run fail \n"); + return re; + } SegmaskImg *= 255; if (bwriteImg) { @@ -771,7 +806,7 @@ std::tuple Down_Detect::templateMatchBasic(const Mat &src, co // 执行模板匹配 matchTemplate(src, templ, result, method); - + cv::imwrite("template_match_result.png", result); // 寻找最佳匹配位置 double minVal, maxVal; Point minLoc, maxLoc; diff --git a/Side_Det/src/Side_Detect.cpp b/Side_Det/src/Side_Detect.cpp index 7df21ca..7643831 100644 --- a/Side_Det/src/Side_Detect.cpp +++ b/Side_Det/src/Side_Detect.cpp @@ -63,7 +63,7 @@ int Side_Detect::CheckImg(std::shared_ptr p, std::shared_ptrimg; - //准备结果图 + // 准备结果图 cv::resize(detimg.clone(), m_CheckResult_shareP->resultImg, cv::Size(800, 600)); if (detimg.empty()) { @@ -116,7 +116,7 @@ int Side_Detect::CheckRun() re = ImgAlinRotate(detimg, AlignImg); if (0 != re) { - //失败NG + // 失败NG m_CheckResult_shareP->nresult = 1; return re; } @@ -124,7 +124,7 @@ int Side_Detect::CheckRun() re = DetectImg(AlignImg); if (0 != re) { - //失败NG + // 失败NG m_CheckResult_shareP->nresult = 1; return re; } @@ -184,6 +184,11 @@ int Side_Detect::InitModel() { re = p->pdetect->init(config); } + if (re != 0) + { + printf("InitModel>>>>>>>>>>> Fail \n"); + return re; + } } printf("InitModel>>>>>>>>>>> End \n"); return 0; @@ -307,20 +312,20 @@ int Side_Detect::Draw(const cv::Mat &img, cv::Mat &resultimg) { resultimg = img.clone(); } - //裁剪到包括产品(1600x1200) + // 裁剪到包括产品(1600x1200) int w = 1600; int h = 1200; cv::Point center{this->m_AlignMaxRoi.x + this->m_AlignMaxRoi.width / 2, this->m_AlignMaxRoi.y + this->m_AlignMaxRoi.height / 2}; int x = center.x - w / 2; int y = center.y - h / 2; - + // 确保裁剪区域不超出图像边界 x = std::max(0, x); y = std::max(0, y); x = std::min(x, img.cols - w); y = std::min(y, img.rows - h); - + // 创建裁剪区域 cv::Rect cropRoi(x, y, w, h); resultimg = resultimg(cropRoi).clone(); @@ -356,7 +361,7 @@ int Side_Detect::Draw(const cv::Mat &img, cv::Mat &resultimg) } cv::Rect roi = m_resultList.at(i).roi; cv::Point pc; - pc.x = roi.x + roi.width * 0.5 + (m_AlignMaxRoi.x - cropRoi.x);//转换为cropRoi中坐标 + pc.x = roi.x + roi.width * 0.5 + (m_AlignMaxRoi.x - cropRoi.x); // 转换为cropRoi中坐标 pc.y = roi.y + roi.height * 0.5 + (m_AlignMaxRoi.y - cropRoi.y); int rw = roi.width * 0.5; int rh = roi.height * 0.5; @@ -373,7 +378,7 @@ int Side_Detect::Draw(const cv::Mat &img, cv::Mat &resultimg) string show_info = buffer; cv::Point p; - p.x = m_resultList.at(i).roi.x + (m_AlignMaxRoi.x - cropRoi.x);//转换为cropRoi中坐标 + p.x = m_resultList.at(i).roi.x + (m_AlignMaxRoi.x - cropRoi.x); // 转换为cropRoi中坐标 p.y = m_resultList.at(i).roi.y + (m_AlignMaxRoi.y - cropRoi.y); cv::putText(resultimg, show_info, p, fontFace, 1, color, 1); } @@ -462,7 +467,12 @@ int Side_Detect::ImgAlinRotate(const cv::Mat &img, cv::Mat &alignImg) } cv::Mat outimg; - p->pdetect->run(temimg, outimg, false); + int re = p->pdetect->run(temimg, outimg, false); + if (re != 0) + { + printf("AI_Run Align run fail \n"); + return re; + } if (bwriteImg) { std::string str = p->strAIModelName + "_AI_out.png"; @@ -492,7 +502,7 @@ int Side_Detect::ImgAlinRotate(const cv::Mat &img, cv::Mat &alignImg) printf("Align is empty, Error exit \n"); return 1; } - //判断尺寸 + // 判断尺寸 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); @@ -501,7 +511,7 @@ int Side_Detect::ImgAlinRotate(const cv::Mat &img, cv::Mat &alignImg) 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"); + printf("Align error, no product\n"); return 1; } @@ -575,7 +585,12 @@ int Side_Detect::DetectImg(const cv::Mat &img) cv::imwrite(str, temimg); } cv::Mat SegmaskImg; - p->pdetect->run(temimg, SegmaskImg, false); + int re = p->pdetect->run(temimg, SegmaskImg, false); + if (re != 0) + { + printf("AI_Run seg run fail \n"); + return re; + } SegmaskImg *= 255; if (bwriteImg) { diff --git a/TOP_Det/src/Top_Detect.cpp b/TOP_Det/src/Top_Detect.cpp index 31a4bef..546e779 100644 --- a/TOP_Det/src/Top_Detect.cpp +++ b/TOP_Det/src/Top_Detect.cpp @@ -182,6 +182,11 @@ int Top_Detect::InitModel() { re = p->pdetect->init(config); } + if (re != 0) + { + printf("InitModel>>>>>>>>>>> Fail \n"); + return re; + } } printf("InitModel>>>>>>>>>>> End \n"); return 0; @@ -460,7 +465,12 @@ int Top_Detect::ImgAlinRotate(const cv::Mat &img, cv::Mat &alignImg) } cv::Mat outimg; - p->pdetect->run(temimg, outimg, false); + int re = p->pdetect->run(temimg, outimg, false); + if (re != 0) + { + printf("AI_Run Align run fail \n"); + return re; + } if (bwriteImg) { std::string str = p->strAIModelName + "_AI_out.png"; @@ -566,15 +576,13 @@ int Top_Detect::ImgAlinRotate(const cv::Mat &img, cv::Mat &alignImg) } cv::Mat outimg; - if ((p->pdetect->run(temimg2, outimg, false)) == 0) // 加载加密后的.bin.aidem文件 - { - std::cout << "CodeAlign----p->pdetect->run--success---" << std::endl; - } - else + int re = p->pdetect->run(temimg2, outimg, false); + if (re != 0) { - std::cout << "CodeAlign----p->pdetect->run--failed--- return 5" << std::endl; - return 5; // 返回5 + printf("CodeAlign----p->pdetect->run--failed \n"); + return re; } + t2 = CheckUtil::getcurTime(); std::cout << "1.2 codeLoc model-run-----time cost -----------" << t2 - t1 << "ms" << std::endl; @@ -622,8 +630,8 @@ int Top_Detect::ImgAlinRotate(const cv::Mat &img, cv::Mat &alignImg) { // 二维码在左侧则旋转90°逆时针 cv::rotate(alignImg, alignImg, cv::ROTATE_90_COUNTERCLOCKWISE); - } - else if(codeCenterPt.x > outimg.cols / 2) + } + else if (codeCenterPt.x > outimg.cols / 2) { // 二维码在右侧则旋转90°顺时针 cv::rotate(alignImg, alignImg, cv::ROTATE_90_CLOCKWISE); @@ -692,7 +700,12 @@ int Top_Detect::DetectImg(const cv::Mat &img) cv::imwrite(str, temimg); } cv::Mat SegmaskImg; - p->pdetect->run(temimg, SegmaskImg, false); + int re = p->pdetect->run(temimg, SegmaskImg, false); + if (re != 0) + { + printf("AI_Run seg run fail \n"); + return re; + } SegmaskImg *= 255; if (bwriteImg) { @@ -856,4 +869,3 @@ int Top_Detect::DetectImg(const cv::Mat &img) // getchar(); return 0; } -