parent
34b76f5f1c
commit
a948ff6c9b
@ -0,0 +1,7 @@
|
|||||||
|
/build
|
||||||
|
/lib
|
||||||
|
/include
|
||||||
|
/data
|
||||||
|
/SaveImg
|
||||||
|
/.cache
|
||||||
|
.vscode/launch.json
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Linux",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/**",
|
||||||
|
"/usr/local/include/opencv4"
|
||||||
|
],
|
||||||
|
"defines": [],
|
||||||
|
"compilerPath": "/usr/bin/gcc",
|
||||||
|
"cStandard": "c17",
|
||||||
|
"cppStandard": "gnu++14",
|
||||||
|
"intelliSenseMode": "linux-gcc-x64"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
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(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_FLAGS "-Wno-error=deprecated-declarations -Wno-deprecated-declarations")
|
||||||
|
|
||||||
|
find_package(CUDA REQUIRED)
|
||||||
|
message(STATUS "cuda version: " ${CUDA_VERSION_STRING})
|
||||||
|
message(STATUS "cuda CUDA_INCLUDE_DIRS: " ${CUDA_INCLUDE_DIRS})
|
||||||
|
include_directories(${CUDA_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
|
${PROJECT_SOURCE_DIR}/AIEngineModule/include
|
||||||
|
${PROJECT_SOURCE_DIR}/AIEngineModule/include_base
|
||||||
|
)
|
||||||
|
|
||||||
|
link_directories(
|
||||||
|
/usr/local/lib/
|
||||||
|
)
|
||||||
|
set(CMAKE_CUDA_ARCHITECTURES 86)
|
||||||
|
set(CMAKE_CUDA_COMPILER "/usr/local/cuda/bin/nvcc")
|
||||||
|
enable_language(CUDA)
|
||||||
|
file(GLOB SRC_LISTS
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
|
||||||
|
${PROJECT_SOURCE_DIR}/AIEngineModule/src/*.cpp
|
||||||
|
${PROJECT_SOURCE_DIR}/AIEngineModule/src/*.c
|
||||||
|
${PROJECT_SOURCE_DIR}/AIEngineModule/src/*.cu
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable("ai_test" ${SRC_LISTS})
|
||||||
|
|
||||||
|
target_link_libraries("ai_test"
|
||||||
|
pthread
|
||||||
|
z
|
||||||
|
nvinfer
|
||||||
|
${CUDA_LIBRARIES}
|
||||||
|
${OpenCV_LIBS}
|
||||||
|
)
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
* @Author: xiewenji 527774126@qq.com
|
||||||
|
* @Date: 2025-07-04 16:18:48
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @LastEditTime: 2025-07-04 16:23:28
|
||||||
|
* @FilePath: /AI_SO_Test/AIEngineModule/example/deal.cpp
|
||||||
|
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
*/
|
||||||
|
#include "deal.h"
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
#ifndef _deal_HPP_
|
||||||
|
#define _deal_HPP_
|
||||||
|
|
||||||
|
#endif //_CORELOGICFACTORY_HPP_
|
||||||
@ -0,0 +1,302 @@
|
|||||||
|
/*
|
||||||
|
* @Author: xiewenji 527774126@qq.com
|
||||||
|
* @Date: 2025-07-04 16:18:48
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @LastEditTime: 2025-09-06 22:37:59
|
||||||
|
* @FilePath: /AI_SO_Test/AIEngineModule/example/test_example.cpp
|
||||||
|
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
*/
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <signal.h>
|
||||||
|
#include "deal.h"
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <thread>
|
||||||
|
#include "AI_Factory.h"
|
||||||
|
#include <chrono>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/statfs.h>
|
||||||
|
long getcurTime()
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
return ((long)tv.tv_sec) * 1000 + ((long)tv.tv_usec) / 1000;
|
||||||
|
}
|
||||||
|
void handler(int sig)
|
||||||
|
{
|
||||||
|
printf("Get handler sig");
|
||||||
|
std::string strcmd = "ps -ef | grep test_JBL_Check| awk '{print $2}' | xargs kill -9 ";
|
||||||
|
const char *cmd = strcmd.c_str();
|
||||||
|
printf("delete test_JBL_Check success");
|
||||||
|
if (-1 == system(cmd))
|
||||||
|
{
|
||||||
|
std::cout << "error" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete UnderCarriageCoreLogic::GetInstance();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int _sysmkdir(const std::string &dir)
|
||||||
|
{
|
||||||
|
int ret = mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
||||||
|
if (ret && errno == EEXIST)
|
||||||
|
{
|
||||||
|
//printf("dir[%s] already exist.\n", dir.c_str());
|
||||||
|
}
|
||||||
|
else if (ret)
|
||||||
|
{
|
||||||
|
printf("create dir[%s] error: %d %s\n", dir.c_str(), ret, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("create dir[%s] success.\n", dir.c_str());
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
std::string __getParentDir(const std::string &dir)
|
||||||
|
{
|
||||||
|
std::string pdir = dir;
|
||||||
|
if (pdir.length() < 1 || (pdir[0] != '/'))
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
while (pdir.length() > 1 && (pdir[pdir.length() - 1] == '/'))
|
||||||
|
pdir = pdir.substr(0, pdir.length() - 1);
|
||||||
|
|
||||||
|
pdir = pdir.substr(0, pdir.find_last_of('/'));
|
||||||
|
return pdir;
|
||||||
|
}
|
||||||
|
int _sysmkdirs(const std::string &dir)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
if (dir.empty())
|
||||||
|
return -1;
|
||||||
|
std::string pdir;
|
||||||
|
if ((ret = _sysmkdir(dir)) == -1)
|
||||||
|
{
|
||||||
|
pdir = __getParentDir(dir);
|
||||||
|
if ((ret = _sysmkdirs(pdir)) == 0)
|
||||||
|
{
|
||||||
|
ret = _sysmkdirs(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
|
||||||
|
// std::shared_ptr<AIFactory> AI_Factory;
|
||||||
|
// AI_Factory = AIFactory::GetInstance();
|
||||||
|
|
||||||
|
// GPU_Config gpu;
|
||||||
|
|
||||||
|
// AI_Factory->InitALLAIModle(gpu);
|
||||||
|
// std::shared_ptr<AIModel_Base> BOE_Edge_Detect = AI_Factory->BOE_Edge_Detect;
|
||||||
|
// BOE_Edge_Detect->input_0.print();
|
||||||
|
// BOE_Edge_Detect->input_1.print();
|
||||||
|
// BOE_Edge_Detect->output_0.print();
|
||||||
|
// BOE_Edge_Detect->output_1.print();
|
||||||
|
// BOE_Edge_Detect->output_2.print();
|
||||||
|
// std::shared_ptr<AIModel_Base> JBL_Detect = AI_Factory->JBL_Detect;
|
||||||
|
// JBL_Detect->input_0.print();
|
||||||
|
// JBL_Detect->input_1.print();
|
||||||
|
// JBL_Detect->output_0.print();
|
||||||
|
// JBL_Detect->output_1.print();
|
||||||
|
// JBL_Detect->output_2.print();
|
||||||
|
|
||||||
|
// cv::Mat temimg = cv::imread("../data/20250319_192154_Main_0_2_L255_Org.tif", 0);
|
||||||
|
// cv::Mat dealImg;
|
||||||
|
// printf("src img %d %d \n", temimg.cols, temimg.rows);
|
||||||
|
|
||||||
|
// cv::Size sz = cv::Size(BOE_Edge_Detect->input_0.width, BOE_Edge_Detect->input_0.height);
|
||||||
|
|
||||||
|
// cv::resize(temimg, dealImg, cv::Size(BOE_Edge_Detect->input_0.width, BOE_Edge_Detect->input_0.height));
|
||||||
|
// cv::Mat outimg;
|
||||||
|
|
||||||
|
// BOE_Edge_Detect->AIDet(dealImg, outimg);
|
||||||
|
// cv::imwrite("outimg.png", outimg);
|
||||||
|
|
||||||
|
// {
|
||||||
|
// long t1 = getcurTime();
|
||||||
|
// cv::Mat output;
|
||||||
|
// for (int i = 0; i < 1000; ++i)
|
||||||
|
// {
|
||||||
|
// cv::resize(temimg, dealImg, sz);
|
||||||
|
// BOE_Edge_Detect->AIDet(dealImg, outimg);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// long t2 = getcurTime();
|
||||||
|
|
||||||
|
// std::cout << "== run 1000 : " << t2 - t1 << " 毫秒" << std::endl;
|
||||||
|
// // cv::imwrite(name + "_output.jpg", output);
|
||||||
|
// // std::cout << "[" << name << "] done\n";
|
||||||
|
// };
|
||||||
|
// printf("========================\n");
|
||||||
|
// {
|
||||||
|
// long t1 = getcurTime();
|
||||||
|
|
||||||
|
// // Lambda 线程函数
|
||||||
|
// auto run_detection = [](std::shared_ptr<AIModel_Base> engine, const cv::Mat &input, const cv::Size sz, const std::string &name)
|
||||||
|
// {
|
||||||
|
// cv::Mat output;
|
||||||
|
// for (int i = 0; i < 250; ++i)
|
||||||
|
// {
|
||||||
|
// cv::Mat dealImg123;
|
||||||
|
// cv::resize(input, dealImg123, sz);
|
||||||
|
// // printf("%s ---- \n",name.c_str());
|
||||||
|
// engine->AIDet(dealImg123, output);
|
||||||
|
// // cv::imwrite(name + "_" + std::to_string(i) + "_output.jpg", output);
|
||||||
|
// }
|
||||||
|
// // cv::imwrite(name + "_output.jpg", output);
|
||||||
|
// // std::cout << "[" << name << "] done\n";
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // 启动两个线程
|
||||||
|
// std::thread thread1(run_detection, BOE_Edge_Detect, temimg, sz, "manager1");
|
||||||
|
// std::thread thread2(run_detection, BOE_Edge_Detect, temimg, sz, "manager2");
|
||||||
|
// std::thread thread3(run_detection, BOE_Edge_Detect, temimg, sz, "manager3");
|
||||||
|
// std::thread thread4(run_detection, BOE_Edge_Detect, temimg, sz, "manager4");
|
||||||
|
// // std::thread thread5(run_detection, BOE_Edge_Detect, dealImg, "manager1");
|
||||||
|
// // std::thread thread6(run_detection, BOE_Edge_Detect, dealImg, "manager2");
|
||||||
|
// // std::thread thread7(run_detection, BOE_Edge_Detect, dealImg, "manager3");
|
||||||
|
// // std::thread thread8(run_detection, BOE_Edge_Detect, dealImg, "manager4");
|
||||||
|
// // 等待线程结束
|
||||||
|
// thread1.join();
|
||||||
|
// thread2.join();
|
||||||
|
// thread3.join();
|
||||||
|
// thread4.join();
|
||||||
|
// // thread5.join();
|
||||||
|
// // thread6.join();
|
||||||
|
// // thread7.join();
|
||||||
|
// // thread8.join();
|
||||||
|
|
||||||
|
// long t2 = getcurTime();
|
||||||
|
// std::cout << "run 1000 = thread 4 * 250 耗时: " << t2 - t1 << " 毫秒" << std::endl;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// cv::Mat dealImg123;
|
||||||
|
// cv::resize(temimg, dealImg123, cv::Size(JBL_Detect->input_0.width, JBL_Detect->input_0.height));
|
||||||
|
// float fss = 0;
|
||||||
|
// int rclass = JBL_Detect->AIClass(dealImg123, &fss);
|
||||||
|
// printf("test ------------rclass %d score %f\n", rclass, fss);
|
||||||
|
// // printf("%d %d\n", manager_1->BOE_Edge_Detect->m_img_In_0.width, manager_1->BOE_Edge_Detect->m_img_In_0.height);
|
||||||
|
|
||||||
|
// // std::string strModelPath = "/home/aidlux/BOE/UseModel/Edge_Big.engine";
|
||||||
|
// // std::string strModelPath_jbl = "/home/aidlux/BOE/UseModel/class_14.engine";
|
||||||
|
// // std::shared_ptr<AIManagerBase> manager_1 = AIManagerBase::GetInstance(0);
|
||||||
|
// // std::shared_ptr<AIManagerBase> manager_2 = AIManagerBase::GetInstance(1);
|
||||||
|
// // std::shared_ptr<AIManagerBase> manager_3 = AIManagerBase::GetInstance(0);
|
||||||
|
|
||||||
|
// // std::cout << "manager_1 instance address: " << manager_1.get() << std::endl;
|
||||||
|
// // std::cout << "manager_2 instance address: " << manager_2.get() << std::endl;
|
||||||
|
// // std::cout << "manager_3 instance address: " << manager_3.get() << std::endl;
|
||||||
|
|
||||||
|
// // std::cout << "manager_1->BOE_Edge_Detect instance address: " << manager_1->BOE_Edge_Detect.get() << std::endl;
|
||||||
|
// // std::cout << "manager_2->BOE_Edge_Detect instance address: " << manager_2->BOE_Edge_Detect.get() << std::endl;
|
||||||
|
// // std::cout << "manager_3->BOE_Edge_Detect instance address: " << manager_3->BOE_Edge_Detect.get() << std::endl;
|
||||||
|
|
||||||
|
// // std::cout << "manager_1->JBL_Detect instance address: " << manager_1->JBL_Detect.get() << std::endl;
|
||||||
|
// // std::cout << "manager_2->JBL_Detect instance address: " << manager_2->JBL_Detect.get() << std::endl;
|
||||||
|
// // std::cout << "manager_3->JBL_Detect instance address: " << manager_3->JBL_Detect.get() << std::endl;
|
||||||
|
|
||||||
|
// // manager_1->BOE_Edge_Detect->Init(strModelPath);
|
||||||
|
// // manager_2->BOE_Edge_Detect->Init(strModelPath);
|
||||||
|
// // manager_3->BOE_Edge_Detect->Init(strModelPath);
|
||||||
|
|
||||||
|
// // manager_1->JBL_Detect->Init(strModelPath_jbl);
|
||||||
|
|
||||||
|
// // manager_2->JBL_Detect->Init(strModelPath_jbl);
|
||||||
|
|
||||||
|
// // manager_3->JBL_Detect->Init(strModelPath_jbl);
|
||||||
|
|
||||||
|
// // cv::Mat temimg = cv::imread("/home/aidlux/xwj/AI_SO_Test/data/img/20250319_192154_Main_0_2_L255_Org.tif", 0);
|
||||||
|
// // cv::Mat dealImg;
|
||||||
|
// // printf("%d %d\n", manager_1->BOE_Edge_Detect->m_img_In_0.width, manager_1->BOE_Edge_Detect->m_img_In_0.height);
|
||||||
|
|
||||||
|
// // if (manager_1->BOE_Edge_Detect)
|
||||||
|
// // {
|
||||||
|
// // cv::resize(temimg, dealImg, cv::Size(manager_1->BOE_Edge_Detect->m_img_In_0.width, manager_1->BOE_Edge_Detect->m_img_In_0.height));
|
||||||
|
// // cv::Mat outimg;
|
||||||
|
|
||||||
|
// // manager_1->BOE_Edge_Detect->AIDet(dealImg, outimg);
|
||||||
|
// // manager_2->BOE_Edge_Detect->AIDet(dealImg, outimg);
|
||||||
|
|
||||||
|
// // {
|
||||||
|
// // long t1 = getcurTime();
|
||||||
|
// // cv::Mat output;
|
||||||
|
// // for (int i = 0; i < 500; ++i)
|
||||||
|
// // {
|
||||||
|
// // manager_1->BOE_Edge_Detect->AIDet(dealImg, output);
|
||||||
|
// // }
|
||||||
|
// // for (int i = 0; i < 500; ++i)
|
||||||
|
// // {
|
||||||
|
// // manager_1->BOE_Edge_Detect->AIDet(dealImg, output);
|
||||||
|
// // }
|
||||||
|
// // long t2 = getcurTime();
|
||||||
|
|
||||||
|
// // std::cout << "run 1000 : " << t2 - t1 << " 毫秒" << std::endl;
|
||||||
|
// // // cv::imwrite(name + "_output.jpg", output);
|
||||||
|
// // // std::cout << "[" << name << "] done\n";
|
||||||
|
// // };
|
||||||
|
|
||||||
|
// // long t1 = getcurTime();
|
||||||
|
|
||||||
|
// // // Lambda 线程函数
|
||||||
|
// // auto run_detection = [](std::shared_ptr<AIEngineBase> engine, const cv::Mat &input, const std::string &name)
|
||||||
|
// // {
|
||||||
|
// // cv::Mat output;
|
||||||
|
// // for (int i = 0; i < 500; ++i)
|
||||||
|
// // {
|
||||||
|
// // engine->AIDet(input, output);
|
||||||
|
// // }
|
||||||
|
// // // cv::imwrite(name + "_output.jpg", output);
|
||||||
|
// // // std::cout << "[" << name << "] done\n";
|
||||||
|
// // };
|
||||||
|
|
||||||
|
// // // 启动两个线程
|
||||||
|
// // std::thread thread1(run_detection, manager_1->BOE_Edge_Detect, dealImg, "manager1");
|
||||||
|
// // std::thread thread2(run_detection, manager_1->BOE_Edge_Detect, dealImg, "manager3");
|
||||||
|
|
||||||
|
// // // 等待线程结束
|
||||||
|
// // thread1.join();
|
||||||
|
// // thread2.join();
|
||||||
|
|
||||||
|
// // // for (int i = 0; i < 1000; i++)
|
||||||
|
// // // {
|
||||||
|
// // // manager_1->BOE_Edge_Detect->AIDet(dealImg, outimg);
|
||||||
|
// // // // manager_3->BOE_Edge_Detect->AIDet(dealImg, outimg);
|
||||||
|
// // // }
|
||||||
|
|
||||||
|
// // long t2 = getcurTime();
|
||||||
|
|
||||||
|
// // std::cout << "run 1000 = thread 2 * 500 耗时: " << t2 - t1 << " 毫秒" << std::endl;
|
||||||
|
|
||||||
|
// // cv::imwrite("dealImg.jpg", dealImg);
|
||||||
|
// // cv::imwrite("outimg.jpg", outimg);
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // cv::Mat dealImg123;
|
||||||
|
// // cv::resize(temimg, dealImg123, cv::Size(manager_1->JBL_Detect->m_img_In_0.width, manager_1->JBL_Detect->m_img_In_0.height));
|
||||||
|
// // float fss = 0;
|
||||||
|
// // int rclass = manager_1->JBL_Detect->AIClass(dealImg, &fss);
|
||||||
|
// // long t11 = getcurTime();
|
||||||
|
// // rclass = manager_1->JBL_Detect->AIClass(dealImg, &fss);
|
||||||
|
// // long t12 = getcurTime();
|
||||||
|
// // printf("test ------------rclass %d score %f------- time %ld\n", rclass, fss, t12 - t11);
|
||||||
|
|
||||||
|
// // printf("test ------------------- \n");
|
||||||
|
// getchar();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,220 @@
|
|||||||
|
/*
|
||||||
|
* @Author: your name
|
||||||
|
* @Date: 2022-04-20 15:49:50
|
||||||
|
* @LastEditTime: 2025-09-06 22:23:08
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
* @FilePath: /ZCXD_MonitorPlatform/src/CoreLogicModule/include/CamDeal.h
|
||||||
|
*/
|
||||||
|
#ifndef AIModel_Impl_H_
|
||||||
|
#define AIModel_Impl_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <thread>
|
||||||
|
#include <mutex>
|
||||||
|
#include "NvInfer.h"
|
||||||
|
#include "cuda_runtime_api.h"
|
||||||
|
#include "AI_Factory.h"
|
||||||
|
#include "Engine.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
// 模型输入输出最大允许的 节点数
|
||||||
|
#define MAX_MODEL_NODE_NUM 5
|
||||||
|
|
||||||
|
class AIModel_Impl : public AIModel_Base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum AI_Buffer_Type
|
||||||
|
{
|
||||||
|
AI_Buffer_Type_INPUT,
|
||||||
|
AI_Buffer_Type_OUTPUT,
|
||||||
|
AI_Buffer_Type_Count,
|
||||||
|
};
|
||||||
|
// 模型节点参数 一个模型包括多个节点,输入 输出。
|
||||||
|
struct Node_Config : public AI_Image
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
int ucharsize;
|
||||||
|
int floatsize;
|
||||||
|
int datalength;
|
||||||
|
|
||||||
|
Node_Config()
|
||||||
|
{
|
||||||
|
channel = 0;
|
||||||
|
width = 0;
|
||||||
|
height = 0;
|
||||||
|
type = AI_Buffer_Type_INPUT;
|
||||||
|
name = "";
|
||||||
|
ucharsize = 0;
|
||||||
|
floatsize = 0;
|
||||||
|
datalength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy(Node_Config tem)
|
||||||
|
{
|
||||||
|
this->type = tem.type;
|
||||||
|
this->channel = tem.channel;
|
||||||
|
this->width = tem.width;
|
||||||
|
this->height = tem.height;
|
||||||
|
this->name = tem.name;
|
||||||
|
this->ucharsize = tem.ucharsize;
|
||||||
|
this->floatsize = tem.floatsize;
|
||||||
|
this->datalength = tem.datalength;
|
||||||
|
}
|
||||||
|
void CalDataSize()
|
||||||
|
{
|
||||||
|
ucharsize = channel * width * height * sizeof(unsigned char);
|
||||||
|
floatsize = channel * width * height * sizeof(float);
|
||||||
|
datalength = channel * width * height;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 流上的 节点参数信息。
|
||||||
|
struct Stream_Node_Config
|
||||||
|
{
|
||||||
|
Node_Config nodeConfig;
|
||||||
|
void *gpu_buffers;
|
||||||
|
void *gpu_ImgData; // uchar
|
||||||
|
|
||||||
|
float *cpu_floatData;
|
||||||
|
|
||||||
|
Stream_Node_Config()
|
||||||
|
{
|
||||||
|
|
||||||
|
gpu_buffers = NULL;
|
||||||
|
gpu_ImgData = NULL;
|
||||||
|
cpu_floatData = NULL;
|
||||||
|
}
|
||||||
|
~Stream_Node_Config()
|
||||||
|
{
|
||||||
|
if (gpu_buffers != NULL)
|
||||||
|
{
|
||||||
|
cudaFree(gpu_buffers);
|
||||||
|
gpu_buffers = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gpu_ImgData != NULL)
|
||||||
|
{
|
||||||
|
cudaFree(gpu_ImgData);
|
||||||
|
gpu_ImgData = NULL;
|
||||||
|
}
|
||||||
|
if (cpu_floatData != NULL)
|
||||||
|
{
|
||||||
|
delete[] cpu_floatData;
|
||||||
|
cpu_floatData = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// cuda上 一个流 包括的所有参数
|
||||||
|
struct Cuda_Stream_Config
|
||||||
|
{
|
||||||
|
int nstreamIdx;
|
||||||
|
cudaStream_t stream;
|
||||||
|
std::unique_ptr<nvinfer1::IExecutionContext> context;
|
||||||
|
std::shared_ptr<Stream_Node_Config> pstreamNode_input_0;
|
||||||
|
std::shared_ptr<Stream_Node_Config> pstreamNode_input_1;
|
||||||
|
std::shared_ptr<Stream_Node_Config> pstreamNode_output_0;
|
||||||
|
std::shared_ptr<Stream_Node_Config> pstreamNode_output_1;
|
||||||
|
std::shared_ptr<Stream_Node_Config> pstreamNode_output_2;
|
||||||
|
std::vector<std::shared_ptr<Stream_Node_Config>> streamConfigList;
|
||||||
|
Cuda_Stream_Config()
|
||||||
|
{
|
||||||
|
nstreamIdx = 0;
|
||||||
|
streamConfigList.clear();
|
||||||
|
pstreamNode_input_0 = nullptr;
|
||||||
|
pstreamNode_input_1 = nullptr;
|
||||||
|
pstreamNode_output_0 = nullptr;
|
||||||
|
pstreamNode_output_1 = nullptr;
|
||||||
|
pstreamNode_output_2 = nullptr;
|
||||||
|
}
|
||||||
|
~Cuda_Stream_Config()
|
||||||
|
{
|
||||||
|
|
||||||
|
cudaStreamDestroy(stream);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// GPU 上封装的参数信息
|
||||||
|
struct GPU_Engine
|
||||||
|
{
|
||||||
|
bool bsucc; // 是否初始化成功
|
||||||
|
int nGPUIdx; // GPU id号
|
||||||
|
std::shared_ptr<Engine> engine; // AI 模型 引擎
|
||||||
|
std::vector<std::shared_ptr<Cuda_Stream_Config>> cudaSteams; // 所有流
|
||||||
|
GPU_Engine()
|
||||||
|
{
|
||||||
|
nGPUIdx = 0;
|
||||||
|
cudaSteams.clear();
|
||||||
|
bsucc = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// AI 检测 顺序调用 gpu stream 流。
|
||||||
|
struct Det_GPU_Stram
|
||||||
|
{
|
||||||
|
std::mutex AI_mutex;
|
||||||
|
int nGPUIdx;
|
||||||
|
std::shared_ptr<Engine> engine; // AI 模型 引擎
|
||||||
|
|
||||||
|
std::shared_ptr<Cuda_Stream_Config> cuda_stream;
|
||||||
|
Det_GPU_Stram()
|
||||||
|
{
|
||||||
|
|
||||||
|
nGPUIdx = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
AIModel_Impl();
|
||||||
|
~AIModel_Impl();
|
||||||
|
|
||||||
|
// 初始化函数
|
||||||
|
int Init(AIModelRun_Config config);
|
||||||
|
int AIDet(const cv::Mat &inImg, cv::Mat &outimg);
|
||||||
|
int AIDet(const cv::Mat &inImg, cv::Mat &outimg0, cv::Mat &outimg1);
|
||||||
|
int AIClass(const cv::Mat &inImg, float *fmaxScore);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 运行参数检查
|
||||||
|
int ModelRunConfigCheck(AIModelRun_Config &runConfig);
|
||||||
|
// 每个gpu 载入模型
|
||||||
|
int LoadEngine(int ngpuIdx);
|
||||||
|
// 解析 模型的信息
|
||||||
|
int GetEngineInfo1(std::shared_ptr<GPU_Engine> &pgpuengine);
|
||||||
|
|
||||||
|
int AI_Det_In_1_Out_1(Node_Config *pConfig_in, Node_Config *pConfig_out, const unsigned char *p_indata_0, unsigned char *p_outdata_1);
|
||||||
|
|
||||||
|
int AI_Det_In_1_Out_1_class(unsigned char *p_indata_0, float *fmaxScore);
|
||||||
|
int F2softmaxId(float *data, int class_num, float *fmaxScore);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 调用相关函数
|
||||||
|
int GetStream(std::shared_ptr<Det_GPU_Stram> &pdetStream);
|
||||||
|
cv::Mat InitMat(int channel, int w, int h);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 模型参数
|
||||||
|
AIModelRun_Config m_modelRun_Config;
|
||||||
|
// 模型的输入输出list
|
||||||
|
std::vector<Node_Config> m_modelNodeList;
|
||||||
|
|
||||||
|
// 输入 输出节点
|
||||||
|
Node_Config *m_pNode_input_0;
|
||||||
|
Node_Config *m_pNode_input_1;
|
||||||
|
Node_Config *m_pNode_output_0;
|
||||||
|
Node_Config *m_pNode_output_1;
|
||||||
|
Node_Config *m_pNode_output_2;
|
||||||
|
// 引擎列表,一个 gpu 一个引擎
|
||||||
|
std::vector<std::shared_ptr<GPU_Engine>> m_GPU_Engine;
|
||||||
|
// 检测信息
|
||||||
|
std::vector<std::shared_ptr<Det_GPU_Stram>> m_DetGPUStream;
|
||||||
|
int m_nALLStreamNum;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 上次使用的GPU stream Idx;
|
||||||
|
std::atomic<int> m_nLast_GPUStreamIdx;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* @Author: your name
|
||||||
|
* @Date: 2022-04-20 15:49:50
|
||||||
|
* @LastEditTime: 2025-07-08 17:55:31
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
* @FilePath: /ZCXD_MonitorPlatform/src/CoreLogicModule/include/CamDeal.h
|
||||||
|
*/
|
||||||
|
#ifndef CUDA_Det_H_
|
||||||
|
#define CUDA_Det_H_
|
||||||
|
#include "cuda_runtime.h"
|
||||||
|
#include "cublas_v2.h"
|
||||||
|
#include "device_launch_parameters.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void Cuda_ucharToFloat_stream(const unsigned char* input, float* output, int size, cudaStream_t stream);
|
||||||
|
void Cuda_FloatTouchar_stream(const float* input, unsigned char* output, int size, cudaStream_t stream);
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,675 @@
|
|||||||
|
/*
|
||||||
|
* @Author: xiewenji 527774126@qq.com
|
||||||
|
* @Date: 2025-09-03 10:44:31
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @LastEditTime: 2025-09-06 22:29:55
|
||||||
|
* @FilePath: /AI_SO_Test/AIEngineModule/src/AIModel_Impl.cpp
|
||||||
|
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AIModel_Impl.h"
|
||||||
|
#include "CUDA_DataChange.cuh"
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
thread_local int g_last_cuda_device = -1;
|
||||||
|
|
||||||
|
bool EnsureCudaDevice(int gpuIdx)
|
||||||
|
{
|
||||||
|
if (g_last_cuda_device == gpuIdx)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
cudaError_t err = cudaSetDevice(gpuIdx);
|
||||||
|
if (err != cudaSuccess)
|
||||||
|
{
|
||||||
|
std::fprintf(stderr, "[AIEngine] cudaSetDevice(%d) failed: %s\n", gpuIdx, cudaGetErrorString(err));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_last_cuda_device = gpuIdx;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
AIModel_Impl::AIModel_Impl() : m_nLast_GPUStreamIdx(0)
|
||||||
|
{
|
||||||
|
m_bInitSuccess = false;
|
||||||
|
m_GPU_Engine.clear();
|
||||||
|
m_modelNodeList.clear();
|
||||||
|
m_pNode_input_0 = NULL;
|
||||||
|
m_pNode_input_1 = NULL;
|
||||||
|
m_pNode_output_0 = NULL;
|
||||||
|
m_pNode_output_1 = NULL;
|
||||||
|
m_pNode_output_2 = NULL;
|
||||||
|
m_DetGPUStream.clear();
|
||||||
|
m_nALLStreamNum = 0;
|
||||||
|
}
|
||||||
|
AIModel_Impl::~AIModel_Impl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
int AIModel_Impl::Init(AIModelRun_Config config)
|
||||||
|
{
|
||||||
|
m_modelRun_Config.Copy(config);
|
||||||
|
printf(">>> %s Init Start \n", m_modelRun_Config.strName.c_str());
|
||||||
|
|
||||||
|
if (m_bInitSuccess)
|
||||||
|
{
|
||||||
|
printf("strName %s Init Success %d ************ return \n", m_modelRun_Config.strName.c_str(), m_bInitSuccess);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int re = 0;
|
||||||
|
re = ModelRunConfigCheck(m_modelRun_Config);
|
||||||
|
if (re != 0)
|
||||||
|
{
|
||||||
|
printf("strName %s Init Error =%d run Config error \n", m_modelRun_Config.strName.c_str(), re);
|
||||||
|
return re;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不同显卡 单独 载入模型
|
||||||
|
if (m_modelRun_Config.gpuconfig.UseGPUList[0] >= 0)
|
||||||
|
{
|
||||||
|
re = LoadEngine(m_modelRun_Config.gpuconfig.UseGPUList[0]);
|
||||||
|
// 加载失败
|
||||||
|
if (re != 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_modelRun_Config.gpuconfig.UseGPUList[1] >= 0)
|
||||||
|
{
|
||||||
|
re = LoadEngine(m_modelRun_Config.gpuconfig.UseGPUList[1]);
|
||||||
|
// 加载失败
|
||||||
|
if (re != 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int nGPUNum = m_GPU_Engine.size();
|
||||||
|
// 模型载入失败
|
||||||
|
if (nGPUNum <= 0 || nGPUNum > 2)
|
||||||
|
{
|
||||||
|
printf(" %s model Init error \n", m_modelRun_Config.strName.c_str());
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
int m_nOutImgNum = 0;
|
||||||
|
for (int i = 0; i < m_modelNodeList.size(); i++)
|
||||||
|
{
|
||||||
|
if (m_modelNodeList.at(i).type == AI_Buffer_Type_INPUT)
|
||||||
|
{
|
||||||
|
if (m_pNode_input_0 == NULL)
|
||||||
|
{
|
||||||
|
m_pNode_input_0 = &m_modelNodeList.at(i);
|
||||||
|
input_0.copy(*m_pNode_input_0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_pNode_input_1 = &m_modelNodeList.at(i);
|
||||||
|
input_1.copy(*m_pNode_input_1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_nOutImgNum++;
|
||||||
|
if (m_pNode_output_0 == NULL)
|
||||||
|
{
|
||||||
|
m_pNode_output_0 = &m_modelNodeList.at(i);
|
||||||
|
output_0.copy(*m_pNode_output_0);
|
||||||
|
}
|
||||||
|
else if (m_pNode_output_1 == NULL)
|
||||||
|
{
|
||||||
|
m_pNode_output_1 = &m_modelNodeList.at(i);
|
||||||
|
output_1.copy(*m_pNode_output_1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_pNode_output_2 = &m_modelNodeList.at(i);
|
||||||
|
output_2.copy(*m_pNode_output_2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_pNode_input_0 == NULL || m_pNode_output_0 == NULL)
|
||||||
|
{
|
||||||
|
printf(" %s model Init error \n", m_modelRun_Config.strName.c_str());
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
int streamNum = m_GPU_Engine.at(0)->cudaSteams.size();
|
||||||
|
|
||||||
|
// 生产推理用的 参数信息
|
||||||
|
if (m_GPU_Engine.size() > 1)
|
||||||
|
{
|
||||||
|
if (m_GPU_Engine.at(0)->cudaSteams.size() != m_GPU_Engine.at(1)->cudaSteams.size())
|
||||||
|
{
|
||||||
|
printf(" %s model Init error \n", m_modelRun_Config.strName.c_str());
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (streamNum <= 0)
|
||||||
|
{
|
||||||
|
printf(" %s model Init streamNum error \n", m_modelRun_Config.strName.c_str());
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示初始化信息
|
||||||
|
if (true)
|
||||||
|
{
|
||||||
|
printf("Model Name :%s GUP engine Num %ld\n", m_modelRun_Config.strName.c_str(), m_GPU_Engine.size());
|
||||||
|
|
||||||
|
for (const auto &ge : m_GPU_Engine)
|
||||||
|
{
|
||||||
|
printf(" gpu %d status %d strem Num %ld \n", ge->nGPUIdx, ge->bsucc, ge->cudaSteams.size());
|
||||||
|
|
||||||
|
for (const auto &psteam : ge->cudaSteams)
|
||||||
|
{
|
||||||
|
printf(" steam %d \n", psteam->nstreamIdx);
|
||||||
|
for (const auto &pcon : psteam->streamConfigList)
|
||||||
|
{
|
||||||
|
printf(" type %d [chw] %d %d %d input %p output %p\n",
|
||||||
|
pcon->nodeConfig.type, pcon->nodeConfig.channel, pcon->nodeConfig.height, pcon->nodeConfig.width,
|
||||||
|
pcon->gpu_buffers, pcon->gpu_ImgData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 把所有gup 的所有stream 都放到一起,方便调用。
|
||||||
|
m_DetGPUStream.reserve(nGPUNum * streamNum);
|
||||||
|
for (int i = 0; i < streamNum; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
for (int igpu = 0; igpu < nGPUNum; igpu++)
|
||||||
|
{
|
||||||
|
std::shared_ptr<Det_GPU_Stram> temDetStream = std::make_shared<Det_GPU_Stram>();
|
||||||
|
temDetStream->nGPUIdx = m_GPU_Engine.at(igpu)->nGPUIdx;
|
||||||
|
temDetStream->engine = m_GPU_Engine.at(igpu)->engine;
|
||||||
|
temDetStream->cuda_stream = m_GPU_Engine.at(igpu)->cudaSteams.at(i);
|
||||||
|
m_DetGPUStream.push_back(temDetStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_nALLStreamNum = m_DetGPUStream.size();
|
||||||
|
printf("========********* Model Name :%s GUP engine Num %ld **************=============\n", m_modelRun_Config.strName.c_str(), m_GPU_Engine.size());
|
||||||
|
for (const auto steam : m_DetGPUStream)
|
||||||
|
{
|
||||||
|
printf(">>> gpu %d stream %d \n",
|
||||||
|
steam->nGPUIdx, steam->cuda_stream->nstreamIdx);
|
||||||
|
}
|
||||||
|
if (config.IsClass)
|
||||||
|
{
|
||||||
|
cv::Mat temimg = cv::Mat::zeros(input_0.height, input_0.width, CV_8UC1);
|
||||||
|
float fs = 0;
|
||||||
|
for (int ig = 0; ig < nGPUNum * 2; ig++)
|
||||||
|
{
|
||||||
|
AIClass(temimg, &fs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_nOutImgNum == 1)
|
||||||
|
{
|
||||||
|
cv::Mat temimg = cv::Mat::zeros(input_0.height, input_0.width, CV_8UC1);
|
||||||
|
cv::Mat outimg = cv::Mat::zeros(output_0.height, output_0.width, CV_8UC1);
|
||||||
|
for (int ig = 0; ig < nGPUNum * 2; ig++)
|
||||||
|
{
|
||||||
|
AIDet(temimg, outimg);
|
||||||
|
printf(">>>test AIDet ====1================= \n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_nOutImgNum == 2)
|
||||||
|
{
|
||||||
|
cv::Mat temimg = cv::Mat::zeros(input_0.height, input_0.width, CV_8UC1);
|
||||||
|
cv::Mat outimg = cv::Mat::zeros(output_0.height, output_0.width, CV_8UC1);
|
||||||
|
cv::Mat outimg1 = cv::Mat::zeros(output_1.height, output_1.width, CV_8UC1);
|
||||||
|
for (int ig = 0; ig < nGPUNum * 2; ig++)
|
||||||
|
{
|
||||||
|
AIDet(temimg, outimg, outimg1);
|
||||||
|
printf(">>>test AIDet =====2================ \n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_bInitSuccess = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
cv::Mat AIModel_Impl::InitMat(int channel, int w, int h)
|
||||||
|
{
|
||||||
|
if (w <= 0 || h <= 0 || channel <= 0 || channel > 3)
|
||||||
|
{
|
||||||
|
return cv::Mat();
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Mat dst;
|
||||||
|
if (channel == 1)
|
||||||
|
{
|
||||||
|
dst = cv::Mat(h, w, CV_8UC1, cv::Scalar(0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dst = cv::Mat(h, w, CV_8UC3, cv::Scalar(0, 0, 0));
|
||||||
|
}
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
int AIModel_Impl::AIDet(const cv::Mat &inImg, cv::Mat &outimg)
|
||||||
|
{
|
||||||
|
|
||||||
|
// 1、准备数据
|
||||||
|
if (m_pNode_input_0 == NULL || m_pNode_output_0 == NULL)
|
||||||
|
{
|
||||||
|
printf("AIDet: Node Config INput output Node error \n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// std::this_thread::sleep_for(std::chrono::milliseconds(2)); // Sleep for 100 milliseconds
|
||||||
|
uchar *p_indata_0 = (uchar *)inImg.data;
|
||||||
|
int outType = m_pNode_output_0->channel == 1 ? CV_8UC1 : CV_8UC3;
|
||||||
|
if (outimg.empty() || outimg.rows != m_pNode_output_0->height ||
|
||||||
|
outimg.cols != m_pNode_output_0->width || outimg.type() != outType)
|
||||||
|
{
|
||||||
|
outimg.create(m_pNode_output_0->height, m_pNode_output_0->width, outType);
|
||||||
|
}
|
||||||
|
uchar *p_outdata_1 = (uchar *)outimg.data;
|
||||||
|
if (!m_bInitSuccess)
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
AI_Det_In_1_Out_1(m_pNode_input_0, m_pNode_output_0, p_indata_0, p_outdata_1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AIModel_Impl::AIDet(const cv::Mat &inImg, cv::Mat &outimg0, cv::Mat &outimg1)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AIModel_Impl::AIClass(const cv::Mat &inImg, float *fmaxScore)
|
||||||
|
{
|
||||||
|
// 1、准备数据
|
||||||
|
if (m_pNode_input_0 == NULL || m_pNode_output_0 == NULL)
|
||||||
|
{
|
||||||
|
printf("AIDet: Node Config INput output Node error \n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!m_bInitSuccess)
|
||||||
|
{
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
uchar *p_indata_0 = (uchar *)inImg.data;
|
||||||
|
|
||||||
|
int class_dix = 0;
|
||||||
|
class_dix = AI_Det_In_1_Out_1_class(p_indata_0, fmaxScore);
|
||||||
|
|
||||||
|
return class_dix;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测模型的运行参数是否合法,是否正常
|
||||||
|
int AIModel_Impl::ModelRunConfigCheck(AIModelRun_Config &runConfig)
|
||||||
|
{
|
||||||
|
// GPU 数量判断
|
||||||
|
if (runConfig.gpuconfig.GetNum() == 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (runConfig.strPath == "")
|
||||||
|
{
|
||||||
|
printf(" %s model path is error \n", runConfig.strName.c_str());
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if (runConfig.Stream_num <= 0)
|
||||||
|
{
|
||||||
|
runConfig.Stream_num = 1;
|
||||||
|
}
|
||||||
|
if (runConfig.Stream_num > 4)
|
||||||
|
{
|
||||||
|
runConfig.Stream_num = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 载入模型。。。。
|
||||||
|
int AIModel_Impl::LoadEngine(int ngpuIdx)
|
||||||
|
{
|
||||||
|
std::shared_ptr<GPU_Engine> gpuEngine = std::make_shared<GPU_Engine>();
|
||||||
|
gpuEngine->engine = std::make_shared<Engine>(ngpuIdx);
|
||||||
|
gpuEngine->nGPUIdx = ngpuIdx;
|
||||||
|
if (!gpuEngine->engine)
|
||||||
|
{
|
||||||
|
printf("Engine Create error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// 1、加载模型
|
||||||
|
bool reload = gpuEngine->engine->loadFromFile(m_modelRun_Config.strPath);
|
||||||
|
|
||||||
|
if (!reload)
|
||||||
|
{
|
||||||
|
printf("GPU %d Load error %s\n", ngpuIdx, m_modelRun_Config.strPath.c_str());
|
||||||
|
printf("Load model error\n");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
printf("%s GPU %d Load succ %s\n", m_modelRun_Config.strName.c_str(), ngpuIdx, m_modelRun_Config.strPath.c_str());
|
||||||
|
|
||||||
|
// 2、 解析 egengine的 相关信息
|
||||||
|
int re = GetEngineInfo1(gpuEngine);
|
||||||
|
if (re != 0)
|
||||||
|
{
|
||||||
|
return re;
|
||||||
|
}
|
||||||
|
// 没有输入输出 节点。
|
||||||
|
if (m_modelNodeList.size() <= 0 || m_modelNodeList.size() > MAX_MODEL_NODE_NUM)
|
||||||
|
{
|
||||||
|
printf("Load model input output error\n");
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
cudaSetDevice(ngpuIdx);
|
||||||
|
// 3、 申请显存
|
||||||
|
for (int i = 0; i < m_modelRun_Config.Stream_num; i++)
|
||||||
|
{
|
||||||
|
std::shared_ptr<Cuda_Stream_Config> cudasteam = std::make_shared<Cuda_Stream_Config>();
|
||||||
|
cudasteam->nstreamIdx = i;
|
||||||
|
|
||||||
|
if (cudaStreamCreateWithFlags(&cudasteam->stream, cudaStreamNonBlocking) != cudaSuccess)
|
||||||
|
{
|
||||||
|
printf("Failed to create CUDA stream\n");
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
cudasteam->context = std::unique_ptr<nvinfer1::IExecutionContext>(
|
||||||
|
gpuEngine->engine->engine_->createExecutionContext());
|
||||||
|
// printf("----- stream %d \n", i);
|
||||||
|
// 初始化 数据 内存
|
||||||
|
for (int j = 0; j < m_modelNodeList.size(); j++)
|
||||||
|
{
|
||||||
|
std::shared_ptr<Stream_Node_Config> steamNodeconfig = std::make_shared<Stream_Node_Config>();
|
||||||
|
steamNodeconfig->nodeConfig.copy(m_modelNodeList.at(j));
|
||||||
|
|
||||||
|
cudaMalloc(&steamNodeconfig->gpu_buffers, steamNodeconfig->nodeConfig.floatsize);
|
||||||
|
cudaMalloc(&steamNodeconfig->gpu_ImgData, steamNodeconfig->nodeConfig.ucharsize);
|
||||||
|
// 分类 的模型
|
||||||
|
if (m_modelRun_Config.IsClass)
|
||||||
|
{
|
||||||
|
if (steamNodeconfig->cpu_floatData)
|
||||||
|
{
|
||||||
|
delete[] steamNodeconfig->cpu_floatData;
|
||||||
|
steamNodeconfig->cpu_floatData = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
steamNodeconfig->cpu_floatData = new float[steamNodeconfig->nodeConfig.datalength];
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("-----******GPU %d stream %d cuda malloc %d inOrout %d [chw] %d*%d*%d \n",
|
||||||
|
ngpuIdx, i, j, steamNodeconfig->nodeConfig.type, steamNodeconfig->nodeConfig.channel,
|
||||||
|
steamNodeconfig->nodeConfig.height, steamNodeconfig->nodeConfig.width);
|
||||||
|
|
||||||
|
if (m_modelNodeList.at(j).type == AI_Buffer_Type_INPUT)
|
||||||
|
{
|
||||||
|
if (cudasteam->pstreamNode_input_0 == nullptr)
|
||||||
|
{
|
||||||
|
cudasteam->pstreamNode_input_0 = steamNodeconfig;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cudasteam->pstreamNode_input_1 = steamNodeconfig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (cudasteam->pstreamNode_output_0 == nullptr)
|
||||||
|
{
|
||||||
|
cudasteam->pstreamNode_output_0 = steamNodeconfig;
|
||||||
|
}
|
||||||
|
else if (cudasteam->pstreamNode_output_1 == nullptr)
|
||||||
|
{
|
||||||
|
cudasteam->pstreamNode_output_1 = steamNodeconfig;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cudasteam->pstreamNode_output_2 = steamNodeconfig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cudasteam->streamConfigList.push_back(steamNodeconfig);
|
||||||
|
}
|
||||||
|
gpuEngine->cudaSteams.push_back(cudasteam);
|
||||||
|
}
|
||||||
|
gpuEngine->bsucc = true;
|
||||||
|
|
||||||
|
m_GPU_Engine.push_back(gpuEngine);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AIModel_Impl::GetEngineInfo1(std::shared_ptr<GPU_Engine> &pgpuengine)
|
||||||
|
{
|
||||||
|
int nInputNum = pgpuengine->engine->getNbBindings();
|
||||||
|
|
||||||
|
m_modelNodeList.erase(m_modelNodeList.begin(), m_modelNodeList.end());
|
||||||
|
m_modelNodeList.clear();
|
||||||
|
|
||||||
|
for (int i = 0; i < nInputNum; i++)
|
||||||
|
{
|
||||||
|
Node_Config node_config;
|
||||||
|
|
||||||
|
std::string name = pgpuengine->engine->getBindingName(i);
|
||||||
|
node_config.name = name;
|
||||||
|
Dims dims = pgpuengine->engine->getBindingDims(i);
|
||||||
|
|
||||||
|
if (pgpuengine->engine->bindingIsInput(i))
|
||||||
|
{
|
||||||
|
std::cout << "Input: " << name << "\n";
|
||||||
|
node_config.type = AI_Buffer_Type_INPUT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Output: " << name << "\n";
|
||||||
|
node_config.type = AI_Buffer_Type_OUTPUT;
|
||||||
|
}
|
||||||
|
std::cout << "dims.nbDims: " << dims.nbDims << "\n";
|
||||||
|
if (dims.nbDims == 4)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (m_modelRun_Config.inputType)
|
||||||
|
{
|
||||||
|
case Input_CHW:
|
||||||
|
node_config.channel = dims.d[1];
|
||||||
|
node_config.height = dims.d[2];
|
||||||
|
node_config.width = dims.d[3];
|
||||||
|
break;
|
||||||
|
case Input_HWC:
|
||||||
|
|
||||||
|
node_config.height = dims.d[1];
|
||||||
|
node_config.width = dims.d[2];
|
||||||
|
node_config.channel = dims.d[3];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
node_config.channel = dims.d[1];
|
||||||
|
node_config.height = dims.d[2];
|
||||||
|
node_config.width = dims.d[3];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dims.nbDims == 3)
|
||||||
|
{
|
||||||
|
switch (m_modelRun_Config.inputType)
|
||||||
|
{
|
||||||
|
case Input_CHW:
|
||||||
|
node_config.channel = dims.d[0];
|
||||||
|
node_config.height = dims.d[1];
|
||||||
|
node_config.width = dims.d[2];
|
||||||
|
break;
|
||||||
|
case Input_HWC:
|
||||||
|
|
||||||
|
node_config.height = dims.d[0];
|
||||||
|
node_config.width = dims.d[1];
|
||||||
|
node_config.channel = dims.d[2];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
node_config.channel = dims.d[0];
|
||||||
|
node_config.height = dims.d[1];
|
||||||
|
node_config.width = dims.d[2];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (dims.d[0] == 1 || dims.d[2] != 1)
|
||||||
|
{
|
||||||
|
node_config.channel = dims.d[0];
|
||||||
|
node_config.height = dims.d[1];
|
||||||
|
node_config.width = dims.d[2];
|
||||||
|
}
|
||||||
|
if (dims.d[0] != 1 || dims.d[2] == 1)
|
||||||
|
{
|
||||||
|
node_config.channel = dims.d[2];
|
||||||
|
node_config.height = dims.d[0];
|
||||||
|
node_config.width = dims.d[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dims.nbDims == 2)
|
||||||
|
{
|
||||||
|
node_config.channel = 1;
|
||||||
|
node_config.height = dims.d[0];
|
||||||
|
node_config.width = dims.d[1];
|
||||||
|
}
|
||||||
|
else if (dims.nbDims == 1)
|
||||||
|
{
|
||||||
|
node_config.channel = 1;
|
||||||
|
node_config.height = dims.d[0];
|
||||||
|
node_config.width = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("engine C H W is error\n");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
node_config.CalDataSize();
|
||||||
|
|
||||||
|
m_modelNodeList.push_back(node_config);
|
||||||
|
printf("dim: ");
|
||||||
|
for (int di = 0; di < dims.nbDims; di++)
|
||||||
|
{
|
||||||
|
printf(" %ld ", dims.d[di]);
|
||||||
|
}
|
||||||
|
printf(" \n");
|
||||||
|
printf("C H W [%d %d %d]\n", node_config.channel, node_config.height, node_config.width);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AIModel_Impl::AI_Det_In_1_Out_1(Node_Config *pConfig_in, Node_Config *pConfig_out, const unsigned char *p_indata_0, unsigned char *p_outdata_1)
|
||||||
|
{
|
||||||
|
// printf("=== s1 ");
|
||||||
|
std::shared_ptr<Det_GPU_Stram> pdetStream;
|
||||||
|
if (GetStream(pdetStream) != 0 || !pdetStream)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// printf("=== s2 ");
|
||||||
|
std::lock_guard<std::mutex> lock(pdetStream->AI_mutex);
|
||||||
|
// printf(" ss g %d s %d -- ", pdetStream->nGPUIdx, pdetStream->cuda_stream->nstreamIdx);
|
||||||
|
// // 设置 显卡ID
|
||||||
|
if (!EnsureCudaDevice(pdetStream->nGPUIdx))
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cudaMemcpyAsync(pdetStream->cuda_stream->pstreamNode_input_0->gpu_ImgData,
|
||||||
|
p_indata_0, pConfig_in->ucharsize, cudaMemcpyHostToDevice, pdetStream->cuda_stream->stream);
|
||||||
|
// // // 在显存中 图片数据从 uchar 转到 float
|
||||||
|
Cuda_ucharToFloat_stream((unsigned char *)pdetStream->cuda_stream->pstreamNode_input_0->gpu_ImgData,
|
||||||
|
(float *)pdetStream->cuda_stream->pstreamNode_input_0->gpu_buffers, pConfig_in->datalength, pdetStream->cuda_stream->stream);
|
||||||
|
|
||||||
|
pdetStream->cuda_stream->context->setTensorAddress(pConfig_in->name.c_str(), pdetStream->cuda_stream->pstreamNode_input_0->gpu_buffers);
|
||||||
|
pdetStream->cuda_stream->context->setTensorAddress(pConfig_out->name.c_str(), pdetStream->cuda_stream->pstreamNode_output_0->gpu_buffers);
|
||||||
|
|
||||||
|
pdetStream->cuda_stream->context->enqueueV3(pdetStream->cuda_stream->stream);
|
||||||
|
|
||||||
|
Cuda_FloatTouchar_stream((float *)pdetStream->cuda_stream->pstreamNode_output_0->gpu_buffers,
|
||||||
|
(unsigned char *)pdetStream->cuda_stream->pstreamNode_output_0->gpu_ImgData, pConfig_out->datalength, pdetStream->cuda_stream->stream);
|
||||||
|
cudaMemcpyAsync(p_outdata_1, pdetStream->cuda_stream->pstreamNode_output_0->gpu_ImgData,
|
||||||
|
pConfig_out->ucharsize, cudaMemcpyDeviceToHost, pdetStream->cuda_stream->stream);
|
||||||
|
cudaStreamSynchronize(pdetStream->cuda_stream->stream);
|
||||||
|
// printf("**ee g %d s %d ** \n", pdetStream->nGPUIdx, pdetStream->cuda_stream->nstreamIdx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AIModel_Impl::GetStream(std::shared_ptr<Det_GPU_Stram> &pdetStream)
|
||||||
|
{
|
||||||
|
if (m_nALLStreamNum <= 0)
|
||||||
|
{
|
||||||
|
pdetStream = nullptr;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sidx = m_nLast_GPUStreamIdx.fetch_add(1, std::memory_order_relaxed) % m_nALLStreamNum;
|
||||||
|
pdetStream = m_DetGPUStream.at(sidx);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int AIModel_Impl::AI_Det_In_1_Out_1_class(unsigned char *p_indata_0, float *fmaxScore)
|
||||||
|
{
|
||||||
|
std::shared_ptr<Det_GPU_Stram> pdetStream;
|
||||||
|
if (GetStream(pdetStream) != 0 || !pdetStream)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// printf("=== s2 ");
|
||||||
|
std::lock_guard<std::mutex> lock(pdetStream->AI_mutex);
|
||||||
|
// printf(" ss g %d s %d -- ", pdetStream->nGPUIdx, pdetStream->cuda_stream->nstreamIdx);
|
||||||
|
// // 设置 显卡ID
|
||||||
|
std::shared_ptr<Stream_Node_Config> p_input_0 = pdetStream->cuda_stream->pstreamNode_input_0;
|
||||||
|
std::shared_ptr<Stream_Node_Config> p_output_0 = pdetStream->cuda_stream->pstreamNode_output_0;
|
||||||
|
if (!EnsureCudaDevice(pdetStream->nGPUIdx))
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cudaMemcpyAsync(p_input_0->gpu_ImgData, p_indata_0,
|
||||||
|
p_input_0->nodeConfig.ucharsize, cudaMemcpyHostToDevice, pdetStream->cuda_stream->stream);
|
||||||
|
// // // 在显存中 图片数据从 uchar 转到 float
|
||||||
|
Cuda_ucharToFloat_stream((unsigned char *)p_input_0->gpu_ImgData,
|
||||||
|
(float *)p_input_0->gpu_buffers, p_input_0->nodeConfig.datalength, pdetStream->cuda_stream->stream);
|
||||||
|
|
||||||
|
pdetStream->cuda_stream->context->setTensorAddress(p_input_0->nodeConfig.name.c_str(), p_input_0->gpu_buffers);
|
||||||
|
pdetStream->cuda_stream->context->setTensorAddress(p_output_0->nodeConfig.name.c_str(), p_output_0->gpu_buffers);
|
||||||
|
|
||||||
|
pdetStream->cuda_stream->context->enqueueV3(pdetStream->cuda_stream->stream);
|
||||||
|
|
||||||
|
cudaMemcpyAsync(p_output_0->cpu_floatData, p_output_0->gpu_buffers,
|
||||||
|
p_output_0->nodeConfig.floatsize, cudaMemcpyDeviceToHost, pdetStream->cuda_stream->stream);
|
||||||
|
cudaStreamSynchronize(pdetStream->cuda_stream->stream);
|
||||||
|
|
||||||
|
int label = F2softmaxId(p_output_0->cpu_floatData, p_output_0->nodeConfig.datalength, fmaxScore);
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
int AIModel_Impl::F2softmaxId(float *data, int class_num, float *fmaxScore)
|
||||||
|
{
|
||||||
|
int cls_num = class_num;
|
||||||
|
float total = 0;
|
||||||
|
for (int i = 0; i < cls_num; i++)
|
||||||
|
{
|
||||||
|
// std::cout<<"data["<<i<<"]="<<data[i]<<std::endl;
|
||||||
|
total += exp(data[i]);
|
||||||
|
}
|
||||||
|
// std::cout<<"total="<<total<<std::endl;
|
||||||
|
// std::vector<float> output;//这样才可以用push_back-但相比于=更耗时
|
||||||
|
std::vector<float> output(cls_num);
|
||||||
|
for (int i = 0; i < output.size(); i++)
|
||||||
|
{
|
||||||
|
float outi = (float)exp(data[i]) / (float)total;
|
||||||
|
output[i] = outi;
|
||||||
|
// output.push_back(outi);
|
||||||
|
// std::cout<<"output["<<i<<"]="<<output[i]<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int max_id = 0;
|
||||||
|
float max_score = 0;
|
||||||
|
for (int i = 0; i < output.size(); i++)
|
||||||
|
{
|
||||||
|
// std::cout << "output[" << i << "]=" << output[i] << std::endl;
|
||||||
|
if (output[i] > max_score)
|
||||||
|
{
|
||||||
|
max_id = i;
|
||||||
|
max_score = output[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*fmaxScore = max_score;
|
||||||
|
// std::cout << "F2softmaxId()----------------------------------max_score=" << max_score << std::endl; // 1023dyy
|
||||||
|
// std::cout << "F2softmaxId()----------------------------------max_id=" << max_id << std::endl; // 1023dyy
|
||||||
|
return max_id;
|
||||||
|
}
|
||||||
@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* @Author: xiewenji 527774126@qq.com
|
||||||
|
* @Date: 2025-07-11 11:35:40
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @LastEditTime: 2025-09-15 10:29:44
|
||||||
|
* @FilePath: /BOE_Bounding/AIEngineModule/src/AIMulThreadRunBase.cpp
|
||||||
|
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
*/
|
||||||
|
#include "AI_Factory.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <chrono>
|
||||||
|
#include <sys/time.h>
|
||||||
|
long getcurTime4444()
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
return ((long)tv.tv_sec) * 1000 + ((long)tv.tv_usec) / 1000;
|
||||||
|
}
|
||||||
|
AIMulThreadRunBase::AIMulThreadRunBase() : m_running_(false), m_processing_count_(0) {}
|
||||||
|
|
||||||
|
AIMulThreadRunBase::~AIMulThreadRunBase()
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIMulThreadRunBase::Start(int num_threads)
|
||||||
|
{
|
||||||
|
if (m_running_)
|
||||||
|
return;
|
||||||
|
m_running_ = true;
|
||||||
|
m_detnum = 0;
|
||||||
|
// num_threads = 2;
|
||||||
|
// 仅启动1个线程
|
||||||
|
for (int i = 0; i < num_threads; ++i)
|
||||||
|
{
|
||||||
|
m_workers_.emplace_back(&AIMulThreadRunBase::ThreadLoop, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIMulThreadRunBase::Stop()
|
||||||
|
{
|
||||||
|
m_running_ = false;
|
||||||
|
m_task_cv_.notify_all();
|
||||||
|
for (auto &t : m_workers_)
|
||||||
|
{
|
||||||
|
if (t.joinable())
|
||||||
|
t.join();
|
||||||
|
}
|
||||||
|
m_workers_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIMulThreadRunBase::SubmitTask(std::shared_ptr<AITask> task)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_task_mutex_);
|
||||||
|
m_tasks_.push(task);
|
||||||
|
}
|
||||||
|
m_processing_count_++;
|
||||||
|
m_task_cv_.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AIMulThreadRunBase::PopResult(std::shared_ptr<AITask> &result)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_result_mutex_);
|
||||||
|
if (m_results_.empty())
|
||||||
|
return false;
|
||||||
|
result = m_results_.front();
|
||||||
|
m_results_.pop();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIMulThreadRunBase::ThreadLoop()
|
||||||
|
{
|
||||||
|
while (m_running_)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::shared_ptr<AITask> task;
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(m_task_mutex_);
|
||||||
|
m_task_cv_.wait(lock, [this]()
|
||||||
|
{ return !m_tasks_.empty() || !m_running_; });
|
||||||
|
|
||||||
|
if (!m_running_ && m_tasks_.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
task = std::move(m_tasks_.front());
|
||||||
|
m_tasks_.pop();
|
||||||
|
}
|
||||||
|
if (task->bclass)
|
||||||
|
{
|
||||||
|
// 执行推理
|
||||||
|
if (task->engine)
|
||||||
|
{
|
||||||
|
// std::lock_guard<std::mutex> lock(m_AI_mutex_);
|
||||||
|
// long t1 = getcurTime4444();
|
||||||
|
task->cls_label = task->engine->AIClass(task->input, &task->cls_score);
|
||||||
|
// long t2 = getcurTime4444();
|
||||||
|
// printf("det time %d m_tasks_ size %ld\n", t2 - t1,m_tasks_.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 执行推理
|
||||||
|
if (task->engine && task->output)
|
||||||
|
{
|
||||||
|
// std::lock_guard<std::mutex> lock(m_AI_mutex_);
|
||||||
|
// long t1 = getcurTime4444();
|
||||||
|
task->engine->AIDet(task->input, *task->output);
|
||||||
|
// long t2 = getcurTime4444();
|
||||||
|
// printf("det time %d m_tasks_ size %ld\n", t2 - t1,m_tasks_.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_result_mutex_);
|
||||||
|
m_results_.push(task);
|
||||||
|
}
|
||||||
|
// m_detnum++;
|
||||||
|
m_processing_count_--;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,237 @@
|
|||||||
|
/*
|
||||||
|
* @Author: xiewenji 527774126@qq.com
|
||||||
|
* @Date: 2025-09-03 10:33:48
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @LastEditTime: 2025-09-25 15:42:47
|
||||||
|
* @FilePath: /AI_SO_Test/AIEngineModule/src/AI_Factory.cpp
|
||||||
|
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
*/
|
||||||
|
#include "AI_Factory.h"
|
||||||
|
|
||||||
|
#include "AIModel_Impl.h"
|
||||||
|
|
||||||
|
std::shared_ptr<AIModel_Base> AIModel_Base::GetInstance()
|
||||||
|
{
|
||||||
|
std::shared_ptr<AIModel_Base> instance = std::make_shared<AIModel_Impl>();
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
AIFactory::AIFactory()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AIFactory::~AIFactory()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
std::shared_ptr<AIFactory> AIFactory::GetInstance()
|
||||||
|
{
|
||||||
|
static std::shared_ptr<AIFactory> instance = std::make_shared<AIFactory>();
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AIFactory::InitALLAIModle(GPU_Config gupconfig)
|
||||||
|
{
|
||||||
|
if (gupconfig.GetNum() == 0)
|
||||||
|
{
|
||||||
|
printf("GPU Num Error \n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 主检测
|
||||||
|
if (!AI_defect_NF)
|
||||||
|
{
|
||||||
|
AI_defect_NF = AIModel_Base::GetInstance();
|
||||||
|
AIModel_Base::AIModelRun_Config boe_config;
|
||||||
|
boe_config.gpuconfig.copy(gupconfig);
|
||||||
|
boe_config.strPath = "/home/aidlux/BOE/UseModel_Cell_ET/defect.engine";
|
||||||
|
boe_config.inputType = AIModel_Base::Input_CHW;
|
||||||
|
boe_config.strName = "Base_detect";
|
||||||
|
boe_config.Stream_num = 2;
|
||||||
|
AI_defect_NF->Init(boe_config);
|
||||||
|
}
|
||||||
|
// 黑白画面模型
|
||||||
|
if (!AI_defect_Type2)
|
||||||
|
{
|
||||||
|
AI_defect_Type2 = AIModel_Base::GetInstance();
|
||||||
|
AIModel_Base::AIModelRun_Config boe_config;
|
||||||
|
boe_config.gpuconfig.copy(gupconfig);
|
||||||
|
boe_config.strPath = "/home/aidlux/BOE/UseModel_Cell_ET/defect_WTB.engine";
|
||||||
|
boe_config.inputType = AIModel_Base::Input_CHW;
|
||||||
|
boe_config.strName = "WTB_detect";
|
||||||
|
boe_config.Stream_num = 2;
|
||||||
|
AI_defect_Type2->Init(boe_config);
|
||||||
|
}
|
||||||
|
// UP画面模型
|
||||||
|
if (!AI_defect_UP)
|
||||||
|
{
|
||||||
|
AI_defect_UP = AIModel_Base::GetInstance();
|
||||||
|
AIModel_Base::AIModelRun_Config boe_config;
|
||||||
|
boe_config.gpuconfig.copy(gupconfig);
|
||||||
|
boe_config.strPath = "/home/aidlux/BOE/UseModel_Cell_ET/defect_UP.engine";
|
||||||
|
boe_config.inputType = AIModel_Base::Input_CHW;
|
||||||
|
boe_config.strName = "UP_detect";
|
||||||
|
boe_config.Stream_num = 2;
|
||||||
|
AI_defect_UP->Init(boe_config);
|
||||||
|
}
|
||||||
|
// UP画面模型
|
||||||
|
if (!AI_defect_Chess)
|
||||||
|
{
|
||||||
|
AI_defect_Chess = AIModel_Base::GetInstance();
|
||||||
|
AIModel_Base::AIModelRun_Config boe_config;
|
||||||
|
boe_config.gpuconfig.copy(gupconfig);
|
||||||
|
boe_config.strPath = "/home/aidlux/BOE/UseModel_Cell_ET/defect_CHESS.engine";
|
||||||
|
boe_config.inputType = AIModel_Base::Input_CHW;
|
||||||
|
boe_config.strName = "chess_detect";
|
||||||
|
boe_config.Stream_num = 2;
|
||||||
|
AI_defect_Chess->Init(boe_config);
|
||||||
|
}
|
||||||
|
// 异显
|
||||||
|
if (!AI_defect_YX_1)
|
||||||
|
{
|
||||||
|
AI_defect_YX_1 = AIModel_Base::GetInstance();
|
||||||
|
AIModel_Base::AIModelRun_Config boe_config;
|
||||||
|
boe_config.gpuconfig.copy(gupconfig);
|
||||||
|
boe_config.strPath = "/home/aidlux/BOE/UseModel_Cell_ET/defect_YX_L0.engine";
|
||||||
|
boe_config.strName = "YX1";
|
||||||
|
boe_config.inputType = AIModel_Base::Input_CHW;
|
||||||
|
AI_defect_YX_1->Init(boe_config);
|
||||||
|
}
|
||||||
|
if (!AI_defect_YX_2)
|
||||||
|
{
|
||||||
|
AI_defect_YX_2 = AIModel_Base::GetInstance();
|
||||||
|
AIModel_Base::AIModelRun_Config boe_config;
|
||||||
|
boe_config.gpuconfig.copy(gupconfig);
|
||||||
|
boe_config.strPath = "/home/aidlux/BOE/UseModel_Cell_ET/defect_YX_L127L255.engine";
|
||||||
|
boe_config.strName = "YX2";
|
||||||
|
boe_config.inputType = AIModel_Base::Input_CHW;
|
||||||
|
AI_defect_YX_2->Init(boe_config);
|
||||||
|
}
|
||||||
|
// 分类
|
||||||
|
|
||||||
|
if (!AI_defect_Cls_L0)
|
||||||
|
{
|
||||||
|
AI_defect_Cls_L0 = AIModel_Base::GetInstance();
|
||||||
|
AIModel_Base::AIModelRun_Config jbl_config;
|
||||||
|
jbl_config.gpuconfig.copy(gupconfig);
|
||||||
|
jbl_config.strPath = "/home/aidlux/BOE/UseModel_Cell_ET/class_14.engine";
|
||||||
|
jbl_config.inputType = AIModel_Base::Input_HWC;
|
||||||
|
jbl_config.strName = "14_Class";
|
||||||
|
jbl_config.IsClass = true;
|
||||||
|
AI_defect_Cls_L0->Init(jbl_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AI_defect_Cls)
|
||||||
|
{
|
||||||
|
AI_defect_Cls = AIModel_Base::GetInstance();
|
||||||
|
AIModel_Base::AIModelRun_Config jbl_config;
|
||||||
|
jbl_config.gpuconfig.copy(gupconfig);
|
||||||
|
jbl_config.strPath = "/home/aidlux/BOE/UseModel_Cell_ET/class_14.engine";
|
||||||
|
jbl_config.inputType = AIModel_Base::Input_HWC;
|
||||||
|
jbl_config.strName = "old_Class";
|
||||||
|
jbl_config.IsClass = true;
|
||||||
|
AI_defect_Cls->Init(jbl_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 字符 检测
|
||||||
|
if (!AI_defect_zf)
|
||||||
|
{
|
||||||
|
AI_defect_zf = AIModel_Base::GetInstance();
|
||||||
|
AIModel_Base::AIModelRun_Config boe_config;
|
||||||
|
boe_config.gpuconfig.copy(gupconfig);
|
||||||
|
boe_config.strPath = "/home/aidlux/BOE/UseModel_Cell_ET/defect_zf.engine";
|
||||||
|
boe_config.strName = "zf";
|
||||||
|
boe_config.inputType = AIModel_Base::Input_CHW;
|
||||||
|
AI_defect_zf->Init(boe_config);
|
||||||
|
}
|
||||||
|
// 字符 127cell
|
||||||
|
if (!AI_defect_127Cell)
|
||||||
|
{
|
||||||
|
AI_defect_127Cell = AIModel_Base::GetInstance();
|
||||||
|
AIModel_Base::AIModelRun_Config boe_config;
|
||||||
|
boe_config.gpuconfig.copy(gupconfig);
|
||||||
|
boe_config.strPath = "/home/aidlux/BOE/UseModel_Cell_ET/defect_L127.engine";
|
||||||
|
boe_config.strName = "127Cell";
|
||||||
|
boe_config.inputType = AIModel_Base::Input_CHW;
|
||||||
|
AI_defect_127Cell->Init(boe_config);
|
||||||
|
}
|
||||||
|
// 精确检测 POL 异物
|
||||||
|
if (!AI_defect_RE_POL)
|
||||||
|
{
|
||||||
|
AI_defect_RE_POL = AIModel_Base::GetInstance();
|
||||||
|
AIModel_Base::AIModelRun_Config boe_config;
|
||||||
|
boe_config.gpuconfig.copy(gupconfig);
|
||||||
|
boe_config.strPath = "/home/aidlux/BOE/UseModel_Cell_ET/BOE_POL_128x128.engine";
|
||||||
|
boe_config.strName = "RE_POL";
|
||||||
|
boe_config.inputType = AIModel_Base::Input_CHW;
|
||||||
|
AI_defect_RE_POL->Init(boe_config);
|
||||||
|
}
|
||||||
|
// 精确检测 AD 异物
|
||||||
|
if (!AI_defect_RE_AD)
|
||||||
|
{
|
||||||
|
AI_defect_RE_AD = AIModel_Base::GetInstance();
|
||||||
|
AIModel_Base::AIModelRun_Config boe_config;
|
||||||
|
boe_config.gpuconfig.copy(gupconfig);
|
||||||
|
boe_config.strPath = "/home/aidlux/BOE/UseModel_Cell_ET/BOE_AD_128x128.engine";
|
||||||
|
boe_config.strName = "RE_POL";
|
||||||
|
boe_config.inputType = AIModel_Base::Input_CHW;
|
||||||
|
AI_defect_RE_AD->Init(boe_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 边缘模型
|
||||||
|
if (!AI_defect_Edge_Big)
|
||||||
|
{
|
||||||
|
AI_defect_Edge_Big = AIModel_Base::GetInstance();
|
||||||
|
AIModel_Base::AIModelRun_Config boe_config;
|
||||||
|
boe_config.gpuconfig.copy(gupconfig);
|
||||||
|
boe_config.strPath = "/home/aidlux/BOE/UseModel_Cell_ET/Edge_Big.engine";
|
||||||
|
boe_config.strName = "Edge_Big";
|
||||||
|
boe_config.inputType = AIModel_Base::Input_HWC;
|
||||||
|
AI_defect_Edge_Big->Init(boe_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AI_defect_Edge_Samll)
|
||||||
|
{
|
||||||
|
AI_defect_Edge_Samll = AIModel_Base::GetInstance();
|
||||||
|
AIModel_Base::AIModelRun_Config boe_config;
|
||||||
|
boe_config.gpuconfig.copy(gupconfig);
|
||||||
|
boe_config.strPath = "/home/aidlux/BOE/UseModel_Cell_ET/Edge_Small.engine";
|
||||||
|
boe_config.inputType = AIModel_Base::Input_HWC;
|
||||||
|
boe_config.strName = "Edge_Small";
|
||||||
|
AI_defect_Edge_Samll->Init(boe_config);
|
||||||
|
}
|
||||||
|
// 缺pol检测
|
||||||
|
if (!AI_defect_LackPol)
|
||||||
|
{
|
||||||
|
AI_defect_LackPol = AIModel_Base::GetInstance();
|
||||||
|
AIModel_Base::AIModelRun_Config boe_config;
|
||||||
|
boe_config.gpuconfig.copy(gupconfig);
|
||||||
|
boe_config.strPath = "/home/aidlux/BOE/UseModel_Cell_ET/BOE_LOSSPOL.engine";
|
||||||
|
boe_config.inputType = AIModel_Base::Input_CHW;
|
||||||
|
boe_config.strName = "BOE_LOSSPOL";
|
||||||
|
AI_defect_LackPol->Init(boe_config);
|
||||||
|
}
|
||||||
|
// 缺pol检测
|
||||||
|
if (!AI_defect_MarkLine)
|
||||||
|
{
|
||||||
|
AI_defect_MarkLine = AIModel_Base::GetInstance();
|
||||||
|
AIModel_Base::AIModelRun_Config boe_config;
|
||||||
|
boe_config.gpuconfig.copy(gupconfig);
|
||||||
|
boe_config.strPath = "/home/aidlux/BOE/UseModel_Cell_ET/defect_MARK_LINE.engine";
|
||||||
|
boe_config.inputType = AIModel_Base::Input_CHW;
|
||||||
|
boe_config.strName = "MarkLine";
|
||||||
|
AI_defect_MarkLine->Init(boe_config);
|
||||||
|
}
|
||||||
|
// 缺pol检测
|
||||||
|
if (!AI_defect_Edge_QX)
|
||||||
|
{
|
||||||
|
AI_defect_Edge_QX = AIModel_Base::GetInstance();
|
||||||
|
AIModel_Base::AIModelRun_Config boe_config;
|
||||||
|
boe_config.gpuconfig.copy(gupconfig);
|
||||||
|
boe_config.strPath = "/home/aidlux/BOE/UseModel_Cell_ET/BOE_Edge_320x320.engine";
|
||||||
|
boe_config.inputType = AIModel_Base::Input_CHW;
|
||||||
|
boe_config.strName = "Edge_QX";
|
||||||
|
AI_defect_Edge_QX->Init(boe_config);
|
||||||
|
}
|
||||||
|
m_bInitSucc = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
#include "CUDA_DataChange.cuh"
|
||||||
|
|
||||||
|
__global__ void ucharToFloat_stream(const unsigned char *input, float *output, int size)
|
||||||
|
{
|
||||||
|
int tid = blockIdx.x * blockDim.x + threadIdx.x;
|
||||||
|
if (tid < size)
|
||||||
|
{
|
||||||
|
output[tid] = static_cast<float>(input[tid]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__global__ void floatToUchar_stream(const float *input, unsigned char *output, int size)
|
||||||
|
{
|
||||||
|
int tid = blockIdx.x * blockDim.x + threadIdx.x;
|
||||||
|
if (tid < size)
|
||||||
|
{
|
||||||
|
output[tid] = static_cast<unsigned char>(input[tid]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cuda_ucharToFloat_stream(const unsigned char *input, float *output, int size, cudaStream_t stream)
|
||||||
|
{
|
||||||
|
int blockSize = 1024;
|
||||||
|
int numBlocks = (size + blockSize - 1) / blockSize;
|
||||||
|
ucharToFloat_stream<<<numBlocks, blockSize, 0, stream>>>(input, output, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cuda_FloatTouchar_stream(const float *input, unsigned char *output, int size, cudaStream_t stream)
|
||||||
|
{
|
||||||
|
|
||||||
|
int blockSize = 1024;
|
||||||
|
int numBlocks = (size + blockSize - 1) / blockSize;
|
||||||
|
floatToUchar_stream<<<numBlocks, blockSize, 0, stream>>>(input, output, size);
|
||||||
|
}
|
||||||
@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* @Author: xiewenji 527774126@qq.com
|
||||||
|
* @Date: 2025-07-05 19:32:41
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @LastEditTime: 2025-09-06 11:13:54
|
||||||
|
* @FilePath: /AI_SO_Test/AIEngineModule/src/Engine.cpp
|
||||||
|
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
*/
|
||||||
|
#include "Engine.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <cuda_runtime_api.h>
|
||||||
|
|
||||||
|
using namespace nvinfer1;
|
||||||
|
|
||||||
|
class Logger : public ILogger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void log(Severity severity, const char *msg) noexcept override
|
||||||
|
{
|
||||||
|
if (severity <= Severity::kWARNING)
|
||||||
|
std::cout << "[TensorRT] " << msg << std::endl;
|
||||||
|
}
|
||||||
|
} gLogger;
|
||||||
|
// 实现自定义删除器
|
||||||
|
void TensorRTDeleter::operator()(nvinfer1::IRuntime *ptr) const noexcept
|
||||||
|
{
|
||||||
|
// if (ptr)
|
||||||
|
// {
|
||||||
|
// printf("************ IRuntime \n");
|
||||||
|
// // delete ptr;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
void TensorRTDeleter::operator()(nvinfer1::IExecutionContext *ptr) const noexcept
|
||||||
|
{
|
||||||
|
// if (!ptr)
|
||||||
|
// return;
|
||||||
|
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// printf("************ IExecutionContext \n");
|
||||||
|
// // 检查有效性、上下文等
|
||||||
|
// delete ptr;
|
||||||
|
// }
|
||||||
|
// catch (const std::exception &e)
|
||||||
|
// {
|
||||||
|
// std::cerr << "[Deleter] Exception: " << e.what() << "\n";
|
||||||
|
// }
|
||||||
|
// catch (...)
|
||||||
|
// {
|
||||||
|
// std::cerr << "[Deleter] Unknown error during deletion\n";
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
void TensorRTDeleter::operator()(nvinfer1::ICudaEngine *ptr) const noexcept
|
||||||
|
{
|
||||||
|
// if (ptr)
|
||||||
|
// {
|
||||||
|
// printf("************ ICudaEngine \n");
|
||||||
|
// delete ptr;
|
||||||
|
// }
|
||||||
|
// if (ptr)
|
||||||
|
// {
|
||||||
|
// printf("************ ICudaEngine \n");
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// // delete ptr; //
|
||||||
|
// }
|
||||||
|
// catch (...)
|
||||||
|
// {
|
||||||
|
// std::cerr << "[Deleter] Exception deleting ICudaEngine\n";
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
Engine::Engine(int gpuId) : gpuId_(gpuId) {}
|
||||||
|
|
||||||
|
Engine::~Engine()
|
||||||
|
{
|
||||||
|
// printf("========Engine= start ====\n");
|
||||||
|
// engine_.reset();
|
||||||
|
// runtime_.reset();
|
||||||
|
// printf("========Engine= engine_.reset();====\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Engine::loadFromFile(const std::string &enginePath)
|
||||||
|
{
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
cudaSetDevice(gpuId_);
|
||||||
|
std::ifstream file(enginePath, std::ios::binary);
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
std::cerr << "[Engine] Failed to open engine file: " << enginePath << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.seekg(0, file.end);
|
||||||
|
size_t size = file.tellg();
|
||||||
|
file.seekg(0, file.beg);
|
||||||
|
std::vector<char> engineData(size);
|
||||||
|
file.read(engineData.data(), size);
|
||||||
|
runtime_ = std::unique_ptr<IRuntime, TensorRTDeleter>(createInferRuntime(gLogger));
|
||||||
|
if (!runtime_)
|
||||||
|
{
|
||||||
|
std::cerr << "[Engine] Failed to create runtime." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
engine_ = std::unique_ptr<ICudaEngine, TensorRTDeleter>(
|
||||||
|
runtime_->deserializeCudaEngine(engineData.data(), size));
|
||||||
|
|
||||||
|
if (!engine_)
|
||||||
|
{
|
||||||
|
std::cerr << "[Engine] Failed to deserialize engine." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (const std::exception &e)
|
||||||
|
{
|
||||||
|
std::cerr << "[Engine] Exception during loadFromFile: " << e.what() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
std::cerr << "[Engine] Unknown exception during loadFromFile." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Engine::getNbBindings() const
|
||||||
|
{
|
||||||
|
return engine_ ? engine_->getNbIOTensors() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Engine::getBindingName(int index) const
|
||||||
|
{
|
||||||
|
return engine_ ? engine_->getIOTensorName(index) : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
Dims Engine::getBindingDims(int index) const
|
||||||
|
{
|
||||||
|
if (!engine_)
|
||||||
|
return Dims{};
|
||||||
|
std::string name = engine_->getIOTensorName(index);
|
||||||
|
return engine_->getTensorShape(name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Engine::bindingIsInput(int index) const
|
||||||
|
{
|
||||||
|
if (!engine_)
|
||||||
|
return false;
|
||||||
|
std::string name = engine_->getIOTensorName(index);
|
||||||
|
return engine_->getTensorIOMode(name.c_str()) == TensorIOMode::kINPUT;
|
||||||
|
}
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
#include "ParmNameChange.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <regex>
|
||||||
|
ParmNameChange *ParmNameChange::instance = nullptr;
|
||||||
|
ParmNameChange::ParmNameChange(/* args */)
|
||||||
|
{
|
||||||
|
m_nWorkIdx = 0;
|
||||||
|
m_bUseWorkIdx = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParmNameChange::~ParmNameChange()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ParmNameChange *ParmNameChange::getInstance()
|
||||||
|
{
|
||||||
|
if (instance == nullptr)
|
||||||
|
{
|
||||||
|
instance = new ParmNameChange(); // 如果实例为空,则创建新实例
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ParmNameChange::GetWorkIdx_WebConfigCamNameT(std::string strWebConfigCamName)
|
||||||
|
{
|
||||||
|
int number = -1;
|
||||||
|
std::regex regex(R"(work_(\d+)_)", std::regex_constants::icase);
|
||||||
|
|
||||||
|
// 用正则表达式搜索字符串
|
||||||
|
std::smatch match;
|
||||||
|
if (std::regex_search(strWebConfigCamName, match, regex))
|
||||||
|
{
|
||||||
|
std::string number_str = match.str(1); // 提取到的数字部分
|
||||||
|
try
|
||||||
|
{
|
||||||
|
number = std::stoi(number_str); // 转换为整数
|
||||||
|
// std::cout << "Extracted number as integer: " << number << std::endl;
|
||||||
|
}
|
||||||
|
catch (const std::invalid_argument &e)
|
||||||
|
{
|
||||||
|
// std::cout << "Invalid argument: " << e.what() << std::endl;
|
||||||
|
number = -1;
|
||||||
|
}
|
||||||
|
catch (const std::out_of_range &e)
|
||||||
|
{
|
||||||
|
// std::cout << "Out of range: " << e.what() << std::endl;
|
||||||
|
number = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "No match found." << std::endl;
|
||||||
|
}
|
||||||
|
number--;
|
||||||
|
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ParmNameChange::GetWebConfigCamName_DetImgCamName(std::string strDetImgCamName)
|
||||||
|
{
|
||||||
|
std::string strWebConfigCamName = "";
|
||||||
|
|
||||||
|
if (strDetImgCamName == "left")
|
||||||
|
{
|
||||||
|
strWebConfigCamName = "left";
|
||||||
|
}
|
||||||
|
else if (strDetImgCamName == "right")
|
||||||
|
{
|
||||||
|
strWebConfigCamName = "right";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strWebConfigCamName = "Merge";
|
||||||
|
}
|
||||||
|
|
||||||
|
return strWebConfigCamName;
|
||||||
|
}
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* @Author: xiewenji 527774126@qq.com
|
||||||
|
* @Date: 2025-09-25 16:25:30
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @LastEditTime: 2025-09-25 17:16:49
|
||||||
|
* @FilePath: /BOE_POL_ET_Detect/AlgorithmModule/include/AI_Mark_Det.h
|
||||||
|
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
//实现对部分缺陷 需要进行 数量 和距离上分析的
|
||||||
|
*/
|
||||||
|
#ifndef ParmNameChange_H_
|
||||||
|
#define ParmNameChange_H_
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class ParmNameChange
|
||||||
|
{
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* data */
|
||||||
|
public:
|
||||||
|
ParmNameChange(/* args */);
|
||||||
|
~ParmNameChange();
|
||||||
|
|
||||||
|
static ParmNameChange *getInstance();
|
||||||
|
|
||||||
|
// 从web参数的相机名称获得 工位序号
|
||||||
|
int GetWorkIdx_WebConfigCamNameT(std::string strWebConfigCamName);
|
||||||
|
// 从检测图片的相机名称 获得 界面的参数的相机名称
|
||||||
|
std::string GetWebConfigCamName_DetImgCamName(std::string strDetImgCamName);
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool m_nWorkIdx; // 工位序号
|
||||||
|
|
||||||
|
private:
|
||||||
|
static ParmNameChange *instance; // 静态成员指针,存储单例对象
|
||||||
|
bool m_bUseWorkIdx; // 是否使用 工位序号
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
//图片基本处理
|
||||||
|
*/
|
||||||
|
#ifndef AIClassify_H_
|
||||||
|
#define AIClassify_H_
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
struct AI_PIECE_INFO
|
||||||
|
{
|
||||||
|
int num;
|
||||||
|
int len;
|
||||||
|
int abs_L;
|
||||||
|
int long_num;
|
||||||
|
int short_num;
|
||||||
|
AI_PIECE_INFO()
|
||||||
|
{
|
||||||
|
num = 0;
|
||||||
|
len = 0;
|
||||||
|
abs_L = 0;
|
||||||
|
long_num = 0;
|
||||||
|
short_num = 0;
|
||||||
|
}
|
||||||
|
void print(std::string str)
|
||||||
|
{
|
||||||
|
printf("%s>> num %d len %d abs_L %d long_num %d short_num %d\n", str.c_str(), num, len, abs_L, long_num, short_num);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct AI_Classify_Info
|
||||||
|
{
|
||||||
|
int num; // 数量
|
||||||
|
float score; // 得分
|
||||||
|
float avgScore; // 平均得分
|
||||||
|
AI_Classify_Info()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
num = 0;
|
||||||
|
score = 0;
|
||||||
|
avgScore = 0;
|
||||||
|
}
|
||||||
|
void print(std::string str)
|
||||||
|
{
|
||||||
|
printf("%s==== num %d score %f avgScore %f\n", str.c_str(), num, score, avgScore);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class AIClassify
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
AIClassify();
|
||||||
|
~AIClassify();
|
||||||
|
// 分类
|
||||||
|
int GetDetRoiList(const cv::Mat &src_Img, cv::Rect qx_roi, std::vector<cv::Rect> &samllRoiList,int nwidth,int nheight);
|
||||||
|
|
||||||
|
private:
|
||||||
|
cv::Rect GetCutRoi(cv::Rect roi, const cv::Mat &img,int nwidth,int nheight);
|
||||||
|
// 获取检测roi list
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* @Author: your name
|
||||||
|
* @Date: 2022-04-20 15:49:50
|
||||||
|
* @LastEditTime: 2025-09-24 09:55:53
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
* @FilePath: /ZCXD_MonitorPlatform/src/CoreLogicModule/include/CamDeal.h
|
||||||
|
*/
|
||||||
|
#ifndef AICommonDefine_H_
|
||||||
|
#define AICommonDefine_H_
|
||||||
|
|
||||||
|
#define USE_WHITEBACK_CLASS 1
|
||||||
|
|
||||||
|
// AI缺陷分类缺陷的种类
|
||||||
|
enum AI_CLass_QX_NAME_
|
||||||
|
{
|
||||||
|
|
||||||
|
AI_CLass_QX_NAME_ok_yisi, // 疑似
|
||||||
|
AI_CLass_QX_NAME_yixian, // 异显
|
||||||
|
AI_CLass_QX_NAME_POL_CEL, // 亮点
|
||||||
|
AI_CLass_QX_NAME_zara, // ZARA
|
||||||
|
AI_CLass_QX_NAME_ps, // PS
|
||||||
|
AI_CLass_QX_NAME_line, // 线
|
||||||
|
AI_CLass_QX_NAME_fangge_line, // 方格线
|
||||||
|
AI_CLass_QX_NAME_qipao, // 气泡
|
||||||
|
AI_CLass_QX_NAME_qing_huashang, // 轻划伤
|
||||||
|
AI_CLass_QX_NAME_mtx, // MTX
|
||||||
|
AI_CLass_QX_NAME_yisi_qianzangwu, // 疑似浅层脏污
|
||||||
|
AI_CLass_QX_NAME_qing_zangwu, // 轻脏污
|
||||||
|
AI_CLass_QX_NAME_zhong_zangwu, // 严重脏污
|
||||||
|
AI_CLass_QX_NAME_andian, // 暗点
|
||||||
|
AI_CLass_QX_NAME_huashang, // 划伤
|
||||||
|
AI_CLass_QX_NAME_zf, // zf
|
||||||
|
AI_CLass_QX_NAME_other, // 其他
|
||||||
|
AI_CLass_QX_NAME_count,
|
||||||
|
};
|
||||||
|
// 缺陷项对应在参数中的名称
|
||||||
|
static const std::string AI_CLass_QX_NAME_Names[] =
|
||||||
|
{
|
||||||
|
"ok_yisi",
|
||||||
|
"yixian",
|
||||||
|
"liangdian",
|
||||||
|
"zara",
|
||||||
|
"ps",
|
||||||
|
"line",
|
||||||
|
"fangge_line",
|
||||||
|
"qipao",
|
||||||
|
"qing_huashang",
|
||||||
|
"mtx",
|
||||||
|
"yisi_qianzangwu",
|
||||||
|
"qing_zangwu",
|
||||||
|
"zhong_zangwu",
|
||||||
|
"andian",
|
||||||
|
"huashang",
|
||||||
|
"zf",
|
||||||
|
"other"};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,181 @@
|
|||||||
|
/*
|
||||||
|
//实现对部分缺陷 需要进行 数量 和距离上分析的
|
||||||
|
*/
|
||||||
|
#ifndef AI_Edge_Algin_H_
|
||||||
|
#define AI_Edge_Algin_H_
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include "CheckUtil.hpp"
|
||||||
|
#include "OtherDetBaseDefine.h"
|
||||||
|
#include "CheckErrorCodeDefine.hpp"
|
||||||
|
#include "ImageDetConfig.h"
|
||||||
|
#include "AI_Factory.h"
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
// 边缘搜索定位结果
|
||||||
|
struct Edge_AI_Result
|
||||||
|
{
|
||||||
|
int nresult;
|
||||||
|
cv::Mat mask;
|
||||||
|
cv::Rect roi;
|
||||||
|
cv::Mat DetMask_src; // 原图上产品区域
|
||||||
|
std::shared_ptr<std::vector<cv::Rect>> edge_RoiList; // 边缘检测的roi区域
|
||||||
|
Edge_AI_Result()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
nresult = 0;
|
||||||
|
roi = cv::Rect(0, 0, 0, 0);
|
||||||
|
if (!mask.empty())
|
||||||
|
{
|
||||||
|
mask.release();
|
||||||
|
}
|
||||||
|
if (!DetMask_src.empty())
|
||||||
|
{
|
||||||
|
DetMask_src.release();
|
||||||
|
}
|
||||||
|
edge_RoiList = std::make_shared<std::vector<cv::Rect>>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class AI_Edge_Algin
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum SaveProcessType
|
||||||
|
{
|
||||||
|
Save_Close, // 不保存
|
||||||
|
Save_Filter, // 过滤的
|
||||||
|
Save_ALL, // 全部
|
||||||
|
};
|
||||||
|
|
||||||
|
/// @brief 检测过程的参数
|
||||||
|
struct DetConfig
|
||||||
|
{
|
||||||
|
int ncamId; // 相机ID
|
||||||
|
std::string strCamName; // 相机ID
|
||||||
|
int nthresholdvalue; // 背景阈值
|
||||||
|
int nAIErodesize; // 边缘腐蚀强度
|
||||||
|
bool bDebugSaveImg; // 保存结果图片
|
||||||
|
SaveProcessType saveProcessImg; // 保存过程图片
|
||||||
|
bool bUseDrawRoi_Check; // 是否用绘制的ROI进行校验
|
||||||
|
cv::Rect drawRoi; // 绘制的 ROi;
|
||||||
|
cv::Mat drawMask; // 绘制的maksk
|
||||||
|
DetConfig()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
ncamId = 0;
|
||||||
|
strCamName = "";
|
||||||
|
nthresholdvalue = 1;
|
||||||
|
nAIErodesize = 7;
|
||||||
|
bDebugSaveImg = false;
|
||||||
|
saveProcessImg = Save_Close;
|
||||||
|
bUseDrawRoi_Check = false;
|
||||||
|
drawRoi = cv::Rect(0, 0, 0, 0);
|
||||||
|
if (!drawMask.empty())
|
||||||
|
{
|
||||||
|
drawMask.release();
|
||||||
|
/* code */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Print()
|
||||||
|
{
|
||||||
|
printf("nthresholdvalue:%d;nAIErodesize %d;bSaveResultImg %s SaveProcessImg %d\n",
|
||||||
|
nthresholdvalue, nAIErodesize, BOOL_TO_STR(bDebugSaveImg), saveProcessImg);
|
||||||
|
|
||||||
|
printf("bUseDrawRoi_Check %s roi %s \n",
|
||||||
|
BOOL_TO_STR(bUseDrawRoi_Check), CheckUtil::GetRectString(drawRoi).c_str());
|
||||||
|
}
|
||||||
|
bool IsSaveProcessImg()
|
||||||
|
{
|
||||||
|
if (saveProcessImg != Save_Close)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
AI_Edge_Algin(/* args */);
|
||||||
|
~AI_Edge_Algin();
|
||||||
|
// 初始化检测模型
|
||||||
|
int InitModel_ALL();
|
||||||
|
int Detect(const cv::Mat &img, DetConfig *pDetConfig, std::shared_ptr<Edge_AI_Result> &pCheckResult_Aling);
|
||||||
|
int SaveSmallImg(const cv::Mat &img, const cv::Mat &mask, cv::Rect roi);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int InitModel_Big();
|
||||||
|
int InitModel_Small();
|
||||||
|
int Det_big(const cv::Mat &img, vector<Rect> &smallRoiList, std::shared_ptr<std::vector<cv::Rect>> edgeRoiList, cv::Rect &bigRoi, cv::Mat &big_mask);
|
||||||
|
int Dtet_small(const cv::Mat &img, vector<Rect> &smallRoiList, cv::Mat &Src_Mask);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_bInitSucc; // 是否初始化成功
|
||||||
|
|
||||||
|
// 检测结果
|
||||||
|
// std::shared_ptr<Edge_AI_Result> m_pCheckResult_Aling;
|
||||||
|
|
||||||
|
OtherDet_Config *m_pOtherDet_Config;
|
||||||
|
DetConfig *m_pDetConfig;
|
||||||
|
std::shared_ptr<AIFactory> AI_Factory;
|
||||||
|
std::shared_ptr<AIMulThreadRunBase> runner;
|
||||||
|
std::string m_str_curCamName;
|
||||||
|
bool m_bInitialized;
|
||||||
|
bool m_bModelSucc;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* data */
|
||||||
|
};
|
||||||
|
|
||||||
|
// 图片特征定位
|
||||||
|
class Image_Feature_Algin
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct DetConfig
|
||||||
|
{
|
||||||
|
bool bSaveImg;
|
||||||
|
bool bSave_Process; // 存储过程图片
|
||||||
|
|
||||||
|
float fscore;
|
||||||
|
cv::Mat TemplateImg; // 模版图片
|
||||||
|
cv::Mat DetImg; // 检测图片
|
||||||
|
|
||||||
|
cv::Rect Search_Roi; // 搜索 范围
|
||||||
|
cv::Rect feature_Roi; // 特征区域
|
||||||
|
cv::Rect param_CropRoi; // 裁剪区域,在参数图片上
|
||||||
|
cv::Rect DetImg_CropROi; // 裁剪区域,在检测图片上
|
||||||
|
DetConfig()
|
||||||
|
{
|
||||||
|
bSaveImg = false;
|
||||||
|
bSave_Process = false;
|
||||||
|
fscore = 0.9;
|
||||||
|
Search_Roi = cv::Rect(0, 0, 0, 0);
|
||||||
|
feature_Roi = cv::Rect(0, 0, 0, 0);
|
||||||
|
param_CropRoi = cv::Rect(0, 0, 0, 0);
|
||||||
|
DetImg_CropROi = cv::Rect(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
Image_Feature_Algin(/* args */);
|
||||||
|
~Image_Feature_Algin();
|
||||||
|
int Detect(DetConfig *pDetConfig, Align_Result *pResult, std::vector<std::string> &LogList);
|
||||||
|
|
||||||
|
private:
|
||||||
|
cv::Point findBestTemplateMatch(const cv::Mat &detectionImage, const cv::Mat &templateImage, double &bestScore, int method = cv::TM_CCOEFF_NORMED);
|
||||||
|
|
||||||
|
private:
|
||||||
|
PRINT_LOG_ m_PrintLog;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* data */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
//实现对部分缺陷 需要进行 数量 和距离上分析的
|
||||||
|
*/
|
||||||
|
#ifndef AI_Edge_QX_Det_H_
|
||||||
|
#define AI_Edge_QX_Det_H_
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include "CheckUtil.hpp"
|
||||||
|
#include "OtherDetect.h"
|
||||||
|
#include "OtherDetBaseDefine.h"
|
||||||
|
#include "CheckErrorCodeDefine.hpp"
|
||||||
|
#include "ImageDetConfig.h"
|
||||||
|
#include "CheckConfigDefine.h"
|
||||||
|
#include "ImageStorage.h"
|
||||||
|
#include "AI_Factory.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
// 边缘缺陷检测
|
||||||
|
class AI_Edge_QX_Det
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// @brief 检测过程的参数
|
||||||
|
struct DetConfig
|
||||||
|
{
|
||||||
|
std::shared_ptr<std::vector<cv::Rect>> pEdgeDet_roiList;
|
||||||
|
Function_Edge_Det *pdege_Det_config;
|
||||||
|
std::string strCamChannel;
|
||||||
|
cv::Rect CutRoi;
|
||||||
|
int ninstruct;
|
||||||
|
DetConfig()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
pdege_Det_config = NULL;
|
||||||
|
strCamChannel = "";
|
||||||
|
ninstruct = 0;
|
||||||
|
CutRoi = cv::Rect(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
AI_Edge_QX_Det(/* args */);
|
||||||
|
~AI_Edge_QX_Det();
|
||||||
|
|
||||||
|
int Detect(const cv::Mat &img, cv::Mat &detmask, DetConfig *pDetConfig,std::shared_ptr<DetLog> pdetlog);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int SaveProcessImg(const cv::Mat &inImg, const cv::Mat &outImg, bool isALLzeros, DetConfig *pDetConfig, int idx = 0, int nruntype = 0);
|
||||||
|
std::string GetImgSaveName(int flag = 0);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_bInitSucc; // 是否初始化成功
|
||||||
|
|
||||||
|
std::string m_strSaveImgRootPath;
|
||||||
|
std::string m_strSaveImgRootPath_OK;
|
||||||
|
std::string m_strSaveImgRootPath_Qx;
|
||||||
|
ImageStorage *m_pImageStorage;
|
||||||
|
DetConfig *m_pDetConfig;
|
||||||
|
|
||||||
|
std::shared_ptr<AIFactory> AI_Factory;
|
||||||
|
std::shared_ptr<DetLog> m_pdetlog;
|
||||||
|
|
||||||
|
int m_nImge_num;
|
||||||
|
std::string m_strCamChannel;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* data */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* @Author: xiewenji 527774126@qq.com
|
||||||
|
* @Date: 2025-09-25 16:25:30
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @LastEditTime: 2025-09-25 16:57:01
|
||||||
|
* @FilePath: /BOE_POL_ET_Detect/AlgorithmModule/include/AI_Mark_Det.h
|
||||||
|
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
//实现对部分缺陷 需要进行 数量 和距离上分析的
|
||||||
|
*/
|
||||||
|
#ifndef AI_Mark_Det_H_
|
||||||
|
#define AI_Mark_Det_H_
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include "CheckUtil.hpp"
|
||||||
|
#include "OtherDetect.h"
|
||||||
|
#include "OtherDetBaseDefine.h"
|
||||||
|
#include "CheckErrorCodeDefine.hpp"
|
||||||
|
#include "ImageDetConfig.h"
|
||||||
|
#include "CheckConfigDefine.h"
|
||||||
|
#include "ImageStorage.h"
|
||||||
|
#include "AI_Factory.h"
|
||||||
|
using namespace std;
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
// 二次分割求面积
|
||||||
|
class AI_Mark_Det : public AIDetectBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// 检测参数和结果
|
||||||
|
struct DetConfigResult
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string strCamName;
|
||||||
|
int nresult;
|
||||||
|
cv::Rect searchroi;
|
||||||
|
std::string strChannel;
|
||||||
|
bool bDebugsaveimg;
|
||||||
|
bool bDetSaveImg;
|
||||||
|
std::shared_ptr<DetLog> pdetlog;
|
||||||
|
cv::Rect markRoi;
|
||||||
|
|
||||||
|
DetConfigResult()
|
||||||
|
{
|
||||||
|
|
||||||
|
nresult = -1;
|
||||||
|
strCamName = "";
|
||||||
|
strChannel = "";
|
||||||
|
searchroi = cv::Rect(0, 0, 0, 0);
|
||||||
|
bDebugsaveimg = false;
|
||||||
|
bDetSaveImg = false;
|
||||||
|
markRoi = cv::Rect(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
AI_Mark_Det(/* args */);
|
||||||
|
~AI_Mark_Det();
|
||||||
|
|
||||||
|
int Detect(const cv::Mat &img, DetConfigResult *pDetConfig);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int Det_img(const cv::Mat &img, DetConfigResult *pDetConfig);
|
||||||
|
|
||||||
|
// 分析结果
|
||||||
|
int Analysisy(const cv::Mat &maskImg, DetConfigResult *pDetConfig);
|
||||||
|
|
||||||
|
// 存储过程图片
|
||||||
|
int SaveProcessImg(const cv::Mat &inImg, const cv::Mat &outImg, const cv::Mat &oldmask, DetConfigResult *pDetConfig);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_bModelSucc;
|
||||||
|
cv::Mat detimg123;
|
||||||
|
ImageStorage *m_pImageStorage;
|
||||||
|
|
||||||
|
std::shared_ptr<AIFactory> AI_Factory;
|
||||||
|
|
||||||
|
std::shared_ptr<DetLog> m_pdetlog;
|
||||||
|
|
||||||
|
int m_Show_Area;
|
||||||
|
float m_Show_Len;
|
||||||
|
cv::Point m_Len_P1;
|
||||||
|
cv::Point m_Len_P2;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* data */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
//实现对部分缺陷 需要进行 数量 和距离上分析的
|
||||||
|
*/
|
||||||
|
#ifndef AI_Second_Det_H_
|
||||||
|
#define AI_Second_Det_H_
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include "CheckUtil.hpp"
|
||||||
|
#include "OtherDetect.h"
|
||||||
|
#include "OtherDetBaseDefine.h"
|
||||||
|
#include "CheckErrorCodeDefine.hpp"
|
||||||
|
#include "ImageDetConfig.h"
|
||||||
|
#include "CheckConfigDefine.h"
|
||||||
|
#include "ImageStorage.h"
|
||||||
|
#include "AI_Factory.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
// 二次分割求面积
|
||||||
|
class AI_SecondDet : public AIDetectBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// 检测参数和结果
|
||||||
|
struct DetConfigResult
|
||||||
|
{
|
||||||
|
Function_SecondDet *pfunction_secondDet;
|
||||||
|
float fImgage_Scale_X;
|
||||||
|
float fImgage_Scale_Y;
|
||||||
|
float min_DetArea;
|
||||||
|
cv::Rect qx_roi;
|
||||||
|
int qx_type;
|
||||||
|
std::string qx_name;
|
||||||
|
int old_Area;
|
||||||
|
float old_len;
|
||||||
|
int new_Area;
|
||||||
|
float new_len;
|
||||||
|
int nresult;
|
||||||
|
std::string strChannel;
|
||||||
|
std::shared_ptr<DetLog> pdetlog; // 检测日志
|
||||||
|
|
||||||
|
DetConfigResult()
|
||||||
|
{
|
||||||
|
qx_roi = cv::Rect(0, 0, 0, 0);
|
||||||
|
qx_type = 0;
|
||||||
|
min_DetArea = 0;
|
||||||
|
qx_name = "";
|
||||||
|
old_Area = 0;
|
||||||
|
old_len = 0;
|
||||||
|
new_Area = 0;
|
||||||
|
new_len = 0;
|
||||||
|
nresult = 0;
|
||||||
|
pfunction_secondDet = NULL;
|
||||||
|
strChannel = "";
|
||||||
|
fImgage_Scale_X = 0.0333;
|
||||||
|
fImgage_Scale_Y = 0.0333;
|
||||||
|
}
|
||||||
|
void SetAreaAndLen(int oldArea, float oldLen)
|
||||||
|
{
|
||||||
|
old_Area = oldArea;
|
||||||
|
old_len = oldLen;
|
||||||
|
new_Area = old_Area;
|
||||||
|
new_len = old_len;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
AI_SecondDet(/* args */);
|
||||||
|
~AI_SecondDet();
|
||||||
|
int Detect(const cv::Mat &img, const cv::Mat &mask, DetConfigResult *pDetConfig);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
cv::Rect GetCutRoi(cv::Rect &roi, const cv::Mat &img);
|
||||||
|
|
||||||
|
int Det_Pol(const cv::Mat &img, DetConfigResult *pDetConfig);
|
||||||
|
int Det_AD(const cv::Mat &img, DetConfigResult *pDetConfig);
|
||||||
|
|
||||||
|
// 分析结果
|
||||||
|
int Analysisy(const cv::Mat &maskImg, DetConfigResult *pDetConfig);
|
||||||
|
|
||||||
|
// 存储过程图片
|
||||||
|
int SaveProcessImg(const cv::Mat &inImg, const cv::Mat &outImg, const cv::Mat &oldmask, DetConfigResult *pDetConfig);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_bModelSucc_AD;
|
||||||
|
bool m_bModelSucc_POL;
|
||||||
|
cv::Mat detimg123;
|
||||||
|
ImageStorage *m_pImageStorage;
|
||||||
|
std::shared_ptr<AIFactory> AI_Factory;
|
||||||
|
|
||||||
|
int m_Show_Area;
|
||||||
|
float m_Show_Len;
|
||||||
|
cv::Point m_Len_P1;
|
||||||
|
cv::Point m_Len_P2;
|
||||||
|
std::shared_ptr<DetLog> m_pdetlog;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* data */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* @Author: xiewenji 527774126@qq.com
|
||||||
|
* @Date: 2025-09-25 16:25:30
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @LastEditTime: 2025-09-25 17:16:49
|
||||||
|
* @FilePath: /BOE_POL_ET_Detect/AlgorithmModule/include/AI_Mark_Det.h
|
||||||
|
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
//实现对部分缺陷 需要进行 数量 和距离上分析的
|
||||||
|
*/
|
||||||
|
#ifndef AI_ZF_Det_H_
|
||||||
|
#define AI_ZF_Det_H_
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include "CheckUtil.hpp"
|
||||||
|
#include "OtherDetect.h"
|
||||||
|
#include "OtherDetBaseDefine.h"
|
||||||
|
#include "CheckErrorCodeDefine.hpp"
|
||||||
|
#include "ImageDetConfig.h"
|
||||||
|
#include "CheckConfigDefine.h"
|
||||||
|
#include "ImageStorage.h"
|
||||||
|
#include "AI_Factory.h"
|
||||||
|
using namespace std;
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
// 二次分割求面积
|
||||||
|
class AI_ZF_Det
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// 检测参数和结果
|
||||||
|
struct DetConfigResult
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string strCamName;
|
||||||
|
int nresult;
|
||||||
|
|
||||||
|
std::shared_ptr<ZF_Result> pZF_Result;
|
||||||
|
bool bDebugsaveimg;
|
||||||
|
bool bDetSaveImg;
|
||||||
|
std::shared_ptr<DetLog> pdetlog;
|
||||||
|
|
||||||
|
DetConfigResult()
|
||||||
|
{
|
||||||
|
|
||||||
|
nresult = -1;
|
||||||
|
strCamName = "";
|
||||||
|
bDebugsaveimg = false;
|
||||||
|
bDetSaveImg = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
AI_ZF_Det(/* args */);
|
||||||
|
~AI_ZF_Det();
|
||||||
|
|
||||||
|
int Detect(const cv::Mat &img, DetConfigResult *pDetConfig);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int Det_img(const cv::Mat &img, DetConfigResult *pDetConfig);
|
||||||
|
|
||||||
|
// 分析结果
|
||||||
|
int Analysisy(const cv::Mat &maskImg, DetConfigResult *pDetConfig);
|
||||||
|
|
||||||
|
// 存储过程图片
|
||||||
|
int SaveProcessImg(const cv::Mat &inImg, const cv::Mat &outImg, const cv::Mat &oldmask, DetConfigResult *pDetConfig);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_bModelSucc;
|
||||||
|
cv::Mat detimg123;
|
||||||
|
ImageStorage *m_pImageStorage;
|
||||||
|
|
||||||
|
std::shared_ptr<AIFactory> AI_Factory;
|
||||||
|
|
||||||
|
std::shared_ptr<DetLog> m_pdetlog;
|
||||||
|
|
||||||
|
int m_Show_Area;
|
||||||
|
float m_Show_Len;
|
||||||
|
cv::Point m_Len_P1;
|
||||||
|
cv::Point m_Len_P2;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* data */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,163 @@
|
|||||||
|
/*
|
||||||
|
* @Author: your name
|
||||||
|
* @Date: 2022-04-20 15:49:50
|
||||||
|
* @LastEditTime: 2025-09-25 17:22:34
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
* @FilePath: /ZCXD_MonitorPlatform/src/CoreLogicModule/include/CamDeal.h
|
||||||
|
*/
|
||||||
|
#ifndef CameraCheckAnalysisy_H_
|
||||||
|
#define CameraCheckAnalysisy_H_
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
#include <thread>
|
||||||
|
#include <string>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include "Define_Base.h"
|
||||||
|
#include "ImgCheckBase.h"
|
||||||
|
#include "ImageDetBase.h"
|
||||||
|
#include "ImgCheckConfig.h"
|
||||||
|
#include "CheckErrorCodeDefine.hpp"
|
||||||
|
#include "ConfigBase.h"
|
||||||
|
#include "CheckConfigDefine.h"
|
||||||
|
#include "ImageDetConfig.h"
|
||||||
|
#include "Define_Product.hpp"
|
||||||
|
#include "CameraResult.h"
|
||||||
|
#include "DetLog.h"
|
||||||
|
#include "ImageResultJudge.h"
|
||||||
|
#include "CheckResultJson.h"
|
||||||
|
#include "Edge_Search.h"
|
||||||
|
#include "AI_Mark_Det.h"
|
||||||
|
#include "AI_ZF_Det.h"
|
||||||
|
#include "ImageMerge.h"
|
||||||
|
#include "QX_Merge_Analysis.h"
|
||||||
|
using namespace std;
|
||||||
|
using namespace cv;
|
||||||
|
// 相机处理类
|
||||||
|
class CameraCheckAnalysisy
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
CameraCheckAnalysisy();
|
||||||
|
~CameraCheckAnalysisy();
|
||||||
|
|
||||||
|
// 相机处理类 初始化
|
||||||
|
int Init(std::string strcameraName);
|
||||||
|
int StartCheck(std::shared_ptr<CameraResult> pCamera_Check_Result);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 开启线程
|
||||||
|
int StartThread();
|
||||||
|
// 停止线程
|
||||||
|
int StopThread();
|
||||||
|
|
||||||
|
// 初始化检测分析线程类
|
||||||
|
int InitCheckAnalysisy();
|
||||||
|
// 初始化其他
|
||||||
|
int InitRun();
|
||||||
|
// 设置新的检测参数
|
||||||
|
int SetNewConfig();
|
||||||
|
// 处理每张图片
|
||||||
|
int CheckImgRun();
|
||||||
|
|
||||||
|
int Run(); // 运行;
|
||||||
|
int set_cpu_id(const std::vector<int> &cpu_set_vec);
|
||||||
|
// 等待处理图片
|
||||||
|
int WaitDetImg();
|
||||||
|
|
||||||
|
// 预处理图片
|
||||||
|
int Detect_Pre();
|
||||||
|
|
||||||
|
// 处理每张图片
|
||||||
|
int Detect_Images();
|
||||||
|
|
||||||
|
// 结果参数分析
|
||||||
|
int ResultParamJudge();
|
||||||
|
|
||||||
|
int MergeResultAnalysisy(); // 合并结果分析
|
||||||
|
|
||||||
|
int UpdateConfigStatus();
|
||||||
|
// 结果参数分析
|
||||||
|
int ResultParamJudge_New();
|
||||||
|
|
||||||
|
// 边缘处理
|
||||||
|
int ImgEdge(std::shared_ptr<ImageAllResult> L255, ChannelCheckFunction *pFuntion_L255);
|
||||||
|
|
||||||
|
// 检测MarkLine
|
||||||
|
int Det_MarkLine(const cv::Mat &L255CutImg, std::shared_ptr<ImageAllResult> L255, Base_Function_MarkLine *pFuntion);
|
||||||
|
|
||||||
|
// 预处理 字符检测
|
||||||
|
int preDet_ZF(const cv::Mat &L255CutImg, std::shared_ptr<ImageAllResult> L255);
|
||||||
|
|
||||||
|
// 边缘处理
|
||||||
|
int ImgEdge(cv::Mat img, cv::Mat &detMaskImg, cv::Rect &roi, int productIdx);
|
||||||
|
|
||||||
|
// 插入相机日志
|
||||||
|
int InsertCameraLog();
|
||||||
|
|
||||||
|
ChannelCheckFunction *GetChannelFuntion(std::string strChannelName); // 获得 通道的检测功能
|
||||||
|
|
||||||
|
// 获取 检测核心库
|
||||||
|
ImgCheckBase *GetDealResult(int idx = -1);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// 运行的基本参数
|
||||||
|
RunInfoST m_RunConfig;
|
||||||
|
|
||||||
|
// 检测参数模块
|
||||||
|
std::shared_ptr<ConfigBase> m_pConfig;
|
||||||
|
int m_nConfigIdx;
|
||||||
|
|
||||||
|
// 检测分析参数
|
||||||
|
AnalysisyConfigST m_AnalysisyConfig;
|
||||||
|
CommonConfigNodeST *m_pCommonAnalysisyConfig;
|
||||||
|
ALLChannelCheckFunction *m_pChannelFuntion; // 画面检测功能
|
||||||
|
BaseCheckFunction *m_pbaseCheckFunction; // 基础检测
|
||||||
|
|
||||||
|
std::shared_ptr<DetLog> m_pdetlog;
|
||||||
|
|
||||||
|
// 结果分析类
|
||||||
|
ImageResultJudge m_imageResultJudge;
|
||||||
|
// 边缘检测模块集合
|
||||||
|
Edge_Search m_Edge_Search;
|
||||||
|
// Mark检测
|
||||||
|
AI_Mark_Det m_MarkDet;
|
||||||
|
|
||||||
|
// 字符检测
|
||||||
|
AI_ZF_Det m_ZF_Det;
|
||||||
|
|
||||||
|
ImageMerge m_ImageMerge;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 相机ID
|
||||||
|
std::string m_strcameraName;
|
||||||
|
|
||||||
|
int m_nErrorCode; // 错误代码
|
||||||
|
bool m_bInitSucc; // 初始化状态
|
||||||
|
bool m_bExit; // 是否退出检测
|
||||||
|
int nLastCheckAnalysisyThreadIdx;
|
||||||
|
// 图片处理线程
|
||||||
|
std::shared_ptr<std::thread> ptr_thread_Run;
|
||||||
|
|
||||||
|
std::shared_ptr<CameraResult> m_pCheck_Result;
|
||||||
|
|
||||||
|
bool m_bHaveImgeDet; // 是否有图片需要检查
|
||||||
|
std::mutex mtx_WaiteImg; // 等待图片的锁
|
||||||
|
std::condition_variable cond_WaiteImg; // 条件变量,是否有图片需要检查
|
||||||
|
|
||||||
|
std::string m_strRootPath_MergeImg;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 检测核心库
|
||||||
|
ImgCheckBase *m_pImgCheckAnalysisy[IMGCHECKANALYSISY_NUM];
|
||||||
|
|
||||||
|
CheckResultJson m_CheckResultJson;
|
||||||
|
std::shared_ptr<QX_Merge_Analysis> m_pQX_Merge_Analysis;
|
||||||
|
|
||||||
|
private:
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* @Author: your name
|
||||||
|
* @Date: 2022-04-20 15:49:50
|
||||||
|
* @LastEditTime: 2025-09-24 22:18:44
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
* @FilePath: /ZCXD_MonitorPlatform/src/CoreLogicModule/include/CamDeal.h
|
||||||
|
*/
|
||||||
|
#ifndef CameraResult_H_
|
||||||
|
#define CameraResult_H_
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
#include <thread>
|
||||||
|
#include <string>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "Define_Product.hpp"
|
||||||
|
#include "CheckErrorCodeDefine.hpp"
|
||||||
|
#include "ImgCheckConfig.h"
|
||||||
|
#include "ImageDetConfig.h"
|
||||||
|
#include "ImageAllResult.h"
|
||||||
|
#include "DetLog.h"
|
||||||
|
using namespace std;
|
||||||
|
using namespace cv;
|
||||||
|
class CameraResult
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
CameraResult(/* args */);
|
||||||
|
~CameraResult();
|
||||||
|
|
||||||
|
void AddLog(std::string str);
|
||||||
|
|
||||||
|
// 添加图片信息
|
||||||
|
int AddDetImage(std::shared_ptr<shareImage> p);
|
||||||
|
// 是否全部检测完成
|
||||||
|
bool bCheckCamplate();
|
||||||
|
|
||||||
|
// 设置 检测步骤
|
||||||
|
Check_Step GetCheckStep();
|
||||||
|
void SetCheckStep(Check_Step step);
|
||||||
|
|
||||||
|
// 送图是否全部完成
|
||||||
|
bool getImgPushComplate();
|
||||||
|
void setImgPushComplate();
|
||||||
|
|
||||||
|
bool IsHaveL255();
|
||||||
|
bool Have_EdgeImg(std::string strConfig_Channel); // 是否有边缘图片
|
||||||
|
void SetHaveL255(bool b);
|
||||||
|
|
||||||
|
bool IsHaveDP();
|
||||||
|
void SetHaveDP(bool b);
|
||||||
|
|
||||||
|
bool IsHaveUp();
|
||||||
|
void SetHaveUp(bool b);
|
||||||
|
|
||||||
|
// 返回一个未检测的 图片进行检测
|
||||||
|
std::shared_ptr<ImageAllResult> GetNoDetImg();
|
||||||
|
std::shared_ptr<ImageAllResult> GetL255DetImg();
|
||||||
|
std::shared_ptr<ImageAllResult> GetEdgeChannel(std::string strConfig_Channel);
|
||||||
|
long time_start;
|
||||||
|
bool bJson = false;
|
||||||
|
|
||||||
|
std::string m_config_EdgeChannel; // 边缘通道
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::vector<std::string> LogList;
|
||||||
|
std::shared_ptr<DetLog> detlog;
|
||||||
|
std::vector<std::shared_ptr<ImageAllResult>> ImageALLDetResultList; // 每个通道的检测结果 ,返回的结果。
|
||||||
|
std::shared_ptr<ProductBaseResult> productBaseResult;
|
||||||
|
std::shared_ptr<CameraBaseResult> cameraBaseResult;
|
||||||
|
|
||||||
|
|
||||||
|
// CameraImage_Status cameraImage_Status; // 图片状态
|
||||||
|
|
||||||
|
std::mutex mtx_Det; // 互斥量
|
||||||
|
private:
|
||||||
|
bool bIsImgComplete = false; // 图片是否都送完了。
|
||||||
|
Check_Step checkStep = Check_Step_NODet; // 检测步骤
|
||||||
|
PRINT_LOG_ m_PrintLog;
|
||||||
|
// 多线程安全
|
||||||
|
std::mutex mtx_DetImageList;
|
||||||
|
|
||||||
|
|
||||||
|
bool bHave_L255 = false;
|
||||||
|
bool bHave_DP = false;
|
||||||
|
bool bHave_Up = false;
|
||||||
|
bool bHave_EdgeImg = false; // 是否有边缘图片
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
//其他类的检测
|
||||||
|
*/
|
||||||
|
#ifndef CheckResultJson_H_
|
||||||
|
#define CheckResultJson_H_
|
||||||
|
#include <vector>
|
||||||
|
#include <thread>
|
||||||
|
#include "ImgCheckConfig.h"
|
||||||
|
#include "JsonCoversion.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "ImageDetConfig.h"
|
||||||
|
class CheckResultJson : public JsonCoversion
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CheckResultJson() {}
|
||||||
|
virtual ~CheckResultJson() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual Json::Value toJsonValue();
|
||||||
|
virtual void toObjectFromValue(Json::Value root);
|
||||||
|
int GetConfig(std::string strJson, std::shared_ptr<One_Image_CheckResult_> &pOneImgDetResult);
|
||||||
|
std::string GetResultString(std::shared_ptr<One_Image_CheckResult_> &pOneImgDetResult);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<One_Image_CheckResult_> m_pOneImgDetResult;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* @Descripttion:
|
||||||
|
* @version:
|
||||||
|
* @Author: sueRimn
|
||||||
|
* @Date: 2022-04-28 10:41:42
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @LastEditTime: 2025-08-03 21:32:02
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* FileName:CoreLogicFactory.hpp
|
||||||
|
* Version:V1.0
|
||||||
|
* Description:
|
||||||
|
* Created On:Mon Sep 10 11:13:13 UTC 2018
|
||||||
|
* Modified date:
|
||||||
|
* Author:Sky
|
||||||
|
*/
|
||||||
|
#ifndef _CheckUtil_HPP_
|
||||||
|
#define _CheckUtil_HPP_
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
#include <thread>
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
using namespace std;
|
||||||
|
class CheckUtil
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static long getcurTime();
|
||||||
|
static std::string getCurrentDate();
|
||||||
|
static std::string getCurTimeHMS();
|
||||||
|
static std::string Op_float2String(float nvalue);
|
||||||
|
static int64_t getSnowId();
|
||||||
|
static bool JudgRect(cv::Rect roi, int img_w, int img_h);
|
||||||
|
static bool JudgRect_SZ(cv::Rect roi, int w, int h);
|
||||||
|
static bool compareIgnoreCase(const std::string &str1, const std::string &str2);
|
||||||
|
static bool RoiInImg(cv::Rect roi, cv::Mat img);
|
||||||
|
static int printROI(cv::Rect roi, std::string str = "");
|
||||||
|
static float CalIoU(cv::Rect rect1, cv::Rect rect2);
|
||||||
|
static float CalIoU_t(cv::Rect rect1, cv::Rect rect2);
|
||||||
|
static int CheckRect(cv::Rect &roi, int img_w, int img_h);
|
||||||
|
static int SizeRect(cv::Rect &roi, int img_w, int img_h, int addw, int addh);
|
||||||
|
static int CalHj(const cv::Mat &img, const cv::Mat &mask, int b_value);
|
||||||
|
static int CalHj(const cv::Mat &img, const cv::Mat &mask, const cv::Mat &backgroundimg);
|
||||||
|
static float CalRoi2RoiPre(cv::Rect rect1, cv::Rect rect2);
|
||||||
|
// 计算平均灰度
|
||||||
|
static float CalImgBrightness(cv::Mat imgRoi);
|
||||||
|
// 计算角度
|
||||||
|
static float Cal2PointAngle(cv::Point p_left, cv::Point p_right);
|
||||||
|
|
||||||
|
// 找图片的最大外轮廓
|
||||||
|
static cv::Rect getLargestContourROI(const cv::Mat &binaryImg, bool &found);
|
||||||
|
|
||||||
|
static std::string GetRectString(cv::Rect rect);
|
||||||
|
// 创建目录
|
||||||
|
static int CreateDir(const std::string &dir);
|
||||||
|
|
||||||
|
// 点的距离是否过小
|
||||||
|
static bool bcalDis(cv::Point p1, cv::Point p2, int disT);
|
||||||
|
static double calDis(cv::Point2f p1, cv::Point2f p2);
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
template <typename... Args>
|
||||||
|
static std::string str_Format(const std::string &format, Args... args)
|
||||||
|
{
|
||||||
|
auto size_buf = std::snprintf(nullptr, 0, format.c_str(), args...) + 1;
|
||||||
|
std::unique_ptr<char[]> buf(new (std::nothrow) char[size_buf]);
|
||||||
|
|
||||||
|
if (!buf)
|
||||||
|
return std::string("");
|
||||||
|
|
||||||
|
std::snprintf(buf.get(), size_buf, format.c_str(), args...);
|
||||||
|
return std::string(buf.get(), buf.get() + size_buf - 1);
|
||||||
|
}
|
||||||
|
#endif //_CORELOGICFACTORY_HPP_
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
//定义整个系统基础的 定义 信息
|
||||||
|
*/
|
||||||
|
#ifndef Define_Base_H_
|
||||||
|
#define Define_Base_H_
|
||||||
|
#include <string>
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include "CheckUtil.hpp"
|
||||||
|
#include "ImgCheckConfig.h"
|
||||||
|
#include "ImageDetConfig.h"
|
||||||
|
#include "Define_Error.h"
|
||||||
|
|
||||||
|
// 检测分析线程类数目
|
||||||
|
#define IMGCHECKANALYSISY_NUM 4
|
||||||
|
|
||||||
|
// 相机ID 的相关定义
|
||||||
|
enum Camera_IDX
|
||||||
|
{
|
||||||
|
Camera_IDX_0 = 0,
|
||||||
|
Camera_IDX_1 = 1,
|
||||||
|
};
|
||||||
|
static const std::string strCameraName[] =
|
||||||
|
{
|
||||||
|
"left",
|
||||||
|
"right"};
|
||||||
|
struct Camera_Info
|
||||||
|
{
|
||||||
|
Camera_IDX camera_ID;
|
||||||
|
std::string camera_name;
|
||||||
|
Camera_Info()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
camera_ID = Camera_IDX_0;
|
||||||
|
camera_name = strCameraName[camera_ID];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static const std::string WebConfig_CameraName[] =
|
||||||
|
{
|
||||||
|
"C1",
|
||||||
|
"C2",
|
||||||
|
"C3"};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
//定义整个系统基础的 定义 信息
|
||||||
|
*/
|
||||||
|
#ifndef Define_Error_H_
|
||||||
|
#define Define_Error_H_
|
||||||
|
#include <string>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
enum ERRORCODEDEFINE
|
||||||
|
{
|
||||||
|
CHECK_OK,
|
||||||
|
CHECK_ERROR_VERSION, // 参数或接口版本问题
|
||||||
|
CHECK_ERROR_Config_Null, // 参数指针为空
|
||||||
|
CHECK_ERROR_Config_Value, // 参数值错误
|
||||||
|
CHECK_ERROR_Path_NULL, // 路径为空
|
||||||
|
CHECK_ERROR_Mask_Empty, // mask 图片为空
|
||||||
|
CHECK_ERROR_Config_cutRoi, // 参数的 roi 错误
|
||||||
|
CHECK_ERROR_CheckImg_Empty, // 检测 图片为空
|
||||||
|
CHECK_ERROR_PushImg_ListSize, // 送图错误 队列太长
|
||||||
|
CHECK_ERROR_PushImg_NoDetChannel, // 不检测通道
|
||||||
|
CHECK_ERROR_PushImg_Existing_ID, // ID 已存在
|
||||||
|
CHECK_ERROR_PushImg_ID_Error, // ID 错误
|
||||||
|
CHECK_ERROR_ID_Error, // ID 错误
|
||||||
|
CHECK_ERROR_L255_Empty, // L255 为空
|
||||||
|
CHECK_ERROR_L255_Edge_Fail, // L255 边界搜索失败
|
||||||
|
CHECK_ERROR_PRODUCT_ID_EXIST, // 产品 ID 已存在
|
||||||
|
CHECK_ERROR_Camear_ID_Error, // 相机ID 错误
|
||||||
|
INIT_CameraCheck_Error, // 初始化 相机处理类错误
|
||||||
|
};
|
||||||
|
static const std::string str_ErrorName[] =
|
||||||
|
{
|
||||||
|
"ok",
|
||||||
|
"ERROR_VERSION",
|
||||||
|
"Config_Null",
|
||||||
|
"Config_Value",
|
||||||
|
"Path_NULL",
|
||||||
|
"Mask_Empty",
|
||||||
|
"Config_cutRoi",
|
||||||
|
"CheckImg_Empty",
|
||||||
|
"PushImg_ListSize",
|
||||||
|
"PushImg_NoDetChannel",
|
||||||
|
"PushImg_Existing_ID",
|
||||||
|
"PushImg_ID_Error",
|
||||||
|
"ID_Error",
|
||||||
|
"L255_Empty",
|
||||||
|
"L255_Edge_Fail",
|
||||||
|
"L255_Empty",
|
||||||
|
"L255_Empty",
|
||||||
|
"PRODUCT_ID_EXIST",
|
||||||
|
"Camear_ID_Error",
|
||||||
|
"INIT_CameraCheck_Error"};
|
||||||
|
struct ErrorInfo
|
||||||
|
{
|
||||||
|
int nerror_code; // 错误代码
|
||||||
|
string strerror_msg; // 错误信息
|
||||||
|
ErrorInfo()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
nerror_code = CHECK_OK;
|
||||||
|
strerror_msg = str_ErrorName[CHECK_OK];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#ifndef Define_Product_HPP_
|
||||||
|
#define Define_Product_HPP_
|
||||||
|
#include "Define_Base.h"
|
||||||
|
#include "ImgCheckConfig.h"
|
||||||
|
|
||||||
|
// 相机的一些状态情况
|
||||||
|
struct CameraImage_Status
|
||||||
|
{
|
||||||
|
bool bImgComplete; /// 图片送完成了
|
||||||
|
bool bHaveImg; // 是否有图片
|
||||||
|
bool bHave_L255; // 是否有L55图片
|
||||||
|
bool bHave_DP; // 是否有DP图片
|
||||||
|
bool bhave_UP; // 是否有UP图片
|
||||||
|
bool bDetCutRoi; // 是否完成边缘检测
|
||||||
|
CameraImage_Status()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
bImgComplete = false;
|
||||||
|
bHaveImg = false;
|
||||||
|
bHave_L255 = false;
|
||||||
|
bHave_DP = false;
|
||||||
|
bhave_UP = false;
|
||||||
|
bDetCutRoi = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 处理状态
|
||||||
|
enum Check_Step
|
||||||
|
{
|
||||||
|
Check_Step_NODet = 0, // 未处理
|
||||||
|
Check_Step_PreDet, // 预处理
|
||||||
|
Check_Step_ImgeDet, // 图片处理
|
||||||
|
Check_Step_ResultParamJudg, // 结果参数判断
|
||||||
|
Check_Step_ImgeDet_End, // 图片检测完成
|
||||||
|
Check_Step_Complete, // 处理完成
|
||||||
|
Check_Step_COUNT,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* @Author: your name
|
||||||
|
* @Date: 2022-04-20 15:49:50
|
||||||
|
* @LastEditTime: 2025-09-16 22:35:59
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
* @FilePath: /ZCXD_MonitorPlatform/src/CoreLogicModule/include/CamDeal.h
|
||||||
|
*/
|
||||||
|
#ifndef DetLog_H_
|
||||||
|
#define DetLog_H_
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <vector>
|
||||||
|
#include "ImgCheckConfig.h"
|
||||||
|
#include "CheckErrorCodeDefine.hpp"
|
||||||
|
using namespace std;
|
||||||
|
enum PrintLevel_
|
||||||
|
{
|
||||||
|
PrintLevel_0,
|
||||||
|
PrintLevel_1,
|
||||||
|
PrintLevel_2,
|
||||||
|
PrintLevel_3,
|
||||||
|
PrintLevel_4,
|
||||||
|
};
|
||||||
|
template <typename... Args>
|
||||||
|
std::string str_Format_1(const std::string &format, Args... args)
|
||||||
|
{
|
||||||
|
// 先尝试用小缓冲
|
||||||
|
char buf[256];
|
||||||
|
int size = std::snprintf(buf, sizeof(buf), format.c_str(), args...);
|
||||||
|
|
||||||
|
if (size < 0)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
if (size < sizeof(buf))
|
||||||
|
{
|
||||||
|
return std::string(buf, size); // 直接返回
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 超过栈缓存时才用堆分配
|
||||||
|
std::vector<char> dynamic_buf(size + 1);
|
||||||
|
std::snprintf(dynamic_buf.data(), dynamic_buf.size(), format.c_str(), args...);
|
||||||
|
return std::string(dynamic_buf.data(), size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测过程临结果
|
||||||
|
struct DetLog
|
||||||
|
{
|
||||||
|
|
||||||
|
std::vector<std::string> logList;
|
||||||
|
bool bPrintStr; // 是否打印日志
|
||||||
|
int addLogLevel;
|
||||||
|
std::mutex mtx;
|
||||||
|
DetLog()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
logList.clear();
|
||||||
|
bPrintStr = false;
|
||||||
|
addLogLevel = DET_LOG_LEVEL_3;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
void AddCheckstr(PrintLevel_ step, std::string stepStr, const std::string &format, Args... args)
|
||||||
|
{
|
||||||
|
std::string str = "";
|
||||||
|
|
||||||
|
if (step <= PrintLevel_0)
|
||||||
|
{
|
||||||
|
str += ".. ";
|
||||||
|
}
|
||||||
|
else if (step == PrintLevel_1)
|
||||||
|
{
|
||||||
|
str += "..... ";
|
||||||
|
}
|
||||||
|
else if (step == PrintLevel_2)
|
||||||
|
{
|
||||||
|
str += "........ ";
|
||||||
|
}
|
||||||
|
else if (step == PrintLevel_3)
|
||||||
|
{
|
||||||
|
str += "........... ";
|
||||||
|
}
|
||||||
|
else if (step >= PrintLevel_4)
|
||||||
|
{
|
||||||
|
str += ".............. ";
|
||||||
|
}
|
||||||
|
str += stepStr + ": ";
|
||||||
|
str += str_Format_1(format, args...);
|
||||||
|
if (bPrintStr)
|
||||||
|
{
|
||||||
|
printf("%s\n", str.c_str());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mtx);
|
||||||
|
logList.push_back(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template <typename... Args>
|
||||||
|
void AddCheckstr(PrintLevel_ step, int LogLevel, std::string stepStr, const std::string &format, Args... args)
|
||||||
|
{
|
||||||
|
std::string str = "";
|
||||||
|
|
||||||
|
if (step <= PrintLevel_0)
|
||||||
|
{
|
||||||
|
str += ".. ";
|
||||||
|
}
|
||||||
|
else if (step == PrintLevel_1)
|
||||||
|
{
|
||||||
|
str += "..... ";
|
||||||
|
}
|
||||||
|
else if (step == PrintLevel_2)
|
||||||
|
{
|
||||||
|
str += "........ ";
|
||||||
|
}
|
||||||
|
else if (step == PrintLevel_3)
|
||||||
|
{
|
||||||
|
str += "........... ";
|
||||||
|
}
|
||||||
|
else if (step >= PrintLevel_4)
|
||||||
|
{
|
||||||
|
str += ".............. ";
|
||||||
|
}
|
||||||
|
str += stepStr + ": ";
|
||||||
|
str += str_Format_1(format, args...);
|
||||||
|
if (bPrintStr)
|
||||||
|
{
|
||||||
|
printf("%s\n", str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LogLevel <= addLogLevel)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mtx);
|
||||||
|
logList.push_back(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void printLog(std::string str)
|
||||||
|
{
|
||||||
|
printf("===========================%s==============================\n", str.c_str());
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mtx);
|
||||||
|
for (auto strl : logList)
|
||||||
|
{
|
||||||
|
printf("%s\n", strl.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("==========================================================\n");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* @Author: xiewenji 527774126@qq.com
|
||||||
|
* @Date: 2025-09-23 18:06:58
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @LastEditTime: 2025-09-25 10:19:29
|
||||||
|
* @FilePath: /BOE_POL_ET_Detect/AlgorithmModule/include/Edge_Search.h
|
||||||
|
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Edge_Search_H_
|
||||||
|
#define Edge_Search_H_
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
|
||||||
|
#include "CheckErrorCodeDefine.hpp"
|
||||||
|
#include "ImageDetConfig.h"
|
||||||
|
#include "CheckConfigDefine.h"
|
||||||
|
#include "AI_Edge_Algin.h"
|
||||||
|
using namespace std;
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
// 边缘缺陷检测
|
||||||
|
class Edge_Search
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// 检测参数和结果
|
||||||
|
struct DetConfigResult
|
||||||
|
{
|
||||||
|
Function_EdgeROI *pEdgeROI;
|
||||||
|
Function_Image_Align *pAlign;
|
||||||
|
std::shared_ptr<DetLog> pdetlog;
|
||||||
|
std::string strCamName;
|
||||||
|
|
||||||
|
bool bMode_Edge_test; // 是否是边缘测试模式
|
||||||
|
bool bDebugsaveImg; // 保存处理图片
|
||||||
|
DetConfigResult()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
bMode_Edge_test = false;
|
||||||
|
pEdgeROI = NULL;
|
||||||
|
pAlign = NULL;
|
||||||
|
pdetlog = NULL;
|
||||||
|
strCamName = "";
|
||||||
|
bDebugsaveImg = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
Edge_Search(/* args */);
|
||||||
|
~Edge_Search();
|
||||||
|
|
||||||
|
int Detect(const cv::Mat &detimg, DetConfigResult *pDetConfig, std::shared_ptr<EdgeDetResult> &pEdgeDetResult);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int Detect_AI(const cv::Mat &detimg, DetConfigResult *pDetConfig, std::shared_ptr<EdgeDetResult> &pEdgeDetResult);
|
||||||
|
int Detect_Draw(const cv::Mat &detimg, DetConfigResult *pDetConfig, std::shared_ptr<EdgeDetResult> &pEdgeDetResult);
|
||||||
|
int Detect_Search(const cv::Mat &detimg, DetConfigResult *pDetConfig, std::shared_ptr<EdgeDetResult> &pEdgeDetResult);
|
||||||
|
int SearchEdge(const cv::Mat &detimg, cv::Rect &roi, bool bsave);
|
||||||
|
|
||||||
|
// 特征定位
|
||||||
|
int Feature_Align(const cv::Mat &detimg, DetConfigResult *pDetConfig, std::shared_ptr<EdgeDetResult> &pEdgeDetResult);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<DetLog> m_pdetlog;
|
||||||
|
AI_Edge_Algin m_pAI_Edge_Algin;
|
||||||
|
// 图片特征定位
|
||||||
|
Image_Feature_Algin m_Image_Feature_Algin;
|
||||||
|
|
||||||
|
private:
|
||||||
|
cv::Mat showimg;
|
||||||
|
bool bshowimg;
|
||||||
|
|
||||||
|
double computeAverage(const std::vector<double> &data);
|
||||||
|
|
||||||
|
std::vector<double> removeOutliers(const std::vector<double> &data);
|
||||||
|
|
||||||
|
/// @brief
|
||||||
|
/// @param img 搜到图片 单通道
|
||||||
|
/// @param DirectSign 搜索方向 >0 正向,< 0 反向
|
||||||
|
/// @param Gate 阈值
|
||||||
|
/// @param BorW 搜索黑点 = 0还是白点 = 1
|
||||||
|
/// @param roi 搜索范围
|
||||||
|
/// @param StepCount 搜索点数
|
||||||
|
/// @param Limit 最小满是阈值点个数算上搜索成功
|
||||||
|
/// @return <0 搜索错误, >=0表示 搜索位置
|
||||||
|
int UDNoiseEdgeDetect(cv::Mat img, int DirectSign, int Gate, int BorW, cv::Rect roi, int StepCount, int Limit);
|
||||||
|
/// @brief
|
||||||
|
/// @param img 搜到图片 单通道
|
||||||
|
/// @param DirectSign 搜索方向 >0 正向,< 0 反向
|
||||||
|
/// @param Gate 阈值
|
||||||
|
/// @param BorW 搜索黑点 = 0还是白点 = 1
|
||||||
|
/// @param roi 搜索范围
|
||||||
|
/// @param StepCount 搜索点数
|
||||||
|
/// @param Limit 最小满是阈值点个数算上搜索成功
|
||||||
|
/// @return <0 搜索错误, >=0表示 搜索位置
|
||||||
|
int LRNoiseEdgeDetect(cv::Mat img, int DirectSign, int Gate, int BorW, cv::Rect roi, int StepCount, int Limit);
|
||||||
|
// int LRNoiseEdgeDetect(cv::Mat img,int DirectSign, int Gate,int BorW, int StartSearchSite, int Step, int StepCount, int top, int bottom, int Limit, int Depth, int MaxLimit);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
//图片基本处理
|
||||||
|
*/
|
||||||
|
#ifndef ImageResultJudge_H_
|
||||||
|
#define ImageResultJudge_H_
|
||||||
|
#include "CheckConfigDefine.h"
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
#include <thread>
|
||||||
|
#include <string>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include "Define_Base.h"
|
||||||
|
#include "ImgCheckBase.h"
|
||||||
|
#include "ImageDetBase.h"
|
||||||
|
#include "ImgCheckConfig.h"
|
||||||
|
#include "CheckErrorCodeDefine.hpp"
|
||||||
|
#include "ConfigBase.h"
|
||||||
|
#include "CheckConfigDefine.h"
|
||||||
|
#include "ImageDetConfig.h"
|
||||||
|
#include "Define_Product.hpp"
|
||||||
|
#include "CameraResult.h"
|
||||||
|
#include "DetLog.h"
|
||||||
|
#include "QX_Merge_Analysis.h"
|
||||||
|
class ImageResultJudge
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
enum DrawType
|
||||||
|
{
|
||||||
|
Draw_rect,
|
||||||
|
Draw_circle,
|
||||||
|
Draw_str,
|
||||||
|
};
|
||||||
|
struct txtDrawBackgroundk
|
||||||
|
{
|
||||||
|
std::vector<cv::Rect> txtDrawRoi;
|
||||||
|
cv::Rect findNonOverlappingPos(
|
||||||
|
const cv::Rect &newRect,
|
||||||
|
int step = 5,
|
||||||
|
int maxRadius = 800)
|
||||||
|
{
|
||||||
|
// 如果本身就不重叠,直接返回
|
||||||
|
bool overlap = false;
|
||||||
|
for (const auto &r : txtDrawRoi)
|
||||||
|
{
|
||||||
|
if ((newRect & r).area() > 0)
|
||||||
|
{
|
||||||
|
overlap = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!overlap)
|
||||||
|
return newRect;
|
||||||
|
// 螺旋搜索
|
||||||
|
for (int radius = step; radius <= maxRadius; radius += step)
|
||||||
|
{
|
||||||
|
for (int dx = -radius; dx <= radius; dx += step)
|
||||||
|
{
|
||||||
|
for (int dy = -radius; dy <= radius; dy += step)
|
||||||
|
{
|
||||||
|
cv::Rect candidate = newRect + cv::Point(dx, dy);
|
||||||
|
bool conflict = false;
|
||||||
|
for (const auto &r : txtDrawRoi)
|
||||||
|
{
|
||||||
|
if ((candidate & r).area() > 0)
|
||||||
|
{
|
||||||
|
conflict = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!conflict)
|
||||||
|
{
|
||||||
|
return candidate; // 找到合适位置
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("find fail ============= \n");
|
||||||
|
// 实在找不到,就返回原始位置
|
||||||
|
return newRect;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct DrawInfo
|
||||||
|
{
|
||||||
|
cv::Mat drawImg;
|
||||||
|
DrawType type = Draw_rect;
|
||||||
|
std::vector<std::string> strlist;
|
||||||
|
cv::Point txtP = cv::Point(0, 0);
|
||||||
|
cv::Rect roi = cv::Rect(0, 0, 0, 0);
|
||||||
|
cv::Scalar color = cv::Scalar(255, 0, 255);
|
||||||
|
cv::Point cp = cv::Point(0, 0);
|
||||||
|
int dr = 0;
|
||||||
|
float txtsize = 0.8;
|
||||||
|
std::shared_ptr<txtDrawBackgroundk> txtbackgroundk;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
ImageResultJudge(/* args */);
|
||||||
|
~ImageResultJudge();
|
||||||
|
|
||||||
|
int SetAnalysisyConfig(AnalysisyConfigST *pAnalysisyConfig);
|
||||||
|
int ResultJudge(std::shared_ptr<ImageAllResult> pImageResult);
|
||||||
|
int UpdateMergedet(std::shared_ptr<CameraResult> pCheck_Result);
|
||||||
|
|
||||||
|
int MergeResult(std::shared_ptr<ImageAllResult> pImageResult, QX_Analysis_Result_List *ptemre);
|
||||||
|
|
||||||
|
int UpdateConfig(std::string strcameraName);
|
||||||
|
int DrawResult(std::shared_ptr<ImageAllResult> pImageResult);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 获取 缺陷在参数列表的位置
|
||||||
|
int GetParamidx();
|
||||||
|
int UpdateImgageScale();
|
||||||
|
int SetInDetConfig(std::string strcameraName);
|
||||||
|
int SetMergeConfig(std::string strcameraName);
|
||||||
|
|
||||||
|
// 参数缺陷类型转 结果参数类型
|
||||||
|
int ConfigTypeToResultType(int nconfigType);
|
||||||
|
cv::Rect GetCutRoi(cv::Rect &roi, const cv::Mat &img);
|
||||||
|
// 获取缺陷 对应的AI输入 输出图片,
|
||||||
|
int GetAIDetImg(std::shared_ptr<ImageAllResult> pImageResult, cv::Point pcenter, cv::Mat &AI_InImg, cv::Mat &AI_OutImg);
|
||||||
|
|
||||||
|
int sendTask(std::shared_ptr<DrawInfo> task);
|
||||||
|
|
||||||
|
std::shared_ptr<ImageResultJudge::DrawInfo> GetTask();
|
||||||
|
|
||||||
|
void ThreadDraw();
|
||||||
|
int DrawResultTask(std::shared_ptr<ImageResultJudge::DrawInfo> task);
|
||||||
|
|
||||||
|
// 等待 绘制完成
|
||||||
|
int WaiteDrawComplate();
|
||||||
|
|
||||||
|
int AnalysisResult_Pre(QX_ERROR_INFO_ *QX_info); // 弱化处理
|
||||||
|
|
||||||
|
ChannelCheckFunction *GetChannelFuntion(std::string strChannelName); // 获得 通道的检测功能
|
||||||
|
|
||||||
|
int ConfigTypeToQXAnalysis(int nconfigType);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_bExit;
|
||||||
|
float m_fImgage_Scale_X = 0.1;
|
||||||
|
float m_fImgage_Scale_Y = 0.1;
|
||||||
|
// 检测分析参数
|
||||||
|
AnalysisyConfigST *m_pAnalysisyConfig;
|
||||||
|
CommonConfigNodeST *m_pCommonAnalysisyConfig;
|
||||||
|
ALLChannelCheckFunction *m_pChannelFuntion; // 画面检测功能
|
||||||
|
BaseCheckFunction *m_pbaseCheckFunction; // 基础检测
|
||||||
|
RegionConfigST *m_pRegionAnalysisyParam; // 分析参数
|
||||||
|
BasicConfig *m_pBasicConfig;
|
||||||
|
// 检查缺陷对应参数中的位置。
|
||||||
|
int m_QxInParamListIdx[CONFIG_QX_NAME_count];
|
||||||
|
|
||||||
|
std::queue<std::shared_ptr<DrawInfo>> m_DrawInfoList;
|
||||||
|
std::mutex m_task_mutex_;
|
||||||
|
std::condition_variable m_task_cv_;
|
||||||
|
std::shared_ptr<std::thread> ptr_thread_Draw;
|
||||||
|
std::condition_variable m_drawComplate_cv_;
|
||||||
|
|
||||||
|
std::shared_ptr<QX_Merge_Analysis> m_pQX_Merge_Analysis;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
#ifndef IMAGE_STORAGE_H
|
||||||
|
#define IMAGE_STORAGE_H
|
||||||
|
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <queue>
|
||||||
|
#include <thread>
|
||||||
|
#include <mutex>
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
|
class ImageStorage {
|
||||||
|
private:
|
||||||
|
std::queue<std::pair<cv::Mat, std::string>> imageQueue;
|
||||||
|
std::mutex queueMutex;
|
||||||
|
std::condition_variable cv;
|
||||||
|
std::thread storageThread;
|
||||||
|
|
||||||
|
static ImageStorage* instance; // 静态成员指针,存储单例对象
|
||||||
|
|
||||||
|
bool stopFlag;
|
||||||
|
|
||||||
|
// 私有构造函数和析构函数,防止外部创建实例
|
||||||
|
ImageStorage();
|
||||||
|
~ImageStorage();
|
||||||
|
|
||||||
|
// 存储线程的工作函数
|
||||||
|
void storeImages();
|
||||||
|
|
||||||
|
public:
|
||||||
|
// 获取单例实例
|
||||||
|
static ImageStorage* getInstance();
|
||||||
|
|
||||||
|
// 禁止拷贝构造和赋值
|
||||||
|
ImageStorage(const ImageStorage&) = delete;
|
||||||
|
ImageStorage& operator=(const ImageStorage&) = delete;
|
||||||
|
|
||||||
|
// 添加图片到队列
|
||||||
|
int addImage(const std::string &path,const cv::Mat &image,bool badd = false);
|
||||||
|
|
||||||
|
// 停止存储线程
|
||||||
|
void stop();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IMAGE_STORAGE_H
|
||||||
@ -0,0 +1,518 @@
|
|||||||
|
/*
|
||||||
|
* @Descripttion:
|
||||||
|
* @version:
|
||||||
|
* @Author: sueRimn
|
||||||
|
* @Date: 2022-03-16 17:09:11
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @LastEditTime: 2025-09-24 17:48:07
|
||||||
|
*/
|
||||||
|
/***********************************************/
|
||||||
|
/************ ***************/
|
||||||
|
/************金佰利检测算法参数定义**************/
|
||||||
|
/************ **************/
|
||||||
|
/**********************************************/
|
||||||
|
#ifndef _ImgCheckConfig_HPP_
|
||||||
|
#define _ImgCheckConfig_HPP_
|
||||||
|
#include <string>
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include <unordered_map> // unordered_map
|
||||||
|
#define RESULT_VERSION 31
|
||||||
|
|
||||||
|
#define MAX_BLOB_NUM 200
|
||||||
|
|
||||||
|
// 输入模型图片尺寸
|
||||||
|
#define SRCIMG_WIDTH 14200
|
||||||
|
#define SRCIMG_HEIGHT 10640
|
||||||
|
|
||||||
|
#define CHECKIMG_HEIGHT 2000
|
||||||
|
#define CHECKIMG_WIDTH 4000
|
||||||
|
|
||||||
|
#define MASK_IMG_STEP 16
|
||||||
|
#define MASK_IMG_STARTVALUE 48
|
||||||
|
|
||||||
|
// 检测日志 等级
|
||||||
|
enum DET_LOG_LEVEL_
|
||||||
|
{
|
||||||
|
DET_LOG_LEVEL_0, // 极简信息
|
||||||
|
DET_LOG_LEVEL_1, // 包含检测关键信息
|
||||||
|
DET_LOG_LEVEL_2, // 关键信息+ 一般节点信息
|
||||||
|
DET_LOG_LEVEL_3, // 详细信息
|
||||||
|
};
|
||||||
|
struct VERSION_INFO
|
||||||
|
{
|
||||||
|
int ConfigVersion = 0;
|
||||||
|
int ResultVersion = RESULT_VERSION;
|
||||||
|
int InterfaceVersion = 0;
|
||||||
|
};
|
||||||
|
// 检测错误代码
|
||||||
|
enum ERROR_TYPE_
|
||||||
|
{
|
||||||
|
ERROR_TYPE_OK, // 0 疑是
|
||||||
|
ERROR_TYPE_AD_YX, // 1 AD-异常显示
|
||||||
|
ERROR_TYPE_Line_X, // 2 x line
|
||||||
|
ERROR_TYPE_Line_Y, // 3 y line
|
||||||
|
ERROR_TYPE_Line_fangge, // 3 y line
|
||||||
|
ERROR_TYPE_Rubbing_Mura, // 4
|
||||||
|
ERROR_TYPE_line_Broken, // 5 断线
|
||||||
|
ERROR_TYPE_ZARA, // 6 ZARA
|
||||||
|
ERROR_TYPE_MTX, // 7 MTX
|
||||||
|
ERROR_TYPE_POL_Cell, // 8 异物
|
||||||
|
ERROR_TYPE_LD, // 9 亮点
|
||||||
|
ERROR_TYPE_AD, // 10 暗点
|
||||||
|
ERROR_TYPE_BD, // 11 黑点
|
||||||
|
ERROR_TYPE_WD, // 12 白点
|
||||||
|
ERROR_TYPE_Scratch, // 13 划伤
|
||||||
|
ERROR_TYPE_Weak_Bright_Mura, // 14 白GAP
|
||||||
|
ERROR_TYPE_No_Label, // 15 缺POL
|
||||||
|
ERROR_TYPE_PS, // 16 PS
|
||||||
|
ERROR_TYPE_GRID_LINE, // 17 方格线
|
||||||
|
ERROR_TYPE_STEAM_POCKET, // 19 气泡
|
||||||
|
ERROR_TYPE_Dirty, // 19 脏污
|
||||||
|
ERROR_TYPE_Other, // 19 other
|
||||||
|
ERROR_TYPE_Cell_W, // 19 other
|
||||||
|
ERROR_TYPE_Cell_B, // 19 other
|
||||||
|
ERROR_TYPE_LackPol, // 缺失Pol
|
||||||
|
ERROR_TYPE_COUNT,
|
||||||
|
};
|
||||||
|
static const std::string QX_Result_Names[] =
|
||||||
|
{
|
||||||
|
"OK",
|
||||||
|
"AD_YX",
|
||||||
|
"X_Line",
|
||||||
|
"Y_Line",
|
||||||
|
"fangge",
|
||||||
|
"Rubbing_Mura",
|
||||||
|
"Broken_line",
|
||||||
|
"ZARA",
|
||||||
|
"MTX",
|
||||||
|
"POL_Cell",
|
||||||
|
"Bright_Point",
|
||||||
|
"Dark_Point",
|
||||||
|
"BLack_Point",
|
||||||
|
"White_Point",
|
||||||
|
"Scratch",
|
||||||
|
"Weak_Bright_Mura",
|
||||||
|
"No_Label",
|
||||||
|
"Bright_Mura_Exe",
|
||||||
|
"Sweak_Line_Dark",
|
||||||
|
"STEAM_POCKET",
|
||||||
|
"Dirty",
|
||||||
|
"other",
|
||||||
|
"Cell_W",
|
||||||
|
"Cell_B",
|
||||||
|
"LackPol"};
|
||||||
|
static const std::string QX_Result_Code[] =
|
||||||
|
{
|
||||||
|
"P1153",
|
||||||
|
"P6873",
|
||||||
|
"P3351",
|
||||||
|
"P3452",
|
||||||
|
"P3453",
|
||||||
|
"P1550",
|
||||||
|
"P3379",
|
||||||
|
"P1153",
|
||||||
|
"P1164",
|
||||||
|
"P1101",
|
||||||
|
"P1112",
|
||||||
|
"P1111",
|
||||||
|
"P1104",
|
||||||
|
"P1103",
|
||||||
|
"P1557",
|
||||||
|
"P1654",
|
||||||
|
"P2833",
|
||||||
|
"P1549",
|
||||||
|
"P1204",
|
||||||
|
"P2534",
|
||||||
|
"P2534",
|
||||||
|
"P1101",
|
||||||
|
"P1103",
|
||||||
|
"P1104",
|
||||||
|
"P8001",
|
||||||
|
};
|
||||||
|
// 检测检测参数类型
|
||||||
|
enum CHECK_CONFIG_TYPE_
|
||||||
|
{
|
||||||
|
CHECK_CONFIG_Run, // 运行参数
|
||||||
|
CHECK_CONFIG_Module, // 参数模块
|
||||||
|
CHECK_CONFIG_COUNT,
|
||||||
|
};
|
||||||
|
// 输入检测图片的
|
||||||
|
enum IMG_INPUT_
|
||||||
|
{
|
||||||
|
IMG_INPUT_SRC,
|
||||||
|
IMG_INPUT_COUNT,
|
||||||
|
};
|
||||||
|
// 输入检测缺陷小图
|
||||||
|
enum IMG_OUTPUT_
|
||||||
|
{
|
||||||
|
IMG_OUTPUT_RESIZE,
|
||||||
|
IMG_OUTPUT_COUNT,
|
||||||
|
};
|
||||||
|
// 输入图片的状态
|
||||||
|
enum IN_IMG_Status_
|
||||||
|
{
|
||||||
|
IN_IMG_Status_Start,
|
||||||
|
IN_IMG_Status_Other,
|
||||||
|
IN_IMG_Status_End,
|
||||||
|
IN_IMG_Status_OneImg,
|
||||||
|
};
|
||||||
|
// 检测模式
|
||||||
|
enum DET_MODE_
|
||||||
|
{
|
||||||
|
DET_MODE_NULL,
|
||||||
|
DET_MODE_EDGE,
|
||||||
|
DET_MODE_MergeImg,
|
||||||
|
DET_MODE_ZF,
|
||||||
|
DET_MODE_YX,
|
||||||
|
DET_MODE_UP,
|
||||||
|
DET_MODE_Det,
|
||||||
|
DET_MODE_MarkLine,
|
||||||
|
DET_MODE_ReJson,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX_REGION_NUM 20
|
||||||
|
|
||||||
|
// 一个检测项基本信息,包括图片序号,图片、开始时间
|
||||||
|
struct shareImage
|
||||||
|
{
|
||||||
|
int Det_Mode; // 检测模式
|
||||||
|
int Status;
|
||||||
|
bool bmergeImg; /// 是否合并图片
|
||||||
|
int camera_ID; // 相机ID
|
||||||
|
int img_id;
|
||||||
|
cv::Mat img;
|
||||||
|
cv::Mat img_B;
|
||||||
|
cv::Mat other_channel_Result_mask;
|
||||||
|
cv::Mat AI_maskImg; // 推理图片
|
||||||
|
std::string strSnowID; // 相机发古来的雪花码
|
||||||
|
long getImgTimeMs; // 获取图片的时间点
|
||||||
|
long readImg_start;
|
||||||
|
long readImg_end;
|
||||||
|
long time_PushIn;
|
||||||
|
long time_sendCheck;
|
||||||
|
long time_startCheck;
|
||||||
|
long time_EndCheck;
|
||||||
|
int imgtype;
|
||||||
|
cv::Rect cutRoi;
|
||||||
|
|
||||||
|
int ninstruct; // 运行指令
|
||||||
|
int nlogLevel; // 日志等级
|
||||||
|
|
||||||
|
std::string strCameraName; // 相机名称
|
||||||
|
std::string strImgProductID; // 产品名称
|
||||||
|
std::string strChannel; // 通道名称
|
||||||
|
std::string strImgName; // 图片名称
|
||||||
|
std::string imgstr;
|
||||||
|
std::string strParm_WorkCamName; // 对应的界面参数 的工位相机名称。 ==等价于 相机管理的 CODE
|
||||||
|
|
||||||
|
int nImgBigIdx;
|
||||||
|
int otherValue;
|
||||||
|
int otherValue_1;
|
||||||
|
std::string resultJson; // 检测结果 json 字符串
|
||||||
|
bool bDebugsaveImg; // 保存处理图片
|
||||||
|
|
||||||
|
std::unordered_map<std::string, int> runCommand; // 运行命令 map
|
||||||
|
shareImage()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
~shareImage()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
if (!img.empty())
|
||||||
|
{
|
||||||
|
img.release();
|
||||||
|
}
|
||||||
|
if (!img_B.empty())
|
||||||
|
{
|
||||||
|
img_B.release();
|
||||||
|
}
|
||||||
|
if (!other_channel_Result_mask.empty())
|
||||||
|
{
|
||||||
|
other_channel_Result_mask.release();
|
||||||
|
}
|
||||||
|
if (!AI_maskImg.empty())
|
||||||
|
{
|
||||||
|
AI_maskImg.release();
|
||||||
|
}
|
||||||
|
Det_Mode = 0;
|
||||||
|
Status = 0;
|
||||||
|
nlogLevel = DET_LOG_LEVEL_0;
|
||||||
|
img_id = -1;
|
||||||
|
|
||||||
|
getImgTimeMs = 0;
|
||||||
|
time_PushIn = 0;
|
||||||
|
time_sendCheck = 0;
|
||||||
|
time_startCheck = 0;
|
||||||
|
time_EndCheck = 0;
|
||||||
|
readImg_start = 0;
|
||||||
|
readImg_end = 0;
|
||||||
|
imgtype = 0;
|
||||||
|
imgstr = "";
|
||||||
|
strSnowID = "";
|
||||||
|
camera_ID = 0;
|
||||||
|
strImgName = "";
|
||||||
|
strCameraName = "";
|
||||||
|
strImgProductID = "";
|
||||||
|
strChannel = "";
|
||||||
|
nImgBigIdx = 0;
|
||||||
|
cutRoi = cv::Rect(0, 0, 0, 0);
|
||||||
|
otherValue = 0;
|
||||||
|
ninstruct = 0;
|
||||||
|
resultJson = "";
|
||||||
|
strParm_WorkCamName = "";
|
||||||
|
bDebugsaveImg = false;
|
||||||
|
bmergeImg = false;
|
||||||
|
}
|
||||||
|
void InitImg(int ImgW, int imgH, bool Isgray = true)
|
||||||
|
{
|
||||||
|
if (Isgray)
|
||||||
|
{
|
||||||
|
img = cv::Mat(imgH, ImgW, CV_8UC1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
img = cv::Mat(imgH, ImgW, CV_8UC3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 检测结果基本信息
|
||||||
|
struct BasicResult
|
||||||
|
{
|
||||||
|
int img_id;
|
||||||
|
long checkUseTimeMs; // 所有时间
|
||||||
|
int64_t snowId; // 雪花ID
|
||||||
|
int imgtype;
|
||||||
|
std::string imgstr;
|
||||||
|
std::string strChannel;
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
img_id = 0;
|
||||||
|
checkUseTimeMs = 0;
|
||||||
|
snowId = 0;
|
||||||
|
imgtype = 0;
|
||||||
|
imgstr = "";
|
||||||
|
strChannel = "";
|
||||||
|
}
|
||||||
|
void copy(BasicResult tem)
|
||||||
|
{
|
||||||
|
this->img_id = tem.img_id;
|
||||||
|
this->checkUseTimeMs = tem.checkUseTimeMs;
|
||||||
|
this->snowId = tem.snowId;
|
||||||
|
this->imgtype = tem.imgtype;
|
||||||
|
this->imgstr = tem.imgstr;
|
||||||
|
this->strChannel = tem.strChannel;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DetectInfo
|
||||||
|
{
|
||||||
|
int nresult;
|
||||||
|
std::string keyName;
|
||||||
|
std::string keyCode;
|
||||||
|
int num;
|
||||||
|
DetectInfo()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
nresult = 0;
|
||||||
|
num = 0;
|
||||||
|
keyName = "";
|
||||||
|
keyCode = "";
|
||||||
|
}
|
||||||
|
void copy(DetectInfo tem)
|
||||||
|
{
|
||||||
|
this->nresult = tem.nresult;
|
||||||
|
this->num = tem.num;
|
||||||
|
this->keyName = tem.keyName;
|
||||||
|
this->keyCode = tem.keyCode;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QXImageResult
|
||||||
|
{
|
||||||
|
int type; // 缺陷类型
|
||||||
|
std::string qx_Code; // 缺陷code
|
||||||
|
std::string strTypeName; // 缺陷名称
|
||||||
|
|
||||||
|
cv::Mat srcImg; // 缺陷原始图片
|
||||||
|
cv::Mat resizeImg; // 缺陷缩略图
|
||||||
|
cv::Mat AI_in_Img;
|
||||||
|
cv::Mat AI_out_img;
|
||||||
|
|
||||||
|
cv::Rect srcImgroi; // 相对原图的 框坐标;
|
||||||
|
cv::Rect CutImgroi; // 裁剪原图 框坐标;
|
||||||
|
cv::Rect resizeImgroi; // 相对相对小图 框坐标;
|
||||||
|
|
||||||
|
float x_pixel; // 缺陷坐标 像素
|
||||||
|
float y_pixel; // 缺陷坐标 像素
|
||||||
|
|
||||||
|
float x_mm; // 缺陷坐标 mm
|
||||||
|
float y_mm; // 缺陷坐标 mm
|
||||||
|
int idx;
|
||||||
|
float area;
|
||||||
|
float energy;
|
||||||
|
float hj;
|
||||||
|
float max_v;
|
||||||
|
float len;
|
||||||
|
float fScore;
|
||||||
|
int qx_type; // 缺陷的原因
|
||||||
|
float minDis_mm;
|
||||||
|
int qx_num;
|
||||||
|
float density; // 密度
|
||||||
|
|
||||||
|
QXImageResult()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
if (!srcImg.empty())
|
||||||
|
{
|
||||||
|
srcImg.release();
|
||||||
|
}
|
||||||
|
if (!resizeImg.empty())
|
||||||
|
{
|
||||||
|
resizeImg.release();
|
||||||
|
}
|
||||||
|
if (!AI_in_Img.empty())
|
||||||
|
{
|
||||||
|
AI_in_Img.release();
|
||||||
|
/* code */
|
||||||
|
}
|
||||||
|
if (!AI_out_img.empty())
|
||||||
|
{
|
||||||
|
AI_out_img.release();
|
||||||
|
/* code */
|
||||||
|
}
|
||||||
|
|
||||||
|
x_pixel = 0;
|
||||||
|
y_pixel = 0;
|
||||||
|
x_mm = 0;
|
||||||
|
y_mm = 0;
|
||||||
|
type = 0;
|
||||||
|
area = 0;
|
||||||
|
energy = 0;
|
||||||
|
hj = 0;
|
||||||
|
max_v = 0;
|
||||||
|
strTypeName = "";
|
||||||
|
qx_Code = "";
|
||||||
|
len = 0;
|
||||||
|
idx = 0;
|
||||||
|
fScore = 0;
|
||||||
|
qx_type = 0;
|
||||||
|
minDis_mm = 0;
|
||||||
|
qx_num = 0;
|
||||||
|
density = 0;
|
||||||
|
srcImgroi = cv::Rect(0, 0, 0, 0);
|
||||||
|
CutImgroi = cv::Rect(0, 0, 0, 0);
|
||||||
|
resizeImgroi = cv::Rect(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 结果信息
|
||||||
|
struct CheckResult
|
||||||
|
{
|
||||||
|
// 原始图片,输入检测的图片
|
||||||
|
int checkStatus;
|
||||||
|
int nDetStep; // 处理步骤
|
||||||
|
int nresult;
|
||||||
|
int nProductResult; // 产品结果
|
||||||
|
int nYS_result;
|
||||||
|
float productWidht_mm; // 产品宽度 毫米
|
||||||
|
float productHeight_mm; // 产品 高度 毫米
|
||||||
|
cv::Mat cutSrcimg;
|
||||||
|
cv::Mat resultimg;
|
||||||
|
cv::Mat SrcResultImg; // 结果
|
||||||
|
cv::Mat resultMaskImg; // AI mask Result
|
||||||
|
std::shared_ptr<shareImage> in_shareImage; // 输入图片信息
|
||||||
|
DetectInfo defectResultList[ERROR_TYPE_COUNT]; // 缺陷检测结果list
|
||||||
|
BasicResult basicResult; // 基本检测结果信息
|
||||||
|
std::vector<QXImageResult> qxImageResult; // 缺陷小图结果
|
||||||
|
std::vector<QXImageResult> YS_ImageResult; // 疑似小图结果
|
||||||
|
std::vector<std::string> det_LogList; // 检测日志
|
||||||
|
std::string strResultJson; // 缺陷结果 jason
|
||||||
|
bool bSaveALL;
|
||||||
|
int nflage1;
|
||||||
|
int nflage2;
|
||||||
|
CheckResult()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
~CheckResult()
|
||||||
|
{
|
||||||
|
release();
|
||||||
|
}
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
nProductResult = 0;
|
||||||
|
checkStatus = 0;
|
||||||
|
nDetStep = 0;
|
||||||
|
nresult = ERROR_TYPE_OK;
|
||||||
|
nYS_result = ERROR_TYPE_OK;
|
||||||
|
bSaveALL = false;
|
||||||
|
nflage1 = 0;
|
||||||
|
nflage2 = 0;
|
||||||
|
productWidht_mm = 0;
|
||||||
|
productHeight_mm = 0;
|
||||||
|
basicResult.Init();
|
||||||
|
strResultJson = "";
|
||||||
|
if (!resultimg.empty())
|
||||||
|
{
|
||||||
|
resultimg.release();
|
||||||
|
}
|
||||||
|
if (!cutSrcimg.empty())
|
||||||
|
{
|
||||||
|
cutSrcimg.release();
|
||||||
|
}
|
||||||
|
if (!SrcResultImg.empty())
|
||||||
|
{
|
||||||
|
SrcResultImg.release();
|
||||||
|
}
|
||||||
|
if (!resultMaskImg.empty())
|
||||||
|
{
|
||||||
|
resultMaskImg.release();
|
||||||
|
}
|
||||||
|
for (int i = 0; i < ERROR_TYPE_COUNT; i++)
|
||||||
|
{
|
||||||
|
defectResultList[i].Init();
|
||||||
|
}
|
||||||
|
std::vector<QXImageResult> tmp;
|
||||||
|
qxImageResult.swap(tmp);
|
||||||
|
YS_ImageResult.swap(tmp);
|
||||||
|
qxImageResult.erase(qxImageResult.begin(), qxImageResult.end());
|
||||||
|
YS_ImageResult.erase(YS_ImageResult.begin(), YS_ImageResult.end());
|
||||||
|
det_LogList.erase(det_LogList.begin(), det_LogList.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void release()
|
||||||
|
{
|
||||||
|
if (!resultimg.empty())
|
||||||
|
{
|
||||||
|
resultimg.release();
|
||||||
|
}
|
||||||
|
if (!cutSrcimg.empty())
|
||||||
|
{
|
||||||
|
cutSrcimg.release();
|
||||||
|
}
|
||||||
|
if (!SrcResultImg.empty())
|
||||||
|
{
|
||||||
|
SrcResultImg.release();
|
||||||
|
}
|
||||||
|
if (!resultMaskImg.empty())
|
||||||
|
{
|
||||||
|
resultMaskImg.release();
|
||||||
|
}
|
||||||
|
strResultJson = "";
|
||||||
|
std::vector<QXImageResult> tmp;
|
||||||
|
qxImageResult.swap(tmp);
|
||||||
|
YS_ImageResult.swap(tmp);
|
||||||
|
det_LogList.erase(det_LogList.begin(), det_LogList.end());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //_CORELOGICFACTORY_HPP_
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* @Author: your name
|
||||||
|
* @Date: 2022-04-20 15:49:50
|
||||||
|
* @LastEditTime: 2025-09-17 18:57:39
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
* @FilePath: /ZCXD_MonitorPlatform/src/CoreLogicModule/include/CamDeal.h
|
||||||
|
*/
|
||||||
|
#ifndef OtherDetBaseDefine_H_
|
||||||
|
#define OtherDetBaseDefine_H_
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include "CheckErrorCodeDefine.hpp"
|
||||||
|
#include "BlobBase.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
struct OtherDet_Config
|
||||||
|
{
|
||||||
|
int nDeviceId; // GPU 号
|
||||||
|
int nUserValue;
|
||||||
|
int nShowImg_Width;
|
||||||
|
int nShowImg_Height;
|
||||||
|
|
||||||
|
OtherDet_Config()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
nDeviceId = 0;
|
||||||
|
nUserValue = 0;
|
||||||
|
nShowImg_Width = 100;
|
||||||
|
nShowImg_Height = 100;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
//其他类的检测
|
||||||
|
*/
|
||||||
|
#ifndef OtherDetect_H_
|
||||||
|
#define OtherDetect_H_
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include "CheckUtil.hpp"
|
||||||
|
#include "OtherDetBaseDefine.h"
|
||||||
|
#include "CheckErrorCodeDefine.hpp"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace cv;
|
||||||
|
// 基础类
|
||||||
|
class AIDetectBase
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
AIDetectBase(/* args */);
|
||||||
|
~AIDetectBase();
|
||||||
|
int Init(OtherDet_Config *pOtherDet_Config);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
OtherDet_Config *m_pOtherDet_Config;
|
||||||
|
|
||||||
|
bool m_bInitialized;
|
||||||
|
bool m_bModelSucc;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 缺pol 检测
|
||||||
|
class LackPolDet : public AIDetectBase
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// @brief 检测过程的参数
|
||||||
|
struct DetConfig
|
||||||
|
{
|
||||||
|
float fImgage_Scale_X;
|
||||||
|
float fImgage_Scale_Y;
|
||||||
|
bool bSaveResultImg; // 保存结果图片
|
||||||
|
std::string strChannel; // 通道名称
|
||||||
|
cv::Mat detMaskImg; // 检测区域图片
|
||||||
|
DetConfig()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
fImgage_Scale_X = 0.03f;
|
||||||
|
fImgage_Scale_Y = 0.03f;
|
||||||
|
bSaveResultImg = false;
|
||||||
|
strChannel = "";
|
||||||
|
}
|
||||||
|
void Print()
|
||||||
|
{
|
||||||
|
printf("bSaveResultImg %s strChannel %s\n",
|
||||||
|
BOOL_TO_STR(bSaveResultImg), strChannel.c_str());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
LackPolDet(/* args */);
|
||||||
|
~LackPolDet();
|
||||||
|
int InitModel_ALL();
|
||||||
|
int Detect(const cv::Mat &img, DetConfig *pDetConfig, cv::Mat &outMask);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int Init_LackPol();
|
||||||
|
|
||||||
|
public:
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* @Author: your name
|
||||||
|
* @Date: 2022-04-20 15:49:50
|
||||||
|
* @LastEditTime: 2025-09-16 21:19:45
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
* @FilePath: /ZCXD_MonitorPlatform/src/CoreLogicModule/include/CamDeal.h
|
||||||
|
*/
|
||||||
|
#ifndef Product_H_
|
||||||
|
#define Product_H_
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
#include <thread>
|
||||||
|
#include <string>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "Define_Product.hpp"
|
||||||
|
#include "CameraResult.h"
|
||||||
|
#include "CheckErrorCodeDefine.hpp"
|
||||||
|
#include "ImageDetConfig.h"
|
||||||
|
using namespace std;
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
class Product
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/* data */
|
||||||
|
public:
|
||||||
|
Product(/* args */);
|
||||||
|
~Product();
|
||||||
|
|
||||||
|
std::shared_ptr<CameraResult> GetCameraResult(std::string strcameraName);
|
||||||
|
void AddLog(std::string str);
|
||||||
|
// 更新 送图状态
|
||||||
|
void UpdatePushStatus(int status);
|
||||||
|
|
||||||
|
// 是否全部检测完成
|
||||||
|
bool bCheckCamplate();
|
||||||
|
|
||||||
|
public:
|
||||||
|
// 相机结果
|
||||||
|
std::vector<std::shared_ptr<CameraResult>> m_pCameraResultList;
|
||||||
|
std::shared_ptr<ProductBaseResult> productBaseResult;
|
||||||
|
// 图片是否都送完了。
|
||||||
|
bool bIsImgComplete = false;
|
||||||
|
// 日志
|
||||||
|
std::vector<std::string> LogList;
|
||||||
|
std::mutex mtx_CameraResultList;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::mutex mtx_;
|
||||||
|
// 多线程安全
|
||||||
|
|
||||||
|
PRINT_LOG_ m_PrintLog;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
//实现对部分缺陷 需要进行 数量 和距离上分析的
|
||||||
|
*/
|
||||||
|
#ifndef QX_Merge_Analysis_H_
|
||||||
|
#define QX_Merge_Analysis_H_
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include "CheckUtil.hpp"
|
||||||
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include "CheckErrorCodeDefine.hpp"
|
||||||
|
#include "CheckConfigDefine.h"
|
||||||
|
#include "QX_Analysis.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
#define QX_MEREGE_CONFIG_CAMERA_NAME "left"
|
||||||
|
|
||||||
|
class QX_Merge_Analysis
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum RUN_STATUS_
|
||||||
|
{
|
||||||
|
RUN_STATUS_NULL,
|
||||||
|
RUN_STATUS_IDLE,
|
||||||
|
RUN_STATUS_READY,
|
||||||
|
RUN_STATUS_BUSY,
|
||||||
|
RUN_STATUS_COMPLETE,
|
||||||
|
};
|
||||||
|
struct tem_AD_QX_Info
|
||||||
|
{
|
||||||
|
int qxidx = 0;
|
||||||
|
int channelidx = 0;
|
||||||
|
};
|
||||||
|
struct AD_Channel_Info_
|
||||||
|
{
|
||||||
|
cv::Rect roi;
|
||||||
|
cv::Point2f location_product_mm;
|
||||||
|
int num;
|
||||||
|
float fdis;
|
||||||
|
int dist_idx;
|
||||||
|
int num_2s;
|
||||||
|
int num_3s;
|
||||||
|
int num_1s;
|
||||||
|
vector<tem_AD_QX_Info> numIdxList;
|
||||||
|
vector<tem_AD_QX_Info> num_2sIdxList;
|
||||||
|
vector<tem_AD_QX_Info> num_3sIdxList;
|
||||||
|
AD_Channel_Info_()
|
||||||
|
{
|
||||||
|
roi = cv::Rect(0, 0, 0, 0);
|
||||||
|
location_product_mm = cv::Point2f(0, 0);
|
||||||
|
num = 0;
|
||||||
|
fdis = 999999999999;
|
||||||
|
dist_idx = 0;
|
||||||
|
num_1s = 0;
|
||||||
|
num_2s = 0;
|
||||||
|
num_3s = 0;
|
||||||
|
numIdxList.clear();
|
||||||
|
num_2sIdxList.clear();
|
||||||
|
num_3sIdxList.clear();
|
||||||
|
}
|
||||||
|
std::string GetInfo()
|
||||||
|
{
|
||||||
|
char buffer[256];
|
||||||
|
sprintf(buffer, "roi:[%d,%d,%d,%d] location [%f %f]num:%d fdis:%.2f dist_idx:%d num_1s:%d num_2s:%d num_3s:%d",
|
||||||
|
roi.x, roi.y, roi.width, roi.height, location_product_mm.x, location_product_mm.y,
|
||||||
|
num, fdis, dist_idx, num_1s, num_2s, num_3s);
|
||||||
|
return std::string(buffer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
QX_Merge_Analysis();
|
||||||
|
~QX_Merge_Analysis();
|
||||||
|
static std::shared_ptr<QX_Merge_Analysis> GetInstance();
|
||||||
|
|
||||||
|
int Clear();
|
||||||
|
int AddCamer(std::string cameraName);
|
||||||
|
|
||||||
|
int InitData();
|
||||||
|
|
||||||
|
int GetReusult(QX_Analysis_Result_List *&presult);
|
||||||
|
|
||||||
|
void SetConfig(std::string cameraName, int qxidx, QXAnalysis_Config config);
|
||||||
|
void InitConfig(std::string cameraName);
|
||||||
|
void SetbaseCheckFunction(std::string cameraName, ALLChannelCheckFunction *pChannelFuntion, BaseCheckFunction *pbaseCheckFunction);
|
||||||
|
|
||||||
|
int ConfigTypeToQXAnalysis(int nconfigType);
|
||||||
|
bool Idx(int qxidx);
|
||||||
|
bool AddQxInfo(int qxidx, QX_Info qxinfo, std::shared_ptr<DetLog> plog, std::shared_ptr<DetLog> pchannelLog);
|
||||||
|
|
||||||
|
bool setSendStatus(std::string cameraName, RUN_STATUS_ status);
|
||||||
|
|
||||||
|
bool waitComplete(int timeoutMs = 15000);
|
||||||
|
std::shared_ptr<DetLog> m_pMergedetlog;
|
||||||
|
|
||||||
|
ALLChannelCheckFunction *m_pChannelFuntion;
|
||||||
|
BaseCheckFunction *m_pbaseCheckFunction;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<std::thread>
|
||||||
|
ptr_thread_Run;
|
||||||
|
int Run(int nId); // 运行;
|
||||||
|
|
||||||
|
// 开启线程
|
||||||
|
int StartThread(int nId);
|
||||||
|
// 停止线程
|
||||||
|
int StopThread();
|
||||||
|
|
||||||
|
int StartAnalysis();
|
||||||
|
|
||||||
|
int Analysis_single_Config(QXAnalysis_Config *pconfig, QX_channel_List *pqxList, int qx_type, std::shared_ptr<DetLog> pchannelLog);
|
||||||
|
|
||||||
|
int Analysis_QXtype(ALL_Qx_DataList *pALLTypeqxList, int qx_idx);
|
||||||
|
int Analysis_Channel(QX_channel_List *pChannelqxList, int qx_idx);
|
||||||
|
int Judge_OK_Config();
|
||||||
|
int Judge_NG_Config();
|
||||||
|
|
||||||
|
int Analysis_AD(ALL_Qx_DataList *pALLTypeqxList, int qx_idx);
|
||||||
|
|
||||||
|
ChannelCheckFunction *GetChannelFuntion(std::string strChannelName);
|
||||||
|
|
||||||
|
double DistanceBetweenRectCenters(const cv::Rect &rect1, const cv::Rect &rect2, float fx, float fy);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ALL_Qx_DataList m_QXList[QX_ANALYSIS_COUNT];
|
||||||
|
ALL_QX_ParamList m_ConfigList[QX_ANALYSIS_COUNT];
|
||||||
|
|
||||||
|
std::mutex mtx_QXList;
|
||||||
|
std::mutex mtx_ConfigList;
|
||||||
|
|
||||||
|
std::mutex mtx_status;
|
||||||
|
std::condition_variable cv_status;
|
||||||
|
RUN_STATUS_ m_status;
|
||||||
|
std::unordered_map<std::string, RUN_STATUS_> m_statusList;
|
||||||
|
std::unordered_map<std::string, std::shared_ptr<DetLog>> m_pdetlogList;
|
||||||
|
|
||||||
|
QX_Analysis_Result_List m_reultList;
|
||||||
|
|
||||||
|
bool m_bExit; // 是否退出检测
|
||||||
|
|
||||||
|
std::vector<AD_Channel_Info_> AD_list;
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* @Author: your name
|
||||||
|
* @Date: 2022-04-20 15:49:50
|
||||||
|
* @LastEditTime: 2025-09-16 10:14:05
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
* @FilePath: /ZCXD_MonitorPlatform/src/CoreLogicModule/include/CamDeal.h
|
||||||
|
*/
|
||||||
|
#ifndef Task_H_
|
||||||
|
#define Task_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include <thread>
|
||||||
|
#include <mutex>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <queue>
|
||||||
|
#include <vector>
|
||||||
|
#include <atomic>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
enum TaskName
|
||||||
|
{
|
||||||
|
Task_AI,
|
||||||
|
Task_AI_Other,
|
||||||
|
Task_Class,
|
||||||
|
Task_Count,
|
||||||
|
};
|
||||||
|
enum TaskStep
|
||||||
|
{
|
||||||
|
TaskStep_Idle,
|
||||||
|
TaskStep_Waite,
|
||||||
|
TaskStep_run,
|
||||||
|
TaskStep_compate,
|
||||||
|
};
|
||||||
|
struct TaskInfo
|
||||||
|
{
|
||||||
|
TaskName taskname;
|
||||||
|
TaskStep status; // 运行状态
|
||||||
|
int nresult; // 运行结果
|
||||||
|
|
||||||
|
// 🔑 新增变量
|
||||||
|
std::mutex mtx;
|
||||||
|
std::condition_variable cv;
|
||||||
|
|
||||||
|
// 设置状态,线程安全
|
||||||
|
void SetStatus(TaskStep newStatus)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mtx);
|
||||||
|
status = newStatus;
|
||||||
|
}
|
||||||
|
cv.notify_all(); // 通知等待者
|
||||||
|
}
|
||||||
|
bool isComplate()
|
||||||
|
{
|
||||||
|
bool bcom = false;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mtx);
|
||||||
|
if (status == TaskStep_compate)
|
||||||
|
{
|
||||||
|
bcom = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bcom;
|
||||||
|
}
|
||||||
|
// 等待任务完成
|
||||||
|
void waitComplate()
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(mtx);
|
||||||
|
cv.wait(lock, [this]
|
||||||
|
{ return status == TaskStep_compate; });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class Task
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Task();
|
||||||
|
~Task();
|
||||||
|
int sendTask(std::shared_ptr<TaskInfo> task);
|
||||||
|
std::shared_ptr<TaskInfo> GetTask();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::queue<std::shared_ptr<TaskInfo>> m_tasks_;
|
||||||
|
std::mutex m_task_mutex_;
|
||||||
|
std::condition_variable m_task_cv_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
private:
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,106 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <cstdint>
|
||||||
|
#include <chrono>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
class snowflake_nonlock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void lock()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void unlock()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<int64_t Twepoch, typename Lock = snowflake_nonlock>
|
||||||
|
class snowflake
|
||||||
|
{
|
||||||
|
using lock_type = Lock;
|
||||||
|
static constexpr int64_t TWEPOCH = Twepoch;
|
||||||
|
static constexpr int64_t WORKER_ID_BITS = 5L;
|
||||||
|
static constexpr int64_t DATACENTER_ID_BITS = 5L;
|
||||||
|
static constexpr int64_t MAX_WORKER_ID = (1 << WORKER_ID_BITS) - 1;
|
||||||
|
static constexpr int64_t MAX_DATACENTER_ID = (1 << DATACENTER_ID_BITS) - 1;
|
||||||
|
static constexpr int64_t SEQUENCE_BITS = 12L;
|
||||||
|
static constexpr int64_t WORKER_ID_SHIFT = SEQUENCE_BITS;
|
||||||
|
static constexpr int64_t DATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;
|
||||||
|
static constexpr int64_t TIMESTAMP_LEFT_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATACENTER_ID_BITS;
|
||||||
|
static constexpr int64_t SEQUENCE_MASK = (1 << SEQUENCE_BITS) - 1;
|
||||||
|
|
||||||
|
using time_point = std::chrono::time_point<std::chrono::steady_clock>;
|
||||||
|
|
||||||
|
time_point start_time_point_ = std::chrono::steady_clock::now();
|
||||||
|
int64_t start_millsecond_ = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
||||||
|
|
||||||
|
int64_t last_timestamp_ = -1;
|
||||||
|
int64_t workerid_ = 0;
|
||||||
|
int64_t datacenterid_ = 0;
|
||||||
|
int64_t sequence_ = 0;
|
||||||
|
lock_type lock_;
|
||||||
|
public:
|
||||||
|
snowflake() = default;
|
||||||
|
|
||||||
|
snowflake(const snowflake&) = delete;
|
||||||
|
|
||||||
|
snowflake& operator=(const snowflake&) = delete;
|
||||||
|
|
||||||
|
void init(int64_t workerid, int64_t datacenterid)
|
||||||
|
{
|
||||||
|
if (workerid > MAX_WORKER_ID || workerid < 0) {
|
||||||
|
throw std::runtime_error("worker Id can't be greater than 31 or less than 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (datacenterid > MAX_DATACENTER_ID || datacenterid < 0) {
|
||||||
|
throw std::runtime_error("datacenter Id can't be greater than 31 or less than 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
workerid_ = workerid;
|
||||||
|
datacenterid_ = datacenterid;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t nextid()
|
||||||
|
{
|
||||||
|
std::lock_guard<lock_type> lock(lock_);
|
||||||
|
//std::chrono::steady_clock cannot decrease as physical time moves forward
|
||||||
|
auto timestamp = millsecond();
|
||||||
|
if (last_timestamp_ == timestamp)
|
||||||
|
{
|
||||||
|
sequence_ = (sequence_ + 1)&SEQUENCE_MASK;
|
||||||
|
if (sequence_ == 0)
|
||||||
|
{
|
||||||
|
timestamp = wait_next_millis(last_timestamp_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sequence_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_timestamp_ = timestamp;
|
||||||
|
|
||||||
|
return ((timestamp - TWEPOCH) << TIMESTAMP_LEFT_SHIFT)
|
||||||
|
| (datacenterid_ << DATACENTER_ID_SHIFT)
|
||||||
|
| (workerid_ << WORKER_ID_SHIFT)
|
||||||
|
| sequence_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int64_t millsecond() const noexcept
|
||||||
|
{
|
||||||
|
auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time_point_);
|
||||||
|
return start_millsecond_ + diff.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t wait_next_millis(int64_t last) const noexcept
|
||||||
|
{
|
||||||
|
auto timestamp = millsecond();
|
||||||
|
while (timestamp <= last)
|
||||||
|
{
|
||||||
|
timestamp = millsecond();
|
||||||
|
}
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,358 @@
|
|||||||
|
|
||||||
|
#include "AIClassify.h"
|
||||||
|
#include "AICommonDefine.h"
|
||||||
|
bool compare_Piece(const AI_PIECE_INFO &a, const AI_PIECE_INFO &b)
|
||||||
|
{
|
||||||
|
return a.abs_L < b.abs_L;
|
||||||
|
}
|
||||||
|
AIClassify::AIClassify()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AIClassify::~AIClassify()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Rect AIClassify::GetCutRoi(cv::Rect roi, const cv::Mat &img, int nwidth, int nheight)
|
||||||
|
{
|
||||||
|
|
||||||
|
cv::Rect cutroi;
|
||||||
|
int pc_x = roi.x + roi.width * 0.5;
|
||||||
|
int pc_y = roi.y + roi.height * 0.5;
|
||||||
|
bool bresize = false;
|
||||||
|
if (roi.width < nwidth && roi.height < nheight)
|
||||||
|
{
|
||||||
|
cutroi.width = nwidth;
|
||||||
|
cutroi.x = pc_x - nwidth * 0.5;
|
||||||
|
cutroi.height = nheight;
|
||||||
|
cutroi.y = pc_y - nheight * 0.5;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 宽 高
|
||||||
|
if (roi.width > roi.height)
|
||||||
|
{
|
||||||
|
cutroi.width = roi.width + 20;
|
||||||
|
cutroi.x = roi.x - 10;
|
||||||
|
|
||||||
|
float fsx = nheight * 1.0f / nwidth;
|
||||||
|
cutroi.height = cutroi.width * fsx;
|
||||||
|
cutroi.y = pc_y - cutroi.height * 0.5;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cutroi.height = roi.height + 20;
|
||||||
|
cutroi.y = roi.y - 10;
|
||||||
|
|
||||||
|
float fsy = nwidth * 1.0f / nheight;
|
||||||
|
cutroi.width = cutroi.height * fsy;
|
||||||
|
cutroi.x = pc_x - cutroi.width * 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
bresize = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cutroi.x < 0)
|
||||||
|
{
|
||||||
|
cutroi.x = 0;
|
||||||
|
}
|
||||||
|
if (cutroi.y < 0)
|
||||||
|
{
|
||||||
|
cutroi.y = 0;
|
||||||
|
}
|
||||||
|
if (cutroi.x + cutroi.width >= img.cols)
|
||||||
|
{
|
||||||
|
cutroi.x = img.cols - cutroi.width;
|
||||||
|
if (cutroi.x < 0)
|
||||||
|
{
|
||||||
|
cutroi.x = 0;
|
||||||
|
if (cutroi.x + cutroi.width >= img.cols)
|
||||||
|
{
|
||||||
|
cutroi.width = img.cols;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cutroi.y + cutroi.height >= img.rows)
|
||||||
|
{
|
||||||
|
cutroi.y = img.rows - cutroi.height;
|
||||||
|
if (cutroi.y < 0)
|
||||||
|
{
|
||||||
|
cutroi.y = 0;
|
||||||
|
if (cutroi.y + cutroi.height >= img.rows)
|
||||||
|
{
|
||||||
|
cutroi.height = img.rows;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cutroi;
|
||||||
|
}
|
||||||
|
int AIClassify::GetDetRoiList(const cv::Mat &src_Img, cv::Rect qx_roi, std::vector<cv::Rect> &samllRoiList, int nwidth, int nheight)
|
||||||
|
{
|
||||||
|
|
||||||
|
// qx_roi.x = 10;
|
||||||
|
// qx_roi.y = src_Img.rows - 10;
|
||||||
|
// qx_roi.width = src_Img.rows - 150;
|
||||||
|
// qx_roi.height = 8;
|
||||||
|
|
||||||
|
int Min_SizeWH = 160;
|
||||||
|
int Max_sizeWH = 400;
|
||||||
|
// 块之间重叠度
|
||||||
|
int overlap = 100;
|
||||||
|
// 单边的块数最多
|
||||||
|
int Edge_Piece_single_Num = 7;
|
||||||
|
// 总的块数最多支持 9个。
|
||||||
|
int Edge_Piece_Sum_Num = 9;
|
||||||
|
|
||||||
|
int qx_w = qx_roi.width;
|
||||||
|
int qx_h = qx_roi.height;
|
||||||
|
// 长边、短边
|
||||||
|
int long_side = qx_w;
|
||||||
|
int short_side = qx_h;
|
||||||
|
if (qx_w >= qx_h)
|
||||||
|
{
|
||||||
|
long_side = qx_w;
|
||||||
|
short_side = qx_h;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
long_side = qx_h;
|
||||||
|
short_side = qx_w;
|
||||||
|
}
|
||||||
|
// printf("img %d %d qx %d %d \n", src_Img.cols, src_Img.rows, long_side, short_side);
|
||||||
|
std::vector<AI_PIECE_INFO> pieceList;
|
||||||
|
if (long_side <= Min_SizeWH)
|
||||||
|
{
|
||||||
|
AI_PIECE_INFO tem;
|
||||||
|
tem.len = long_side;
|
||||||
|
tem.num = 1;
|
||||||
|
tem.long_num = 1;
|
||||||
|
tem.short_num = 1;
|
||||||
|
tem.abs_L = 0;
|
||||||
|
|
||||||
|
pieceList.push_back(tem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
// 1、从长边开始计算
|
||||||
|
for (int i = 1; i <= Edge_Piece_single_Num; i++)
|
||||||
|
{
|
||||||
|
int piece_len = std::ceil(long_side * 1.0f / i);
|
||||||
|
int piece_overlap_len = std::ceil(piece_len + (i - 1) / i * overlap);
|
||||||
|
int long_Piece_Num = i;
|
||||||
|
int short_Piece_Num = std::ceil(short_side * 1.0f / piece_overlap_len);
|
||||||
|
int sum_Piece_Num = long_Piece_Num * short_Piece_Num;
|
||||||
|
|
||||||
|
// printf("piece size %d %d long Num %d short Num %d sum %d \n", piece_len, piece_overlap_len, long_Piece_Num, short_Piece_Num, sum_Piece_Num);
|
||||||
|
if (sum_Piece_Num > Edge_Piece_Sum_Num)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AI_PIECE_INFO tem;
|
||||||
|
tem.len = piece_overlap_len;
|
||||||
|
tem.num = sum_Piece_Num;
|
||||||
|
tem.long_num = long_Piece_Num;
|
||||||
|
tem.short_num = short_Piece_Num;
|
||||||
|
tem.abs_L = std::abs(piece_overlap_len - Max_sizeWH);
|
||||||
|
|
||||||
|
pieceList.push_back(tem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::sort(pieceList.begin(), pieceList.end(), compare_Piece);
|
||||||
|
|
||||||
|
// for (int i = 0; i < pieceList.size(); i++)
|
||||||
|
// {
|
||||||
|
// pieceList.at(i).print(std::to_string(i));
|
||||||
|
// }
|
||||||
|
if (pieceList.size() <= 0)
|
||||||
|
{
|
||||||
|
printf("Select Roi fail\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
AI_PIECE_INFO selectPiece;
|
||||||
|
selectPiece.len = pieceList.at(0).len;
|
||||||
|
selectPiece.num = pieceList.at(0).num;
|
||||||
|
selectPiece.long_num = pieceList.at(0).long_num;
|
||||||
|
selectPiece.short_num = pieceList.at(0).short_num;
|
||||||
|
selectPiece.abs_L = pieceList.at(0).abs_L;
|
||||||
|
// selectPiece.print("select");
|
||||||
|
|
||||||
|
int W_Piece_Num = selectPiece.long_num;
|
||||||
|
int H_Piece_Num = selectPiece.short_num;
|
||||||
|
if (qx_w >= qx_h)
|
||||||
|
{
|
||||||
|
W_Piece_Num = selectPiece.long_num;
|
||||||
|
H_Piece_Num = selectPiece.short_num;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
W_Piece_Num = selectPiece.short_num;
|
||||||
|
H_Piece_Num = selectPiece.long_num;
|
||||||
|
}
|
||||||
|
int Piece_len = selectPiece.len;
|
||||||
|
if (Piece_len < Min_SizeWH)
|
||||||
|
{
|
||||||
|
Piece_len = Min_SizeWH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////、计算宽度方向 块的个数 和 重叠 ///////////////////////
|
||||||
|
// 块的个数
|
||||||
|
int nBlocknum_x = W_Piece_Num;
|
||||||
|
|
||||||
|
int use_MinOverlap_Width = 0;
|
||||||
|
// 计算重叠率
|
||||||
|
if (nBlocknum_x > 1)
|
||||||
|
{
|
||||||
|
// 有多个块,要判断 块的重叠是否满足要求
|
||||||
|
int nSumLen_x = nBlocknum_x * Piece_len; //
|
||||||
|
float fOverlap_x = (nSumLen_x - qx_w) * 1.0f / (nBlocknum_x - 1);
|
||||||
|
use_MinOverlap_Width = int(fOverlap_x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////、计算高度方向 块的个数 和 重叠 ///////////////////////
|
||||||
|
|
||||||
|
// 块的个数
|
||||||
|
int nBlocknum_y = H_Piece_Num;
|
||||||
|
|
||||||
|
int use_MinOverlap_Height = 0;
|
||||||
|
// 计算重叠率
|
||||||
|
if (nBlocknum_y > 1)
|
||||||
|
{
|
||||||
|
// 有多个块,要判断 块的重叠是否满足要求
|
||||||
|
int nSumLen_y = nBlocknum_y * Piece_len; //
|
||||||
|
float fOverlap_y = (nSumLen_y - qx_h) * 1.0f / (nBlocknum_y - 1);
|
||||||
|
use_MinOverlap_Height = int(fOverlap_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
int start_x = qx_roi.x;
|
||||||
|
int start_y = qx_roi.y;
|
||||||
|
|
||||||
|
int end_x = qx_roi.width + qx_roi.x;
|
||||||
|
int end_y = qx_roi.height + qx_roi.y;
|
||||||
|
|
||||||
|
// 有效图片 宽 高
|
||||||
|
int det_width = qx_roi.width;
|
||||||
|
int det_height = qx_roi.height;
|
||||||
|
|
||||||
|
int AI_Img_width = Piece_len;
|
||||||
|
int AI_Img_height = Piece_len;
|
||||||
|
|
||||||
|
if (nBlocknum_x == 1)
|
||||||
|
{
|
||||||
|
int sx = AI_Img_width - det_width;
|
||||||
|
int sub_x = 0;
|
||||||
|
if (sx > 0)
|
||||||
|
{
|
||||||
|
sub_x = sx / 2;
|
||||||
|
}
|
||||||
|
start_x -= sub_x;
|
||||||
|
if (start_x < 0)
|
||||||
|
{
|
||||||
|
start_x = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cut_sy = qx_roi.y;
|
||||||
|
int cut_ey = qx_roi.y + Piece_len;
|
||||||
|
|
||||||
|
if (nBlocknum_y == 1)
|
||||||
|
{
|
||||||
|
int sy = AI_Img_width - det_height;
|
||||||
|
int sub_y = 0;
|
||||||
|
if (sy > 0)
|
||||||
|
{
|
||||||
|
sub_y = sy / 2;
|
||||||
|
}
|
||||||
|
start_y -= sub_y;
|
||||||
|
if (start_y < 0)
|
||||||
|
{
|
||||||
|
start_y = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cut_sy = start_y;
|
||||||
|
cut_ey = start_y + AI_Img_height;
|
||||||
|
if (cut_ey >= src_Img.rows)
|
||||||
|
{
|
||||||
|
cut_ey = src_Img.rows;
|
||||||
|
cut_sy = cut_ey - AI_Img_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int iy = 0; iy < nBlocknum_y; iy++)
|
||||||
|
{
|
||||||
|
int nleny = end_y - cut_ey;
|
||||||
|
int cut_sx = start_x;
|
||||||
|
int cut_ex = start_x + AI_Img_width;
|
||||||
|
if (cut_ex >= src_Img.cols)
|
||||||
|
{
|
||||||
|
cut_ex = src_Img.cols;
|
||||||
|
cut_sx = cut_ex - AI_Img_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int ix = 0; ix < nBlocknum_x; ix++)
|
||||||
|
{
|
||||||
|
|
||||||
|
cv::Rect roi;
|
||||||
|
roi.x = cut_sx;
|
||||||
|
roi.y = cut_sy;
|
||||||
|
roi.width = AI_Img_width;
|
||||||
|
roi.height = AI_Img_height;
|
||||||
|
|
||||||
|
samllRoiList.push_back(roi);
|
||||||
|
|
||||||
|
// 剩余长度
|
||||||
|
int nlenx = end_x - cut_ex;
|
||||||
|
if (nlenx > AI_Img_width)
|
||||||
|
{
|
||||||
|
cut_sx = cut_sx + AI_Img_width - use_MinOverlap_Width;
|
||||||
|
cut_ex = cut_sx + AI_Img_width;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cut_sx = end_x - AI_Img_width;
|
||||||
|
cut_ex = cut_sx + AI_Img_width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nleny > AI_Img_height)
|
||||||
|
{
|
||||||
|
cut_sy = cut_sy + AI_Img_height - use_MinOverlap_Height;
|
||||||
|
cut_ey = cut_sy + AI_Img_height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cut_sy = end_y - AI_Img_height;
|
||||||
|
cut_ey = cut_sy + AI_Img_height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果是偶数个,则需要再加个一个。
|
||||||
|
int sumblob = nBlocknum_y * nBlocknum_x;
|
||||||
|
if (sumblob % 2 == 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
cv::Rect temRoi = GetCutRoi(qx_roi, src_Img, nwidth, nheight);
|
||||||
|
samllRoiList.push_back(temRoi);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false)
|
||||||
|
{
|
||||||
|
cv::Mat showimg = src_Img.clone();
|
||||||
|
if (showimg.channels() == 1)
|
||||||
|
{
|
||||||
|
cv::cvtColor(showimg, showimg, cv::COLOR_GRAY2BGR);
|
||||||
|
}
|
||||||
|
cv::rectangle(showimg, qx_roi, cv::Scalar(255, 255, 0), 5);
|
||||||
|
for (size_t i = 0; i < samllRoiList.size(); i++)
|
||||||
|
{
|
||||||
|
cv::rectangle(showimg, samllRoiList.at(i), cv::Scalar(255, 0, 0));
|
||||||
|
}
|
||||||
|
static int idx = 0;
|
||||||
|
cv::imwrite(std::to_string(idx++) + "tem_piece.png", showimg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// getchar();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,337 @@
|
|||||||
|
|
||||||
|
#include "AI_Edge_QX_Det.h"
|
||||||
|
#include "CheckErrorCodeDefine.hpp"
|
||||||
|
|
||||||
|
AI_Edge_QX_Det::AI_Edge_QX_Det()
|
||||||
|
{
|
||||||
|
|
||||||
|
m_bInitSucc = false;
|
||||||
|
m_strSaveImgRootPath = "/home/aidlux/BOE/CELL_ET/Edge_QX/";
|
||||||
|
CheckUtil::CreateDir(m_strSaveImgRootPath);
|
||||||
|
m_strSaveImgRootPath_OK = m_strSaveImgRootPath + "ok/";
|
||||||
|
CheckUtil::CreateDir(m_strSaveImgRootPath_OK);
|
||||||
|
m_strSaveImgRootPath_Qx = m_strSaveImgRootPath + "qx/";
|
||||||
|
CheckUtil::CreateDir(m_strSaveImgRootPath_Qx);
|
||||||
|
m_pImageStorage = ImageStorage::getInstance();
|
||||||
|
m_nImge_num = 0;
|
||||||
|
m_strCamChannel = "";
|
||||||
|
AI_Factory = AIFactory::GetInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
AI_Edge_QX_Det::~AI_Edge_QX_Det()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int AI_Edge_QX_Det::SaveProcessImg(const cv::Mat &inImg, const cv::Mat &outImg, bool isALLzeros, DetConfig *pDetConfig, int idx, int nruntype)
|
||||||
|
{
|
||||||
|
// printf("nruntype %d %d %d\n", nruntype, pDetConfig->pdege_Det_config->bsave_all, pDetConfig->pdege_Det_config->bsave_qx);
|
||||||
|
|
||||||
|
// m_pdetlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "AI_Edge_QX_Det ", "nruntype %d %d %d\n", nruntype, pDetConfig->pdege_Det_config->bsave_all, pDetConfig->pdege_Det_config->bsave_qx);
|
||||||
|
// 正常模式
|
||||||
|
if (nruntype == 0)
|
||||||
|
{
|
||||||
|
if (pDetConfig->pdege_Det_config->bsave_all || pDetConfig->pdege_Det_config->bsave_qx)
|
||||||
|
{
|
||||||
|
// printf("==s1 \n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// printf("==s2 \n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (pDetConfig->pdege_Det_config->bsave_qx && isALLzeros)
|
||||||
|
{
|
||||||
|
// printf("==s3 \n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 只存 有问题的。
|
||||||
|
if (nruntype == 1 && isALLzeros)
|
||||||
|
{
|
||||||
|
// printf("==s4 \n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// printf("==s5\n");
|
||||||
|
// 循环存储
|
||||||
|
int flage = 1; // 0:正常 1:OK 2:qx
|
||||||
|
if (isALLzeros)
|
||||||
|
{
|
||||||
|
flage = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flage = 2;
|
||||||
|
}
|
||||||
|
std::string str_root;
|
||||||
|
str_root = GetImgSaveName(flage) + "_" + std::to_string(idx);
|
||||||
|
// printf("str_root = %s \n", str_root.c_str());
|
||||||
|
|
||||||
|
int re = 0;
|
||||||
|
if (!inImg.empty())
|
||||||
|
{
|
||||||
|
std::string strIn = str_root + "_in.png";
|
||||||
|
|
||||||
|
if (nruntype == 0)
|
||||||
|
{
|
||||||
|
re = m_pImageStorage->addImage(strIn, inImg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cv::imwrite(strIn, inImg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (re == 0)
|
||||||
|
{
|
||||||
|
std::string strmask = str_root + "_in_mask.png";
|
||||||
|
if (nruntype == 0)
|
||||||
|
{
|
||||||
|
if (!outImg.empty())
|
||||||
|
{
|
||||||
|
m_pImageStorage->addImage(strmask, outImg, true); // 强制 存储
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cv::imwrite(strmask, outImg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
std::string AI_Edge_QX_Det::GetImgSaveName(int flag)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string str_root;
|
||||||
|
if (flag == 0)
|
||||||
|
{
|
||||||
|
str_root = m_strSaveImgRootPath;
|
||||||
|
}
|
||||||
|
else if (flag == 1)
|
||||||
|
{
|
||||||
|
str_root = m_strSaveImgRootPath_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
str_root = m_strSaveImgRootPath_Qx;
|
||||||
|
}
|
||||||
|
str_root += m_strCamChannel + "_" + std::to_string(m_nImge_num);
|
||||||
|
|
||||||
|
return str_root;
|
||||||
|
}
|
||||||
|
int AI_Edge_QX_Det::Detect(const cv::Mat &img, cv::Mat &detmask, DetConfig *pDetConfig, std::shared_ptr<DetLog> pdetlog)
|
||||||
|
{
|
||||||
|
static int n_count = 0;
|
||||||
|
int nRuntype = 0; // 0:检测 1:测试。。。。。
|
||||||
|
m_pdetlog = pdetlog;
|
||||||
|
if (pDetConfig->ninstruct == 767)
|
||||||
|
{
|
||||||
|
nRuntype = 1;
|
||||||
|
}
|
||||||
|
else if (pDetConfig->ninstruct == 768)
|
||||||
|
{
|
||||||
|
nRuntype = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bdege = false;
|
||||||
|
// 二次求面积长度 功能关闭
|
||||||
|
if (!pDetConfig->pdege_Det_config->bOpen)
|
||||||
|
{
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "AI_Edge_QX_Det ", "function colse");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// if (!m_bInitialized || !m_bModelSucc)
|
||||||
|
// {
|
||||||
|
// m_pTemCheck->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "AI_Edge_QX_Det ", "m_bModelSucc error");
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
std::shared_ptr<AIModel_Base> m_pAIDeal = AI_Factory->AI_defect_Edge_QX;
|
||||||
|
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "AI_Edge_QX_Det ", "AI start %s", pDetConfig->strCamChannel.c_str());
|
||||||
|
m_strCamChannel = pDetConfig->strCamChannel;
|
||||||
|
n_count++;
|
||||||
|
if (n_count > 1000)
|
||||||
|
{
|
||||||
|
m_nImge_num = 0;
|
||||||
|
}
|
||||||
|
m_nImge_num = n_count;
|
||||||
|
// printf("pDetConfig->ninstruct ========== %d channel %s imgname %d \n", pDetConfig->ninstruct, m_strCamChannel.c_str(), m_nImge_num);
|
||||||
|
cv::Mat showImg;
|
||||||
|
cv::Mat cut_show_R;
|
||||||
|
cv::Mat cut_show_G;
|
||||||
|
cv::Mat cut_show_B;
|
||||||
|
cv::Mat edge_mask;
|
||||||
|
std::vector<cv::Mat> cut_show_channels;
|
||||||
|
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "AI_Edge_QX_Det ", "nruntype %d %d\n", pDetConfig->pdege_Det_config->bsave_all, pDetConfig->pdege_Det_config->bsave_qx);
|
||||||
|
|
||||||
|
if (bdege || nRuntype != 0)
|
||||||
|
{
|
||||||
|
showImg = img.clone();
|
||||||
|
cut_show_R = showImg(pDetConfig->CutRoi).clone();
|
||||||
|
cut_show_B = showImg(pDetConfig->CutRoi).clone();
|
||||||
|
cut_show_G = showImg(pDetConfig->CutRoi).clone();
|
||||||
|
|
||||||
|
cut_show_B += detmask * 0.2;
|
||||||
|
edge_mask = cv::Mat::zeros(detmask.size(), CV_8UC1);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < pDetConfig->pEdgeDet_roiList->size(); i++)
|
||||||
|
{
|
||||||
|
cv::Rect r = pDetConfig->pEdgeDet_roiList->at(i);
|
||||||
|
cv::Mat outMask;
|
||||||
|
if (!CheckUtil::RoiInImg(r, img))
|
||||||
|
{
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cv::Mat detimg = img(r).clone();
|
||||||
|
if (bdege || nRuntype != 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
cv::rectangle(showImg, r, cv::Scalar(255, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
int re = m_pAIDeal->AIDet(detimg, outMask);
|
||||||
|
if (re != 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (outMask.empty())
|
||||||
|
{
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
bool isAllZero = true;
|
||||||
|
if (cv::countNonZero(outMask) > 0)
|
||||||
|
{
|
||||||
|
isAllZero = false;
|
||||||
|
if (bdege || nRuntype != 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
outMask.copyTo(showImg(r), outMask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveProcessImg(detimg, outMask, isAllZero, pDetConfig, i, nRuntype);
|
||||||
|
|
||||||
|
// if (!isAllZero)
|
||||||
|
// {
|
||||||
|
// cv::imwrite("edge_AI_outMask.png", outMask);
|
||||||
|
// cv::imwrite("edge_AI_pre_detmask(r).png", detmask(r));
|
||||||
|
// }
|
||||||
|
|
||||||
|
cv::Point p_smallImg_lt;
|
||||||
|
cv::Point p_smallImg_rb;
|
||||||
|
p_smallImg_lt.x = 0;
|
||||||
|
p_smallImg_lt.y = 0;
|
||||||
|
p_smallImg_rb.x = r.width;
|
||||||
|
p_smallImg_rb.y = r.height;
|
||||||
|
|
||||||
|
cv::Point p_mask_lt;
|
||||||
|
cv::Point p_mask_rb;
|
||||||
|
|
||||||
|
p_mask_lt.x = r.x - pDetConfig->CutRoi.x;
|
||||||
|
p_mask_lt.y = r.y - pDetConfig->CutRoi.y;
|
||||||
|
p_mask_rb.x = p_mask_lt.x + r.width;
|
||||||
|
p_mask_rb.y = p_mask_lt.y + r.height;
|
||||||
|
|
||||||
|
if (p_mask_lt.x < 0)
|
||||||
|
{
|
||||||
|
p_smallImg_lt.x = -p_mask_lt.x;
|
||||||
|
|
||||||
|
p_mask_lt.x = 0;
|
||||||
|
}
|
||||||
|
if (p_mask_lt.y < 0)
|
||||||
|
{
|
||||||
|
p_smallImg_lt.y = -p_mask_lt.y;
|
||||||
|
p_mask_lt.y = 0;
|
||||||
|
}
|
||||||
|
if (p_mask_rb.x > detmask.cols)
|
||||||
|
{
|
||||||
|
p_smallImg_rb.x -= (p_mask_rb.x - detmask.cols);
|
||||||
|
p_mask_rb.x = detmask.cols;
|
||||||
|
}
|
||||||
|
if (p_mask_rb.y > detmask.rows)
|
||||||
|
{
|
||||||
|
p_smallImg_rb.y -= (p_mask_rb.y - detmask.rows);
|
||||||
|
p_mask_rb.y = detmask.rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Rect mask_roi;
|
||||||
|
mask_roi.x = p_mask_lt.x;
|
||||||
|
mask_roi.y = p_mask_lt.y;
|
||||||
|
mask_roi.width = p_mask_rb.x - p_mask_lt.x;
|
||||||
|
mask_roi.height = p_mask_rb.y - p_mask_lt.y;
|
||||||
|
|
||||||
|
cv::Rect smallImg_roi;
|
||||||
|
smallImg_roi.x = p_smallImg_lt.x;
|
||||||
|
smallImg_roi.y = p_smallImg_lt.y;
|
||||||
|
smallImg_roi.width = p_smallImg_rb.x - p_smallImg_lt.x;
|
||||||
|
smallImg_roi.height = p_smallImg_rb.y - p_smallImg_lt.y;
|
||||||
|
|
||||||
|
if (!CheckUtil::RoiInImg(smallImg_roi, outMask))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CheckUtil::RoiInImg(mask_roi, detmask))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
outMask *= 0.5;
|
||||||
|
if (nRuntype != 0)
|
||||||
|
{
|
||||||
|
outMask(smallImg_roi).copyTo(edge_mask(mask_roi), outMask(smallImg_roi));
|
||||||
|
cv::rectangle(cut_show_G, mask_roi, cv::Scalar(255, 0, 0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pDetConfig->pdege_Det_config->type == Function_Edge_Det::Edge_type_Add)
|
||||||
|
{
|
||||||
|
outMask(smallImg_roi).copyTo(detmask(mask_roi), outMask(smallImg_roi));
|
||||||
|
}
|
||||||
|
else if (pDetConfig->pdege_Det_config->type == Function_Edge_Det::Edge_type_And)
|
||||||
|
{
|
||||||
|
cv::bitwise_and(detmask(mask_roi), outMask(smallImg_roi), detmask(mask_roi));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outMask(smallImg_roi).copyTo(detmask(mask_roi));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nRuntype != 0)
|
||||||
|
{
|
||||||
|
cut_show_R += edge_mask * 0.5;
|
||||||
|
std::vector<cv::Mat> chs = {cut_show_B, cut_show_G, cut_show_R};
|
||||||
|
cv::Mat merged;
|
||||||
|
cv::merge(chs, merged);
|
||||||
|
cv::resize(merged, merged, cv::Size(merged.cols * 0.5, merged.rows * 0.5));
|
||||||
|
std::string str = GetImgSaveName(0) + "_mask.png";
|
||||||
|
cv::imwrite(str, merged);
|
||||||
|
// std::cout<<str;
|
||||||
|
// getchar();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bdege)
|
||||||
|
{
|
||||||
|
cut_show_R += edge_mask * 0.5;
|
||||||
|
std::vector<cv::Mat> chs = {cut_show_B, cut_show_G, cut_show_R};
|
||||||
|
cv::Mat merged;
|
||||||
|
cv::merge(chs, merged);
|
||||||
|
cv::resize(merged, merged, cv::Size(merged.cols * 0.5, merged.rows * 0.5));
|
||||||
|
std::string str = GetImgSaveName(0) + "_mask.png";
|
||||||
|
cv::imwrite(str, merged);
|
||||||
|
|
||||||
|
str = GetImgSaveName(0) + "_showImg.png";
|
||||||
|
cv::imwrite(str, showImg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,377 @@
|
|||||||
|
|
||||||
|
#include "AI_Edge_Algin.h"
|
||||||
|
#include "CheckErrorCodeDefine.hpp"
|
||||||
|
#include "AI_Mark_Det.h"
|
||||||
|
|
||||||
|
AI_Mark_Det::AI_Mark_Det()
|
||||||
|
{
|
||||||
|
m_bModelSucc = false;
|
||||||
|
CheckUtil::CreateDir("/home/aidlux/BOE/CELL_ET/MarkLine/");
|
||||||
|
m_pImageStorage = ImageStorage::getInstance();
|
||||||
|
m_Show_Area = 0;
|
||||||
|
m_Show_Len = 0;
|
||||||
|
m_Len_P1 = cv::Point(0, 0);
|
||||||
|
m_Len_P2 = cv::Point(0, 0);
|
||||||
|
AI_Factory = AIFactory::GetInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
AI_Mark_Det::~AI_Mark_Det()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int AI_Mark_Det::Detect(const cv::Mat &img, DetConfigResult *pDetConfig)
|
||||||
|
{
|
||||||
|
m_pdetlog = pDetConfig->pdetlog;
|
||||||
|
printf("AI_Mark_Det::Detect \n");
|
||||||
|
cv::Rect searchroi = pDetConfig->searchroi;
|
||||||
|
|
||||||
|
if (searchroi.x < 0)
|
||||||
|
{
|
||||||
|
searchroi.x = 0;
|
||||||
|
}
|
||||||
|
if (searchroi.y < 0)
|
||||||
|
{
|
||||||
|
searchroi.y = 0;
|
||||||
|
}
|
||||||
|
if (searchroi.x + searchroi.width > img.cols)
|
||||||
|
{
|
||||||
|
searchroi.width = img.cols - searchroi.x;
|
||||||
|
}
|
||||||
|
if (searchroi.y + searchroi.width > img.rows)
|
||||||
|
{
|
||||||
|
searchroi.height = img.rows - searchroi.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 每个小矩形的大小
|
||||||
|
int rectWidth = 512;
|
||||||
|
int rectHeight = 512;
|
||||||
|
// 重叠区域大小
|
||||||
|
int overlap = 50;
|
||||||
|
|
||||||
|
// 计算步长
|
||||||
|
int stepX = rectWidth - overlap;
|
||||||
|
int stepY = rectHeight - overlap;
|
||||||
|
|
||||||
|
int x_start = searchroi.x;
|
||||||
|
int x_end = searchroi.x + searchroi.width;
|
||||||
|
int y_start = searchroi.y;
|
||||||
|
int y_end = searchroi.y + searchroi.height;
|
||||||
|
if (searchroi.width < 512)
|
||||||
|
{
|
||||||
|
int cx = searchroi.x + searchroi.width * 0.5;
|
||||||
|
x_start = cx - rectWidth * 0.5;
|
||||||
|
x_end = x_start + rectWidth;
|
||||||
|
}
|
||||||
|
if (searchroi.height < 512)
|
||||||
|
{
|
||||||
|
int cy = searchroi.y + searchroi.height * 0.5;
|
||||||
|
y_start = cy - rectHeight * 0.5;
|
||||||
|
y_end = y_start + rectHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x_start < 0)
|
||||||
|
{
|
||||||
|
x_start = 0;
|
||||||
|
}
|
||||||
|
if (y_start < 0)
|
||||||
|
{
|
||||||
|
y_start = 0;
|
||||||
|
}
|
||||||
|
if (y_start + searchroi.height > img.rows)
|
||||||
|
{
|
||||||
|
y_start = img.rows - searchroi.height;
|
||||||
|
}
|
||||||
|
if (x_start + searchroi.width > img.cols)
|
||||||
|
{
|
||||||
|
x_start = img.cols - searchroi.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y_end > img.rows)
|
||||||
|
{
|
||||||
|
y_end = img.rows;
|
||||||
|
}
|
||||||
|
if (x_end > img.cols)
|
||||||
|
{
|
||||||
|
x_end = img.cols;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cv::Mat showImg;
|
||||||
|
|
||||||
|
// if (true)
|
||||||
|
// {
|
||||||
|
// cv::cvtColor(detSrcImg, showImg, cv::COLOR_GRAY2BGR);
|
||||||
|
// }
|
||||||
|
|
||||||
|
int cut_y_s = y_start;
|
||||||
|
int cut_y_e = cut_y_s + rectHeight;
|
||||||
|
int cut_x_s = x_start;
|
||||||
|
int cut_x_e = cut_x_s + rectWidth;
|
||||||
|
|
||||||
|
bool bb_y = false;
|
||||||
|
bool bb_x = false;
|
||||||
|
|
||||||
|
int w = x_end - x_start;
|
||||||
|
int h = y_end - y_start;
|
||||||
|
if (w < 512)
|
||||||
|
{
|
||||||
|
if (x_start == 0)
|
||||||
|
{
|
||||||
|
x_end = x_start + 512;
|
||||||
|
if (x_end > img.cols)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x_start = x_end - 512;
|
||||||
|
if (x_start < 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h < 512)
|
||||||
|
{
|
||||||
|
if (y_start == 0)
|
||||||
|
{
|
||||||
|
y_end = y_start + 512;
|
||||||
|
if (y_end > img.rows)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
y_start = y_end - 512;
|
||||||
|
if (y_start < 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
w = x_end - x_start;
|
||||||
|
h = y_end - y_start;
|
||||||
|
if (w < rectWidth)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (h < rectHeight)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Rect allroi(x_start, y_start, w, h);
|
||||||
|
cv::Mat allmask = cv::Mat(h, w, CV_8UC1, cv::Scalar(0));
|
||||||
|
|
||||||
|
// printf("y_start %d y_end %d\n", y_start, y_end);
|
||||||
|
// printf("x_start %d x_end %d\n", x_start, x_end);
|
||||||
|
|
||||||
|
std::shared_ptr<AIModel_Base> pAI_Model = AI_Factory->AI_defect_MarkLine;
|
||||||
|
|
||||||
|
static int ki = 0;
|
||||||
|
//
|
||||||
|
for (int y = y_start; y < y_end; y += stepY)
|
||||||
|
{
|
||||||
|
cut_y_s = y;
|
||||||
|
cut_y_e = cut_y_s + rectHeight;
|
||||||
|
if (cut_y_e > y_end)
|
||||||
|
{
|
||||||
|
cut_y_e = y_end;
|
||||||
|
cut_y_s = y_end - rectHeight;
|
||||||
|
bb_y = true;
|
||||||
|
}
|
||||||
|
bb_x = false;
|
||||||
|
for (int x = x_start; x < x_end; x += stepX)
|
||||||
|
{
|
||||||
|
cut_x_s = x;
|
||||||
|
cut_x_e = cut_x_s + rectWidth;
|
||||||
|
if (cut_x_e > x_end)
|
||||||
|
{
|
||||||
|
cut_x_e = x_end;
|
||||||
|
cut_x_s = x_end - rectWidth;
|
||||||
|
bb_x = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义小矩形
|
||||||
|
cv::Rect smallRect(cut_x_s, cut_y_s, rectWidth, rectHeight);
|
||||||
|
cv::Rect maskrect = smallRect;
|
||||||
|
maskrect.x -= x_start;
|
||||||
|
maskrect.y -= y_start;
|
||||||
|
|
||||||
|
if (!CheckUtil::RoiInImg(smallRect, img))
|
||||||
|
{
|
||||||
|
// printf("img %d %d= \n", img.cols, img.rows);
|
||||||
|
// CheckUtil::printROI(smallRect, "smallRect");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cv::Mat outmask;
|
||||||
|
|
||||||
|
cv::Mat temdet = img(smallRect).clone();
|
||||||
|
|
||||||
|
if (m_bModelSucc)
|
||||||
|
{
|
||||||
|
|
||||||
|
int re = pAI_Model->AIDet(temdet, outmask);
|
||||||
|
// m_pTemCheck->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", "AI Model POL");
|
||||||
|
// 推理是否成功
|
||||||
|
if (re != 0)
|
||||||
|
{
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_2, "AI_Mark_Det ", "Error POL AI Model Error");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_2, "AI_Mark_Det ", "Error POL AI Model Error");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (outmask.empty())
|
||||||
|
{
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_2, "AI_Mark_Det ", "Error POL AI Error");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// printf("AI_Mark_Det::Detect ========3333============ \n");
|
||||||
|
|
||||||
|
// printf("img %d %d= \n", allmask.cols, allmask.rows);
|
||||||
|
// CheckUtil::printROI(maskrect, "maskrect---");
|
||||||
|
outmask.copyTo(allmask(maskrect), outmask);
|
||||||
|
|
||||||
|
if (pDetConfig->bDebugsaveimg || pDetConfig->bDetSaveImg)
|
||||||
|
{
|
||||||
|
std::string str12 = "/home/aidlux/BOE/CELL_ET/MarkLine/" + pDetConfig->strCamName + "_" + std::to_string(ki) + "_in.png";
|
||||||
|
std::string strmask = "/home/aidlux/BOE/CELL_ET/MarkLine/" + pDetConfig->strCamName + "_" + std::to_string(ki) + "_in_mask.png";
|
||||||
|
if (pDetConfig->bDebugsaveimg)
|
||||||
|
{
|
||||||
|
str12 = pDetConfig->strCamName + "_" + std::to_string(ki) + "_in.png";
|
||||||
|
strmask = pDetConfig->strCamName + "_" + std::to_string(ki) + "_in_mask.png";
|
||||||
|
}
|
||||||
|
|
||||||
|
ki++;
|
||||||
|
if (ki > 999999)
|
||||||
|
{
|
||||||
|
ki = 0;
|
||||||
|
}
|
||||||
|
cv::imwrite(str12, img(smallRect));
|
||||||
|
cv::imwrite(strmask, outmask);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bb_x)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
/* code */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bb_y)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bf = false;
|
||||||
|
cv::Rect markroi = CheckUtil::getLargestContourROI(allmask, bf);
|
||||||
|
|
||||||
|
if (bf)
|
||||||
|
{
|
||||||
|
pDetConfig->nresult = 0;
|
||||||
|
pDetConfig->markRoi = markroi;
|
||||||
|
|
||||||
|
if (pDetConfig->bDebugsaveimg || pDetConfig->bDetSaveImg)
|
||||||
|
{
|
||||||
|
std::string str12 = "/home/aidlux/BOE/CELL_ET/MarkLine/Check_big_" + pDetConfig->strCamName + "_in.png";
|
||||||
|
std::string strmask = "/home/aidlux/BOE/CELL_ET/MarkLine/Check_big_" + pDetConfig->strCamName + "_in_mask.png";
|
||||||
|
if (pDetConfig->bDebugsaveimg)
|
||||||
|
{
|
||||||
|
str12 = "Check_big_" + pDetConfig->strCamName + "_" + std::to_string(ki) + "_in.png";
|
||||||
|
strmask = "Check_big_" + pDetConfig->strCamName + "_" + std::to_string(ki) + "_in_mask.png";
|
||||||
|
}
|
||||||
|
// CheckUtil::printROI(allroi, "allroi");
|
||||||
|
// printf("-------------------1111 33 img %d %d\n", img.cols, img.rows);
|
||||||
|
cv::Mat detimg = img(allroi).clone();
|
||||||
|
// printf("-------------------1111 33 \n");
|
||||||
|
cv::rectangle(detimg, pDetConfig->markRoi, cv::Scalar(180), 3);
|
||||||
|
// printf("-------------------1111 444\n");
|
||||||
|
cv::imwrite(str12, detimg);
|
||||||
|
cv::imwrite(strmask, allmask);
|
||||||
|
}
|
||||||
|
|
||||||
|
pDetConfig->markRoi.x += x_start;
|
||||||
|
pDetConfig->markRoi.y += y_start;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AI_Mark_Det::Det_img(const cv::Mat &img, DetConfigResult *pDetConfig)
|
||||||
|
{
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AI_Mark_Det::Analysisy(const cv::Mat &maskImg, DetConfigResult *pDetConfig)
|
||||||
|
{
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AI_Mark_Det::SaveProcessImg(const cv::Mat &inImg, const cv::Mat &outImg, const cv::Mat &oldmask, DetConfigResult *pDetConfig)
|
||||||
|
{
|
||||||
|
|
||||||
|
// if (inImg.empty() || outImg.empty())
|
||||||
|
// {
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
// static int saveimgIdx_pol = 0;
|
||||||
|
// static int saveimgIdx_ad = 0;
|
||||||
|
// // 循环存储
|
||||||
|
|
||||||
|
// std::string str_Root = "/home/aidlux/BOE/Second/";
|
||||||
|
// if (pDetConfig->qx_type == CONFIG_QX_NAME_POL_Cell)
|
||||||
|
// {
|
||||||
|
|
||||||
|
// saveimgIdx_pol++;
|
||||||
|
// if (saveimgIdx_pol > 1000)
|
||||||
|
// {
|
||||||
|
// saveimgIdx_pol = 0;
|
||||||
|
// }
|
||||||
|
// str_Root += "POL/POl_" + pDetConfig->strChannel + "_" + std::to_string(saveimgIdx_pol);
|
||||||
|
// }
|
||||||
|
// if (pDetConfig->qx_type == CONFIG_QX_NAME_AD)
|
||||||
|
// {
|
||||||
|
|
||||||
|
// saveimgIdx_ad++;
|
||||||
|
// if (saveimgIdx_ad > 1000)
|
||||||
|
// {
|
||||||
|
// saveimgIdx_ad = 0;
|
||||||
|
// }
|
||||||
|
// str_Root += "AD/AD_" + pDetConfig->strChannel + "_" + std::to_string(saveimgIdx_ad);
|
||||||
|
// }
|
||||||
|
// std::string strIn = str_Root + +"_in.png";
|
||||||
|
// int re = 0;
|
||||||
|
// if (!inImg.empty())
|
||||||
|
// {
|
||||||
|
// re = m_pImageStorage->addImage(strIn, inImg);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (re == 0)
|
||||||
|
// {
|
||||||
|
// std::string strmask = str_Root + "_in_mask.png";
|
||||||
|
// if (!outImg.empty())
|
||||||
|
// {
|
||||||
|
// m_pImageStorage->addImage(strmask, outImg, true); // 强制 存储
|
||||||
|
// }
|
||||||
|
|
||||||
|
// std::string stroldmask = str_Root + "_old_mask.png";
|
||||||
|
// if (!oldmask.empty())
|
||||||
|
// {
|
||||||
|
// m_pImageStorage->addImage(stroldmask, oldmask, true); // 强制 存储
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,564 @@
|
|||||||
|
|
||||||
|
#include "AI_Edge_Algin.h"
|
||||||
|
#include "CheckErrorCodeDefine.hpp"
|
||||||
|
#include "AI_Second_Det.h"
|
||||||
|
|
||||||
|
AI_SecondDet::AI_SecondDet()
|
||||||
|
{
|
||||||
|
m_bModelSucc_AD = false;
|
||||||
|
m_bModelSucc_POL = false;
|
||||||
|
CheckUtil::CreateDir("/home/aidlux/BOE/CELL_ET/Second/POL/");
|
||||||
|
CheckUtil::CreateDir("/home/aidlux/BOE/CELL_ET/Second/AD/");
|
||||||
|
m_pImageStorage = ImageStorage::getInstance();
|
||||||
|
m_Show_Area = 0;
|
||||||
|
m_Show_Len = 0;
|
||||||
|
m_Len_P1 = cv::Point(0, 0);
|
||||||
|
m_Len_P2 = cv::Point(0, 0);
|
||||||
|
AI_Factory = AIFactory::GetInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
AI_SecondDet::~AI_SecondDet()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int AI_SecondDet::Detect(const cv::Mat &img, const cv::Mat &mask, DetConfigResult *pDetConfig)
|
||||||
|
{
|
||||||
|
m_pdetlog = pDetConfig->pdetlog;
|
||||||
|
// 二次求面积长度 功能关闭
|
||||||
|
if (!pDetConfig->pfunction_secondDet->bOpen)
|
||||||
|
{
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", "function colse");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// cv::Mat temimg = mask.clone();
|
||||||
|
// cv::rectangle(temimg, pDetConfig->qx_roi, cv::Scalar(128, 0, 0));
|
||||||
|
cv::Rect AIroi = GetCutRoi(pDetConfig->qx_roi, img);
|
||||||
|
|
||||||
|
if (AIroi.width <= 0 || AIroi.height <= 0)
|
||||||
|
{
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", "Error Size");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!CheckUtil::RoiInImg(AIroi, img))
|
||||||
|
{
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", "Error ROI");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
float min_set_param_area = 0;
|
||||||
|
float max_set_param_area = 9999;
|
||||||
|
if (pDetConfig->qx_type == CONFIG_QX_NAME_POL_Cell)
|
||||||
|
{
|
||||||
|
min_set_param_area = pDetConfig->pfunction_secondDet->pol_area_min;
|
||||||
|
max_set_param_area = pDetConfig->pfunction_secondDet->pol_area_max;
|
||||||
|
}
|
||||||
|
if (pDetConfig->qx_type == CONFIG_QX_NAME_AD)
|
||||||
|
{
|
||||||
|
min_set_param_area = pDetConfig->pfunction_secondDet->andian_area_min;
|
||||||
|
max_set_param_area = pDetConfig->pfunction_secondDet->andian_area_max;
|
||||||
|
}
|
||||||
|
float oldarea_mm2 = pDetConfig->old_Area * pDetConfig->fImgage_Scale_X * pDetConfig->fImgage_Scale_Y;
|
||||||
|
if (oldarea_mm2 < min_set_param_area || oldarea_mm2 > max_set_param_area)
|
||||||
|
{
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", "error Area %0.2f out[%0.2f %0.2f] ", oldarea_mm2, min_set_param_area, max_set_param_area);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (oldarea_mm2 < pDetConfig->min_DetArea)
|
||||||
|
{
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", "Error Area %0.2f < det param %0.2f ", oldarea_mm2, pDetConfig->min_DetArea);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", "succ Area %0.2f >= min det param %0.2f and in [%0.2f %0.2f] ", oldarea_mm2, pDetConfig->min_DetArea, min_set_param_area, max_set_param_area);
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Mat detimg = img(AIroi).clone();
|
||||||
|
|
||||||
|
cv::Mat outimg;
|
||||||
|
int re12 = 0;
|
||||||
|
//
|
||||||
|
if (pDetConfig->qx_type == CONFIG_QX_NAME_POL_Cell)
|
||||||
|
{
|
||||||
|
if (pDetConfig->pfunction_secondDet->pol_saveProcessImg)
|
||||||
|
{
|
||||||
|
printf("mask %d %d \n", mask.cols, mask.rows);
|
||||||
|
printf("AIroi %d %d %d %d\n", AIroi.x, AIroi.y, AIroi.width, AIroi.height);
|
||||||
|
detimg123 = mask(AIroi).clone();
|
||||||
|
printf("1111mask %d %d \n", mask.cols, mask.rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
re12 = Det_Pol(detimg, pDetConfig);
|
||||||
|
}
|
||||||
|
if (pDetConfig->qx_type == CONFIG_QX_NAME_AD)
|
||||||
|
{
|
||||||
|
if (pDetConfig->pfunction_secondDet->andian_saveProcessImg)
|
||||||
|
{
|
||||||
|
// printf("mask %d %d \n", mask.cols, mask.rows);
|
||||||
|
// printf("AIroi %d %d %d %d\n", AIroi.x, AIroi.y, AIroi.width, AIroi.height);
|
||||||
|
detimg123 = mask(AIroi).clone();
|
||||||
|
// printf("2222mask %d %d \n", mask.cols, mask.rows);
|
||||||
|
}
|
||||||
|
re12 = Det_AD(detimg, pDetConfig);
|
||||||
|
}
|
||||||
|
if (re12 != 0)
|
||||||
|
{
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE_POL /AD", "Error ");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Rect AI_SecondDet::GetCutRoi(cv::Rect &roi, const cv::Mat &img)
|
||||||
|
{
|
||||||
|
std::shared_ptr<AIModel_Base> pAI_Model = AI_Factory->AI_defect_RE_POL;
|
||||||
|
|
||||||
|
cv::Size sz;
|
||||||
|
sz.width = pAI_Model->input_0.width;
|
||||||
|
sz.height = pAI_Model->input_0.height;
|
||||||
|
|
||||||
|
int Dst_Width = sz.width;
|
||||||
|
int Dst_Height = sz.height;
|
||||||
|
cv::Rect cutroi = cv::Rect(0, 0, 0, 0);
|
||||||
|
if (Dst_Width >= img.cols || Dst_Height >= img.rows)
|
||||||
|
{
|
||||||
|
return cutroi;
|
||||||
|
}
|
||||||
|
if (roi.width >= Dst_Width || roi.height >= Dst_Height)
|
||||||
|
{
|
||||||
|
return cutroi;
|
||||||
|
}
|
||||||
|
|
||||||
|
int centerX = roi.x + roi.width / 2;
|
||||||
|
int centerY = roi.y + roi.height / 2;
|
||||||
|
|
||||||
|
// 构造一个以中心为中心的 128x128 矩形
|
||||||
|
int halfSize = Dst_Width / 2; // 128 / 2
|
||||||
|
int newX = centerX - halfSize;
|
||||||
|
int newY = centerY - halfSize;
|
||||||
|
int newWidth = Dst_Width;
|
||||||
|
int newHeight = Dst_Height;
|
||||||
|
|
||||||
|
// 检查矩形是否越界
|
||||||
|
if (newX < 0)
|
||||||
|
{
|
||||||
|
newX = 0;
|
||||||
|
}
|
||||||
|
if (newY < 0)
|
||||||
|
{
|
||||||
|
newY = 0;
|
||||||
|
}
|
||||||
|
if (newX + newWidth > img.cols)
|
||||||
|
{
|
||||||
|
newX = img.cols - newWidth;
|
||||||
|
}
|
||||||
|
if (newY + newHeight > img.rows)
|
||||||
|
{
|
||||||
|
newY = img.rows - newHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建新的矩形
|
||||||
|
cv::Rect newRect(newX, newY, newWidth, newHeight);
|
||||||
|
int add = 3;
|
||||||
|
// 重新计算 roi 在新的矩形中的位置
|
||||||
|
int newRoiX = roi.x - newRect.x - add;
|
||||||
|
int newRoiY = roi.y - newRect.y - add;
|
||||||
|
int newRoiWidth = roi.width + 2 * add;
|
||||||
|
int newRoiHeight = roi.height + 2 * add;
|
||||||
|
|
||||||
|
// 确保新的 roi 在新的矩形内
|
||||||
|
if (newRoiX < 0)
|
||||||
|
{
|
||||||
|
newRoiX = 0;
|
||||||
|
}
|
||||||
|
if (newRoiY < 0)
|
||||||
|
{
|
||||||
|
newRoiY = 0;
|
||||||
|
}
|
||||||
|
if (newRoiX + newRoiWidth > newRect.width)
|
||||||
|
{
|
||||||
|
newRoiWidth = newRect.width - newRoiX;
|
||||||
|
}
|
||||||
|
if (newRoiY + newRoiHeight > newRect.height)
|
||||||
|
{
|
||||||
|
newRoiHeight = newRect.height - newRoiY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新 roi
|
||||||
|
roi = cv::Rect(newRoiX, newRoiY, newRoiWidth, newRoiHeight);
|
||||||
|
|
||||||
|
// 返回新的矩形
|
||||||
|
return newRect;
|
||||||
|
}
|
||||||
|
int AI_SecondDet::Det_Pol(const cv::Mat &img, DetConfigResult *pDetConfig)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::shared_ptr<AIModel_Base> pAI_Model = AI_Factory->AI_defect_RE_POL;
|
||||||
|
int re = 0;
|
||||||
|
cv::Mat outimg;
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", " POL start");
|
||||||
|
|
||||||
|
re = pAI_Model->AIDet(img, outimg);
|
||||||
|
if (re != 0)
|
||||||
|
{
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE ", "Error POL AI Model Error");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outimg.empty())
|
||||||
|
{
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE ", "Error POL AI Error");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
cv::Mat AnalysisyImg = outimg(pDetConfig->qx_roi).clone();
|
||||||
|
m_Show_Area = pDetConfig->old_Area;
|
||||||
|
m_Show_Len = pDetConfig->old_len;
|
||||||
|
// 开始分析mask;
|
||||||
|
re = Analysisy(AnalysisyImg, pDetConfig);
|
||||||
|
m_Len_P1.x += pDetConfig->qx_roi.x;
|
||||||
|
m_Len_P1.y += pDetConfig->qx_roi.y;
|
||||||
|
|
||||||
|
m_Len_P2.x += pDetConfig->qx_roi.x;
|
||||||
|
m_Len_P2.y += pDetConfig->qx_roi.y;
|
||||||
|
|
||||||
|
// 存储中间过程图片
|
||||||
|
if (pDetConfig->pfunction_secondDet->pol_saveProcessImg)
|
||||||
|
{
|
||||||
|
if (true)
|
||||||
|
{
|
||||||
|
cv::rectangle(outimg, pDetConfig->qx_roi, cv::Scalar(128, 0, 0));
|
||||||
|
cv::rectangle(detimg123, pDetConfig->qx_roi, cv::Scalar(128, 0, 0));
|
||||||
|
|
||||||
|
cv::line(outimg, m_Len_P1, m_Len_P2, cv::Scalar(128, 0, 0));
|
||||||
|
|
||||||
|
{
|
||||||
|
char buffer[128];
|
||||||
|
sprintf(buffer, " oA %d -> nA %d ",
|
||||||
|
pDetConfig->old_Area, m_Show_Area);
|
||||||
|
std::string st1 = buffer;
|
||||||
|
cv::Point p(0, 10);
|
||||||
|
cv::putText(outimg, st1, p, cv::FONT_HERSHEY_SIMPLEX, 0.35, cv::Scalar(200, 0, 255), 0.35, 1, 0);
|
||||||
|
|
||||||
|
sprintf(buffer, " oL %0.2f -> nL %0.2f ",
|
||||||
|
pDetConfig->old_len, m_Show_Len);
|
||||||
|
st1 = buffer;
|
||||||
|
cv::Point p2(0, 20);
|
||||||
|
cv::putText(outimg, st1, p2, cv::FONT_HERSHEY_SIMPLEX, 0.35, cv::Scalar(200, 0, 255), 0.35, 1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SaveProcessImg(img, outimg, detimg123, pDetConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
return re;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AI_SecondDet::Det_AD(const cv::Mat &img, DetConfigResult *pDetConfig)
|
||||||
|
{
|
||||||
|
std::shared_ptr<AIModel_Base> pAI_Model = AI_Factory->AI_defect_RE_AD;
|
||||||
|
int re = 0;
|
||||||
|
cv::Mat outimg;
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", " AD start");
|
||||||
|
re = pAI_Model->AIDet(img, outimg);
|
||||||
|
|
||||||
|
if (re != 0)
|
||||||
|
{
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE ", "Error AD AI Model Error");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outimg.empty())
|
||||||
|
{
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE ", "Error AD AI Error");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!CheckUtil::RoiInImg(pDetConfig->qx_roi, outimg))
|
||||||
|
{
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", "qx roi Error");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
cv::Mat AnalysisyImg = outimg(pDetConfig->qx_roi).clone();
|
||||||
|
|
||||||
|
m_Show_Area = pDetConfig->old_Area;
|
||||||
|
m_Show_Len = pDetConfig->old_len;
|
||||||
|
// 开始分析mask;
|
||||||
|
re = Analysisy(AnalysisyImg, pDetConfig);
|
||||||
|
|
||||||
|
m_Len_P1.x += pDetConfig->qx_roi.x;
|
||||||
|
m_Len_P1.y += pDetConfig->qx_roi.y;
|
||||||
|
|
||||||
|
m_Len_P2.x += pDetConfig->qx_roi.x;
|
||||||
|
m_Len_P2.y += pDetConfig->qx_roi.y;
|
||||||
|
|
||||||
|
if (pDetConfig->pfunction_secondDet->andian_saveProcessImg)
|
||||||
|
{
|
||||||
|
if (true)
|
||||||
|
{
|
||||||
|
cv::rectangle(outimg, pDetConfig->qx_roi, cv::Scalar(128, 0, 0));
|
||||||
|
cv::rectangle(detimg123, pDetConfig->qx_roi, cv::Scalar(128, 0, 0));
|
||||||
|
cv::line(outimg, m_Len_P1, m_Len_P2, cv::Scalar(128, 0, 0));
|
||||||
|
{
|
||||||
|
char buffer[128];
|
||||||
|
sprintf(buffer, " oA %d -> nA %d ",
|
||||||
|
pDetConfig->old_Area, m_Show_Area);
|
||||||
|
std::string st1 = buffer;
|
||||||
|
cv::Point p(0, 10);
|
||||||
|
cv::putText(outimg, st1, p, cv::FONT_HERSHEY_SIMPLEX, 0.35, cv::Scalar(200, 0, 255), 0.35, 1, 0);
|
||||||
|
|
||||||
|
sprintf(buffer, " oL %0.2f -> nL %0.2f ",
|
||||||
|
pDetConfig->old_len, m_Show_Len);
|
||||||
|
st1 = buffer;
|
||||||
|
cv::Point p2(0, 20);
|
||||||
|
cv::putText(outimg, st1, p2, cv::FONT_HERSHEY_SIMPLEX, 0.35, cv::Scalar(200, 0, 255), 0.35, 1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveProcessImg(img, outimg, detimg123, pDetConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
return re;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AI_SecondDet::Analysisy(const cv::Mat &maskImg, DetConfigResult *pDetConfig)
|
||||||
|
{
|
||||||
|
// 存储轮廓
|
||||||
|
std::vector<std::vector<cv::Point>> contours;
|
||||||
|
// 存储每个轮廓的层级
|
||||||
|
std::vector<cv::Vec4i> hierarchy;
|
||||||
|
|
||||||
|
// 寻找轮廓
|
||||||
|
cv::findContours(maskImg, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
|
||||||
|
|
||||||
|
double maxArea = 0;
|
||||||
|
int maxIndex = -1;
|
||||||
|
|
||||||
|
// 遍历每个轮廓,计算面积并找出最大的面积
|
||||||
|
for (size_t i = 0; i < contours.size(); i++)
|
||||||
|
{
|
||||||
|
double area = cv::contourArea(contours[i]);
|
||||||
|
if (area > maxArea)
|
||||||
|
{
|
||||||
|
maxArea = area;
|
||||||
|
maxIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (maxIndex < 0)
|
||||||
|
{
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", "second mask is error");
|
||||||
|
return 1;
|
||||||
|
/* code */
|
||||||
|
}
|
||||||
|
bool barea = false;
|
||||||
|
bool blen = false;
|
||||||
|
int oldArea = pDetConfig->old_Area;
|
||||||
|
float oldLen = pDetConfig->old_len;
|
||||||
|
if (pDetConfig->qx_type == CONFIG_QX_NAME_POL_Cell)
|
||||||
|
{
|
||||||
|
barea = pDetConfig->pfunction_secondDet->pol_Open_area;
|
||||||
|
blen = pDetConfig->pfunction_secondDet->pol_Open_len;
|
||||||
|
}
|
||||||
|
if (pDetConfig->qx_type == CONFIG_QX_NAME_AD)
|
||||||
|
{
|
||||||
|
barea = pDetConfig->pfunction_secondDet->andian_Open_area;
|
||||||
|
blen = pDetConfig->pfunction_secondDet->andian_Open_len;
|
||||||
|
}
|
||||||
|
// 计算面积
|
||||||
|
// if (barea)
|
||||||
|
{
|
||||||
|
int maxContourPixelCount = 0;
|
||||||
|
if (maxIndex >= 0)
|
||||||
|
{
|
||||||
|
cv::Mat mask = cv::Mat::zeros(maskImg.size(), CV_8UC1);
|
||||||
|
cv::drawContours(mask, contours, maxIndex, cv::Scalar(255), cv::FILLED); // 绘制轮廓填充区域
|
||||||
|
maxContourPixelCount = cv::countNonZero(mask); // 计算填充区域的像素个数
|
||||||
|
}
|
||||||
|
m_Show_Area = maxContourPixelCount;
|
||||||
|
|
||||||
|
if (barea)
|
||||||
|
{
|
||||||
|
if (maxContourPixelCount > 0 && maxContourPixelCount < oldArea)
|
||||||
|
{
|
||||||
|
pDetConfig->new_Area = maxContourPixelCount;
|
||||||
|
}
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", "Use New Area :old area %d (pixel) new %d", oldArea, pDetConfig->new_Area);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", " Not Use Area :old area %d (pixel) new %d", oldArea, maxContourPixelCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// m_pTemCheck->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", "Cal Area is Close");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 计算长度
|
||||||
|
// if (blen)
|
||||||
|
{
|
||||||
|
cv::RotatedRect rect = cv::minAreaRect(contours[maxIndex]);
|
||||||
|
|
||||||
|
// 获取最小外接矩形的尺寸
|
||||||
|
float width = rect.size.width;
|
||||||
|
float height = rect.size.height;
|
||||||
|
|
||||||
|
Point2f vertices[4];
|
||||||
|
rect.points(vertices);
|
||||||
|
|
||||||
|
if (pDetConfig->qx_type == CONFIG_QX_NAME_AD)
|
||||||
|
{
|
||||||
|
float len1 = sqrt((vertices[0].x - vertices[1].x) * (vertices[0].x - vertices[1].x) +
|
||||||
|
(vertices[0].y - vertices[1].y) * (vertices[0].y - vertices[1].y));
|
||||||
|
|
||||||
|
float len2 = sqrt((vertices[2].x - vertices[1].x) * (vertices[2].x - vertices[1].x) +
|
||||||
|
(vertices[2].y - vertices[1].y) * (vertices[2].y - vertices[1].y));
|
||||||
|
|
||||||
|
if (len1 > len2)
|
||||||
|
{
|
||||||
|
m_Len_P1.x = vertices[0].x;
|
||||||
|
m_Len_P1.y = vertices[0].y;
|
||||||
|
|
||||||
|
m_Len_P2.x = vertices[1].x;
|
||||||
|
m_Len_P2.y = vertices[1].y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_Len_P1.x = vertices[2].x;
|
||||||
|
m_Len_P1.y = vertices[2].y;
|
||||||
|
|
||||||
|
m_Len_P2.x = vertices[1].x;
|
||||||
|
m_Len_P2.y = vertices[1].y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_Len_P1.x = vertices[2].x;
|
||||||
|
m_Len_P1.y = vertices[2].y;
|
||||||
|
|
||||||
|
m_Len_P2.x = vertices[0].x;
|
||||||
|
m_Len_P2.y = vertices[0].y;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<Point2f> newcont;
|
||||||
|
for (int i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
Point2f p;
|
||||||
|
p.x = vertices[i].x * pDetConfig->fImgage_Scale_X;
|
||||||
|
p.y = vertices[i].y * pDetConfig->fImgage_Scale_Y;
|
||||||
|
newcont.push_back(p);
|
||||||
|
}
|
||||||
|
vector<vector<Point2f>> contours_New;
|
||||||
|
contours_New.push_back(newcont);
|
||||||
|
// Recreate the rotated rectangle with scaled vertices
|
||||||
|
RotatedRect scaledRect = minAreaRect(contours_New[0]);
|
||||||
|
|
||||||
|
// Calculate scaled width and height
|
||||||
|
width = scaledRect.size.width;
|
||||||
|
height = scaledRect.size.height;
|
||||||
|
float new_len = width;
|
||||||
|
if (width > 0 && height > 0)
|
||||||
|
{
|
||||||
|
if (pDetConfig->qx_type == CONFIG_QX_NAME_AD)
|
||||||
|
{
|
||||||
|
if (width > height)
|
||||||
|
{
|
||||||
|
new_len = width;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_len = height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_len = sqrt(width * width + height * height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (width > height)
|
||||||
|
{
|
||||||
|
new_len = width;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_len = height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// printf("oldLen %f new_len %f \n", oldLen, new_len);
|
||||||
|
m_Show_Len = new_len;
|
||||||
|
if (blen)
|
||||||
|
{
|
||||||
|
if (new_len > 0 && new_len < oldLen)
|
||||||
|
{
|
||||||
|
pDetConfig->new_len = new_len;
|
||||||
|
}
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Len", "Use New Len :old Len %f (mm) new %f", oldLen, pDetConfig->new_len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Len", " Not Use Len :old Len %f (mm) new %f", oldLen, new_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// m_pTemCheck->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Len", "Cal Len is Close");
|
||||||
|
// }
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AI_SecondDet::SaveProcessImg(const cv::Mat &inImg, const cv::Mat &outImg, const cv::Mat &oldmask, DetConfigResult *pDetConfig)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (inImg.empty() || outImg.empty())
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
static int saveimgIdx_pol = 0;
|
||||||
|
static int saveimgIdx_ad = 0;
|
||||||
|
// 循环存储
|
||||||
|
|
||||||
|
std::string str_Root = "/home/aidlux/BOE/CELL_ET/Second/";
|
||||||
|
if (pDetConfig->qx_type == CONFIG_QX_NAME_POL_Cell)
|
||||||
|
{
|
||||||
|
|
||||||
|
saveimgIdx_pol++;
|
||||||
|
if (saveimgIdx_pol > 1000)
|
||||||
|
{
|
||||||
|
saveimgIdx_pol = 0;
|
||||||
|
}
|
||||||
|
str_Root += "POL/POl_" + pDetConfig->strChannel + "_" + std::to_string(saveimgIdx_pol);
|
||||||
|
}
|
||||||
|
if (pDetConfig->qx_type == CONFIG_QX_NAME_AD)
|
||||||
|
{
|
||||||
|
|
||||||
|
saveimgIdx_ad++;
|
||||||
|
if (saveimgIdx_ad > 1000)
|
||||||
|
{
|
||||||
|
saveimgIdx_ad = 0;
|
||||||
|
}
|
||||||
|
str_Root += "AD/AD_" + pDetConfig->strChannel + "_" + std::to_string(saveimgIdx_ad);
|
||||||
|
}
|
||||||
|
std::string strIn = str_Root + +"_in.png";
|
||||||
|
int re = 0;
|
||||||
|
if (!inImg.empty())
|
||||||
|
{
|
||||||
|
re = m_pImageStorage->addImage(strIn, inImg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (re == 0)
|
||||||
|
{
|
||||||
|
std::string strmask = str_Root + "_in_mask.png";
|
||||||
|
if (!outImg.empty())
|
||||||
|
{
|
||||||
|
m_pImageStorage->addImage(strmask, outImg, true); // 强制 存储
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string stroldmask = str_Root + "_old_mask.png";
|
||||||
|
if (!oldmask.empty())
|
||||||
|
{
|
||||||
|
m_pImageStorage->addImage(stroldmask, oldmask, true); // 强制 存储
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,157 @@
|
|||||||
|
|
||||||
|
#include "AI_ZF_Det.h"
|
||||||
|
#include "CheckErrorCodeDefine.hpp"
|
||||||
|
|
||||||
|
static bool compareContourAreas123(const vector<Point> &contour1, const vector<Point> &contour2)
|
||||||
|
{
|
||||||
|
double i = contourArea(contour1);
|
||||||
|
double j = contourArea(contour2);
|
||||||
|
return (i > j);
|
||||||
|
}
|
||||||
|
|
||||||
|
AI_ZF_Det::AI_ZF_Det()
|
||||||
|
{
|
||||||
|
m_bModelSucc = false;
|
||||||
|
CheckUtil::CreateDir("/home/aidlux/BOE/CELL_ET/zf/");
|
||||||
|
m_pImageStorage = ImageStorage::getInstance();
|
||||||
|
m_Show_Area = 0;
|
||||||
|
m_Show_Len = 0;
|
||||||
|
m_Len_P1 = cv::Point(0, 0);
|
||||||
|
m_Len_P2 = cv::Point(0, 0);
|
||||||
|
AI_Factory = AIFactory::GetInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
AI_ZF_Det::~AI_ZF_Det()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int AI_ZF_Det::Detect(const cv::Mat &img, DetConfigResult *pDetConfig)
|
||||||
|
{
|
||||||
|
std::shared_ptr<AIModel_Base> pAI_Model = AI_Factory->AI_defect_zf;
|
||||||
|
m_pdetlog = pDetConfig->pdetlog;
|
||||||
|
cv::Size sz;
|
||||||
|
sz.width = pAI_Model->input_0.width;
|
||||||
|
sz.height = pAI_Model->input_0.height;
|
||||||
|
|
||||||
|
cv::Mat inImg;
|
||||||
|
cv::Mat AIoutimg;
|
||||||
|
cv::resize(img, inImg, sz, 0, 0, cv::INTER_AREA);
|
||||||
|
pAI_Model->AIDet(inImg, AIoutimg);
|
||||||
|
if (pDetConfig->bDebugsaveimg)
|
||||||
|
{
|
||||||
|
if (!inImg.empty())
|
||||||
|
{
|
||||||
|
cv::imwrite("ZF_img_In.png", inImg);
|
||||||
|
}
|
||||||
|
if (!AIoutimg.empty())
|
||||||
|
{
|
||||||
|
cv::imwrite("ZF_img_out.png", AIoutimg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
float fx = img.cols * 1.0f / AIoutimg.cols;
|
||||||
|
float fy = img.rows * 1.0f / AIoutimg.rows;
|
||||||
|
|
||||||
|
// 轮廓检测
|
||||||
|
std::vector<std::vector<cv::Point>> contours;
|
||||||
|
findContours(AIoutimg, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
|
||||||
|
|
||||||
|
// 根据面积大小对轮廓进行排序
|
||||||
|
sort(contours.begin(), contours.end(), compareContourAreas123);
|
||||||
|
|
||||||
|
int kd = 0;
|
||||||
|
for (size_t i = 0; i < contours.size(); ++i)
|
||||||
|
{
|
||||||
|
|
||||||
|
// 获取当前轮廓的边界矩形
|
||||||
|
cv::Rect boundingRect = cv::boundingRect(contours[i]);
|
||||||
|
|
||||||
|
cv::Rect roi;
|
||||||
|
roi.x = boundingRect.x * fx;
|
||||||
|
roi.y = boundingRect.y * fy;
|
||||||
|
roi.width = boundingRect.width * fx;
|
||||||
|
roi.height = boundingRect.height * fy;
|
||||||
|
pDetConfig->pZF_Result->pZF_roiList.push_back(roi);
|
||||||
|
|
||||||
|
|
||||||
|
kd++;
|
||||||
|
if (kd >= 2)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AI_ZF_Det::Det_img(const cv::Mat &img, DetConfigResult *pDetConfig)
|
||||||
|
{
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AI_ZF_Det::Analysisy(const cv::Mat &maskImg, DetConfigResult *pDetConfig)
|
||||||
|
{
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AI_ZF_Det::SaveProcessImg(const cv::Mat &inImg, const cv::Mat &outImg, const cv::Mat &oldmask, DetConfigResult *pDetConfig)
|
||||||
|
{
|
||||||
|
|
||||||
|
// if (inImg.empty() || outImg.empty())
|
||||||
|
// {
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
// static int saveimgIdx_pol = 0;
|
||||||
|
// static int saveimgIdx_ad = 0;
|
||||||
|
// // 循环存储
|
||||||
|
|
||||||
|
// std::string str_Root = "/home/aidlux/BOE/Second/";
|
||||||
|
// if (pDetConfig->qx_type == CONFIG_QX_NAME_POL_Cell)
|
||||||
|
// {
|
||||||
|
|
||||||
|
// saveimgIdx_pol++;
|
||||||
|
// if (saveimgIdx_pol > 1000)
|
||||||
|
// {
|
||||||
|
// saveimgIdx_pol = 0;
|
||||||
|
// }
|
||||||
|
// str_Root += "POL/POl_" + pDetConfig->strChannel + "_" + std::to_string(saveimgIdx_pol);
|
||||||
|
// }
|
||||||
|
// if (pDetConfig->qx_type == CONFIG_QX_NAME_AD)
|
||||||
|
// {
|
||||||
|
|
||||||
|
// saveimgIdx_ad++;
|
||||||
|
// if (saveimgIdx_ad > 1000)
|
||||||
|
// {
|
||||||
|
// saveimgIdx_ad = 0;
|
||||||
|
// }
|
||||||
|
// str_Root += "AD/AD_" + pDetConfig->strChannel + "_" + std::to_string(saveimgIdx_ad);
|
||||||
|
// }
|
||||||
|
// std::string strIn = str_Root + +"_in.png";
|
||||||
|
// int re = 0;
|
||||||
|
// if (!inImg.empty())
|
||||||
|
// {
|
||||||
|
// re = m_pImageStorage->addImage(strIn, inImg);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (re == 0)
|
||||||
|
// {
|
||||||
|
// std::string strmask = str_Root + "_in_mask.png";
|
||||||
|
// if (!outImg.empty())
|
||||||
|
// {
|
||||||
|
// m_pImageStorage->addImage(strmask, outImg, true); // 强制 存储
|
||||||
|
// }
|
||||||
|
|
||||||
|
// std::string stroldmask = str_Root + "_old_mask.png";
|
||||||
|
// if (!oldmask.empty())
|
||||||
|
// {
|
||||||
|
// m_pImageStorage->addImage(stroldmask, oldmask, true); // 强制 存储
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,740 @@
|
|||||||
|
/*
|
||||||
|
* @Author: your name
|
||||||
|
* @Date: 2022-04-20 15:50:00
|
||||||
|
* @LastEditTime: 2025-09-24 11:03:35
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
* @FilePath: /ZCXD_MonitorPlatform/src/CoreLogicModule/src/CamDeal.cpp
|
||||||
|
*/
|
||||||
|
#include "ALLImgCheckAnalysisy.hpp"
|
||||||
|
#include "CheckUtil.hpp"
|
||||||
|
#include "Define.h"
|
||||||
|
#include "AI_Factory.h"
|
||||||
|
double calculateDistanceBetweenRectCenters(const cv::Rect &rect1, const cv::Rect &rect2, float fx, float fy)
|
||||||
|
{
|
||||||
|
// 计算矩形1的中心点
|
||||||
|
cv::Point center1(rect1.x + rect1.width / 2, rect1.y + rect1.height / 2);
|
||||||
|
|
||||||
|
// 计算矩形2的中心点
|
||||||
|
cv::Point center2(rect2.x + rect2.width / 2, rect2.y + rect2.height / 2);
|
||||||
|
center1.x *= fx;
|
||||||
|
center1.y *= fy;
|
||||||
|
|
||||||
|
center2.x *= fx;
|
||||||
|
center2.y *= fy;
|
||||||
|
|
||||||
|
// 计算中心点之间的欧几里得距离
|
||||||
|
double distance = cv::norm(center1 - center2);
|
||||||
|
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALLImgCheckAnalysisy::ALLImgCheckAnalysisy()
|
||||||
|
{
|
||||||
|
m_strTest = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
ALLImgCheckAnalysisy::~ALLImgCheckAnalysisy()
|
||||||
|
{
|
||||||
|
StopThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::RunStart(void *pconfig1)
|
||||||
|
{
|
||||||
|
|
||||||
|
// 1、参数版本核对
|
||||||
|
int re = CheckConfigVersion(pconfig1);
|
||||||
|
if (re != 0)
|
||||||
|
{
|
||||||
|
printf("*************CheckConfigVersion error %d*************** \n", re);
|
||||||
|
m_nErrorCode = INIT_CameraCheck_Error;
|
||||||
|
return m_nErrorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pParamName = ParmNameChange::getInstance();
|
||||||
|
m_pParamName->m_nWorkIdx = m_RunConfig.nWorkIdx;
|
||||||
|
// 2、初始化相机类
|
||||||
|
|
||||||
|
re = InitCameraCheckAnalysisy();
|
||||||
|
if (re != 0)
|
||||||
|
{
|
||||||
|
printf("*************InitCameraCheckAnalysisy error %d*************** \n", re);
|
||||||
|
m_nErrorCode = INIT_CameraCheck_Error;
|
||||||
|
return m_nErrorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
re = InitRun();
|
||||||
|
if (CHECK_OK != re)
|
||||||
|
{
|
||||||
|
m_nErrorCode = re;
|
||||||
|
return m_nErrorCode;
|
||||||
|
}
|
||||||
|
re = InitAIFactory();
|
||||||
|
if (CHECK_OK != re)
|
||||||
|
{
|
||||||
|
m_nErrorCode = re;
|
||||||
|
return m_nErrorCode;
|
||||||
|
}
|
||||||
|
m_nErrorCode = CHECK_OK;
|
||||||
|
printf(">>>> ALLImgCheckAnalysisy Start Succ \n");
|
||||||
|
|
||||||
|
m_nErrorCode = CHECK_OK;
|
||||||
|
m_bInitSucc = true;
|
||||||
|
return m_nErrorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::SetDataRun_SharePtr(std::shared_ptr<shareImage> p)
|
||||||
|
{
|
||||||
|
|
||||||
|
int re = PushInImg_New(p);
|
||||||
|
if (re != 0)
|
||||||
|
{
|
||||||
|
printf("SetDataRun_SharePtr======================= re %d \n", re);
|
||||||
|
}
|
||||||
|
|
||||||
|
return re;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::GetCheckReuslt(std::shared_ptr<CheckResult> &pResult)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lk(mtx_CheckResult); // 使用 unique_lock
|
||||||
|
CheckResult_cond.wait(lk, [this]
|
||||||
|
{ return !m_CheckResultList.empty(); }); // 等待直到数据队列非空
|
||||||
|
pResult = m_CheckResultList.front(); // 从队列中取出数
|
||||||
|
m_CheckResultList.pop();
|
||||||
|
lk.unlock();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::ReJson(std::shared_ptr<shareImage> p, std::shared_ptr<CheckResult> &pResult)
|
||||||
|
{
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::CheckImg(std::shared_ptr<shareImage> p, std::shared_ptr<CheckResult> &pResult)
|
||||||
|
{
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::GetStatus()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::UpdateConfig(void *pconfig, int nConfigType)
|
||||||
|
{
|
||||||
|
int re = 0;
|
||||||
|
RunInfoST *tempconfig;
|
||||||
|
switch (nConfigType)
|
||||||
|
{
|
||||||
|
case CHECK_CONFIG_Run:
|
||||||
|
tempconfig = (RunInfoST *)pconfig;
|
||||||
|
m_RunConfig.copy(*tempconfig);
|
||||||
|
break;
|
||||||
|
case CHECK_CONFIG_Module:
|
||||||
|
m_pConfigManager = (ConfigManagerBase *)pconfig;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ALLImgCheckAnalysisy::GetVersion()
|
||||||
|
{
|
||||||
|
return std::string("BOE_2.0.5");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ALLImgCheckAnalysisy::GetErrorInfo()
|
||||||
|
{
|
||||||
|
std::string result = "";
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::ErrorReturn(std::shared_ptr<shareImage> p)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::shared_ptr<CheckResult> result = std::make_shared<CheckResult>();
|
||||||
|
result->in_shareImage = p;
|
||||||
|
result->checkStatus = 1;
|
||||||
|
result->nresult = -CHECK_ERROR_PushImg_ID_Error;
|
||||||
|
result->basicResult.img_id = p->img_id;
|
||||||
|
result->basicResult.imgtype = p->imgtype;
|
||||||
|
result->basicResult.imgstr = p->imgstr;
|
||||||
|
result->basicResult.strChannel = p->strChannel;
|
||||||
|
// printf("ErrorReturn==== %s %s\n", p->strImgProductID.c_str(), p->strChannel.c_str());
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mtx_CheckResult);
|
||||||
|
m_CheckResultList.push(result);
|
||||||
|
}
|
||||||
|
CheckResult_cond.notify_all();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Product> ALLImgCheckAnalysisy::GetProduct(std::string strProduct)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mtx_ProductList);
|
||||||
|
for (int i = 0; i < m_ProductList.size(); i++)
|
||||||
|
{
|
||||||
|
// printf("ddd %s \n", m_ProductList.at(i)->productBaseResult->strproductName.c_str());
|
||||||
|
if (m_ProductList.at(i)->productBaseResult->strproductName == strProduct)
|
||||||
|
{
|
||||||
|
return m_ProductList.at(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::shared_ptr<Product>();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::InitAIFactory()
|
||||||
|
{
|
||||||
|
std::shared_ptr<AIFactory> AI_Factory;
|
||||||
|
AI_Factory = AIFactory::GetInstance();
|
||||||
|
|
||||||
|
GPU_Config gpu;
|
||||||
|
int num = 0;
|
||||||
|
for (int i = 0; i < MAX_GPU_NUM; i++)
|
||||||
|
{
|
||||||
|
gpu.UseGPUList[i] = m_RunConfig.UseGPUList[i];
|
||||||
|
if (gpu.UseGPUList[i] >= 0)
|
||||||
|
{
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (num == 0)
|
||||||
|
{
|
||||||
|
gpu.UseGPUList[0] = 0;
|
||||||
|
gpu.UseGPUList[1] = 1;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < MAX_GPU_NUM; i++)
|
||||||
|
{
|
||||||
|
printf("=====InitAIFactory gpu %d %d \n", i, gpu.UseGPUList[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
AI_Factory->InitALLAIModle(gpu);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::LoadRunConfig(void *p)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::LoadCheckConfig(void *p)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::InitRun()
|
||||||
|
{
|
||||||
|
int re;
|
||||||
|
re = StartThread();
|
||||||
|
if (CHECK_OK != re)
|
||||||
|
{
|
||||||
|
return re;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::StartCheck()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::SetIDLE()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::CheckConfigVersion(void *pconfig1)
|
||||||
|
{
|
||||||
|
int re = 0;
|
||||||
|
VERSION_INFO *pVersionconfig = (VERSION_INFO *)pconfig1;
|
||||||
|
if (pVersionconfig == NULL)
|
||||||
|
{
|
||||||
|
m_nErrorCode = CHECK_ERROR_VERSION; // 参数或接口版本问题
|
||||||
|
return m_nErrorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int v1 = ALL_INTERFACE_VERSION;
|
||||||
|
int v2 = CONFIGBASE_VERSION;
|
||||||
|
int v3 = RESULT_VERSION;
|
||||||
|
printf("**************************** ALL_INTERFACE_VERSION so: %d in:%d CONFIGBASE_VERSION so:%d in:%d RESULT_VERSION so:%d in:%d\n",
|
||||||
|
v1, pVersionconfig->InterfaceVersion, v2, pVersionconfig->ConfigVersion, v3, pVersionconfig->ResultVersion);
|
||||||
|
// 版本控制
|
||||||
|
if (pVersionconfig->InterfaceVersion != ALL_INTERFACE_VERSION ||
|
||||||
|
pVersionconfig->ConfigVersion != CONFIGBASE_VERSION ||
|
||||||
|
pVersionconfig->ResultVersion != RESULT_VERSION)
|
||||||
|
{
|
||||||
|
m_nErrorCode = CHECK_ERROR_VERSION; // 参数或接口版本问题
|
||||||
|
return m_nErrorCode;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::StartThread()
|
||||||
|
{
|
||||||
|
m_bExit = false;
|
||||||
|
|
||||||
|
{ // 开启检测线程
|
||||||
|
ptr_thread_Run = std::make_shared<std::thread>(std::bind(&ALLImgCheckAnalysisy::Run, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::StopThread()
|
||||||
|
{
|
||||||
|
m_bExit = true;
|
||||||
|
if (ptr_thread_Run != nullptr)
|
||||||
|
{
|
||||||
|
if (ptr_thread_Run->joinable())
|
||||||
|
{
|
||||||
|
ptr_thread_Run->join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::ExitSystem()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::InitCameraCheckAnalysisy()
|
||||||
|
{
|
||||||
|
m_pCameraCheckAnalysisyList.clear();
|
||||||
|
// m_pQX_Merge_Analysis->Clear();
|
||||||
|
for (const auto &config : m_pConfigManager->Config_instances_)
|
||||||
|
{
|
||||||
|
std::cout << "key: " << config.first << std::endl;
|
||||||
|
|
||||||
|
std::shared_ptr<CameraCheckAnalysisy> p = std::make_shared<CameraCheckAnalysisy>();
|
||||||
|
|
||||||
|
p->m_RunConfig.copy(m_RunConfig);
|
||||||
|
p->m_pConfig = config.second;
|
||||||
|
int re = p->Init(config.first);
|
||||||
|
if (re != 0)
|
||||||
|
{
|
||||||
|
std::cout << "Init CameraCheckAnalysisy " << config.first << " Failed" << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
m_pCameraCheckAnalysisyList[config.first] = p;
|
||||||
|
// m_pQX_Merge_Analysis->AddCamer(config.first);
|
||||||
|
}
|
||||||
|
if (m_pCameraCheckAnalysisyList.size() < 0)
|
||||||
|
{
|
||||||
|
printf("ALLImgCheckAnalysisy::InitCameraCheckAnalysisy error camera config is null \n");
|
||||||
|
return 1;
|
||||||
|
/* code */
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("ALLImgCheckAnalysisy::InitCameraCheckAnalysisy end \n");
|
||||||
|
// getchar();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::InitData()
|
||||||
|
{
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::Det_Product(std::shared_ptr<Product> &product)
|
||||||
|
{
|
||||||
|
// m_pQX_Merge_Analysis->InitData();
|
||||||
|
// 处理每个相机
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(product->mtx_CameraResultList); //
|
||||||
|
for (auto &ptr : product->m_pCameraResultList)
|
||||||
|
{
|
||||||
|
if (ptr->GetCheckStep() == Check_Step_NODet)
|
||||||
|
{
|
||||||
|
m_pCameraCheckAnalysisyList[ptr->cameraBaseResult->strCameraName]->StartCheck(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断每个相机是否都处理完了。
|
||||||
|
bool bdetComplete = product->bCheckCamplate();
|
||||||
|
// 处理完成,退出循环
|
||||||
|
if (bdetComplete)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 联合分析
|
||||||
|
// AnalysiyAll(0);
|
||||||
|
MergeShowImg(product);
|
||||||
|
SetProductResult(product);
|
||||||
|
printf(">>>>>>>>>>>>>>>Det_Product****************det End************\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Product> ALLImgCheckAnalysisy::GetProduct()
|
||||||
|
{
|
||||||
|
|
||||||
|
std::unique_lock<std::mutex> lk(mtx_ProductList); // 使用 unique_lock
|
||||||
|
ProductList_cond.wait(lk, [this]
|
||||||
|
{ return !m_ProductList.empty(); }); // 等待直到数据队列非空
|
||||||
|
std::shared_ptr<Product> tem = m_ProductList.at(0);
|
||||||
|
lk.unlock();
|
||||||
|
return tem;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::AnalysiyAll(int productIdx)
|
||||||
|
{
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::SetProductResult(std::shared_ptr<Product> product)
|
||||||
|
{
|
||||||
|
|
||||||
|
int nDetCamNum = product->m_pCameraResultList.size();
|
||||||
|
// 相机2的起始位置
|
||||||
|
bool bNG = false;
|
||||||
|
for (int icam = 0; icam < nDetCamNum; icam++)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::shared_ptr<CameraResult> pcam = product->m_pCameraResultList.at(icam);
|
||||||
|
for (int i = 0; i < pcam->ImageALLDetResultList.size(); i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::shared_ptr<CheckResult> pCheckResult = pcam->ImageALLDetResultList.at(i)->result;
|
||||||
|
|
||||||
|
if (pCheckResult->qxImageResult.size() > 0)
|
||||||
|
{
|
||||||
|
bNG = true;
|
||||||
|
}
|
||||||
|
if (bNG)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bNG)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bNG)
|
||||||
|
{
|
||||||
|
for (int icam = 0; icam < nDetCamNum; icam++)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::shared_ptr<CameraResult> pcam = product->m_pCameraResultList.at(icam);
|
||||||
|
for (int i = 0; i < pcam->ImageALLDetResultList.size(); i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::shared_ptr<CheckResult> pCheckResult = pcam->ImageALLDetResultList.at(i)->result;
|
||||||
|
pCheckResult->nProductResult = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::SetSetComplet_New(std::shared_ptr<Product> product, int nerror)
|
||||||
|
{
|
||||||
|
if (product)
|
||||||
|
{
|
||||||
|
|
||||||
|
int nDetCamNum = product->m_pCameraResultList.size();
|
||||||
|
for (int icam = 0; icam < nDetCamNum; icam++)
|
||||||
|
{
|
||||||
|
std::shared_ptr<CameraResult> pcam = product->m_pCameraResultList.at(icam);
|
||||||
|
for (int i = 0; i < pcam->ImageALLDetResultList.size(); i++)
|
||||||
|
{
|
||||||
|
std::shared_ptr<CheckResult> pCheckResult = pcam->ImageALLDetResultList.at(i)->result;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock123(mtx_CheckResult);
|
||||||
|
m_CheckResultList.push(pCheckResult);
|
||||||
|
}
|
||||||
|
CheckResult_cond.notify_all();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::PushInImg_New(std::shared_ptr<shareImage> p)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!m_bInitSucc)
|
||||||
|
{
|
||||||
|
printf("Init fail exit \n");
|
||||||
|
return CHECK_ERROR_Config_Null;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->strParm_WorkCamName = m_pParamName->GetWebConfigCamName_DetImgCamName(p->strCameraName);
|
||||||
|
|
||||||
|
std::string strlog = "";
|
||||||
|
m_strTest += " PushInImg->SN:";
|
||||||
|
m_strTest += p->strImgProductID;
|
||||||
|
m_strTest += " Channel:";
|
||||||
|
m_strTest += p->strChannel;
|
||||||
|
m_strTest += " CameraID:";
|
||||||
|
m_strTest += p->strCameraName;
|
||||||
|
m_strTest += " WorkCamName:";
|
||||||
|
m_strTest += p->strParm_WorkCamName;
|
||||||
|
std::string strBase = "";
|
||||||
|
strBase += " PushInImg->SN:";
|
||||||
|
strBase += p->strImgProductID;
|
||||||
|
strBase += " camera:";
|
||||||
|
strBase += p->strCameraName;
|
||||||
|
|
||||||
|
strBase += " WorkCamName:";
|
||||||
|
strBase += p->strParm_WorkCamName;
|
||||||
|
|
||||||
|
strBase += " Channel:";
|
||||||
|
strBase += p->strChannel;
|
||||||
|
printf("strBase %s p->Status %d\n", strBase.c_str(), p->Status);
|
||||||
|
std::shared_ptr<Product> product;
|
||||||
|
{
|
||||||
|
std::string strcameraName = p->strParm_WorkCamName;
|
||||||
|
|
||||||
|
// 判断 相机名称是否存在
|
||||||
|
if (!m_pCameraCheckAnalysisyList.count(strcameraName) && -1 != p->Status)
|
||||||
|
{
|
||||||
|
|
||||||
|
return CHECK_ERROR_Camear_ID_Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
product = GetProduct(p->strImgProductID);
|
||||||
|
bool ProductID_Exist = false; // 是否存在当前产品ID
|
||||||
|
strlog += "productID ";
|
||||||
|
if (product)
|
||||||
|
{
|
||||||
|
strlog += "exist";
|
||||||
|
ProductID_Exist = true;
|
||||||
|
}
|
||||||
|
// 产品ID存在
|
||||||
|
if(ProductID_Exist)
|
||||||
|
{
|
||||||
|
// 模式为第一张图,返回异常
|
||||||
|
if(IN_IMG_Status_Start == p->Status)
|
||||||
|
{
|
||||||
|
cout << "---ProductID_Exist && IN_IMG_Status_Start == p->Status---" << endl;
|
||||||
|
return CHECK_ERROR_PRODUCT_ID_EXIST;
|
||||||
|
}
|
||||||
|
// 图片都已经完了的状态
|
||||||
|
if(product->bIsImgComplete)
|
||||||
|
{
|
||||||
|
cout << "---ProductID_Exist && product->bIsImgComplete is true---" << endl;
|
||||||
|
ErrorReturn(p);
|
||||||
|
return CHECK_ERROR_PRODUCT_ID_EXIST;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 产品ID不存在
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strlog += "isnot exist";
|
||||||
|
//设置其他m_ProductList送图状态设置为结束
|
||||||
|
cout << "-------set m_ProductList other product to end-------" << endl ;
|
||||||
|
for(auto &tem:m_ProductList){
|
||||||
|
tem->bIsImgComplete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 产品不存在 新建一个
|
||||||
|
if (!product)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mtx_ProductList);
|
||||||
|
{
|
||||||
|
if (m_ProductList.size() > 50)
|
||||||
|
{
|
||||||
|
|
||||||
|
return CHECK_ERROR_PushImg_ListSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strlog += " | create new product";
|
||||||
|
product = std::make_shared<Product>();
|
||||||
|
product->productBaseResult->strproductName = p->strImgProductID;
|
||||||
|
m_ProductList.push_back(product);
|
||||||
|
std::string strTimg = CheckUtil::getCurTimeHMS();
|
||||||
|
product->productBaseResult->detlog->bPrintStr = true;
|
||||||
|
product->productBaseResult->detlog->AddCheckstr(PrintLevel_0, "PushInImg", "add new product %s %s ", p->strImgProductID.c_str(), strTimg.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strlog += " | product: ";
|
||||||
|
strlog += product->productBaseResult->strproductName;
|
||||||
|
// printf("Product Is %s \n", product->productBaseResult->strproductName.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 送入图的状态 结束
|
||||||
|
if(-1 == p->Status)
|
||||||
|
{
|
||||||
|
strlog += " | p->Status == -1, set product complete";
|
||||||
|
product->bIsImgComplete = true;
|
||||||
|
}
|
||||||
|
// 送入图的状态 不是结束
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strlog += " | create new camera result";
|
||||||
|
// 对应相机的 检测结果
|
||||||
|
std::shared_ptr<CameraResult> pCamera = product->GetCameraResult(strcameraName);
|
||||||
|
|
||||||
|
if (pCamera.get() == nullptr)
|
||||||
|
{
|
||||||
|
strlog += " | CHECK_ERROR_Camear_ID_Error";
|
||||||
|
product->productBaseResult->detlog->bPrintStr = true;
|
||||||
|
product->productBaseResult->detlog->AddCheckstr(PrintLevel_1, "PushInImg end", "%s", strlog.c_str());
|
||||||
|
ErrorReturn(p);
|
||||||
|
return CHECK_ERROR_Camear_ID_Error;
|
||||||
|
}
|
||||||
|
// 添加产品信息
|
||||||
|
pCamera->AddDetImage(p);
|
||||||
|
}
|
||||||
|
product->UpdatePushStatus(p->Status);
|
||||||
|
if (IN_IMG_Status_End == p->Status)
|
||||||
|
{
|
||||||
|
strlog += " | p->Status == IN_IMG_Status_End, set product complete";
|
||||||
|
product->bIsImgComplete = true;
|
||||||
|
m_strTest += "\n";
|
||||||
|
product->AddLog(m_strTest);
|
||||||
|
m_strTest = "";
|
||||||
|
}
|
||||||
|
product->productBaseResult->detlog->bPrintStr = true;
|
||||||
|
product->productBaseResult->detlog->AddCheckstr(PrintLevel_0, "PushInImg end", "%s", strlog.c_str());
|
||||||
|
ProductList_cond.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
cv::Mat ALLImgCheckAnalysisy::hconcatWithFirstBase(const cv::Mat &img1, const cv::Mat &img2,
|
||||||
|
int interpolation = cv::INTER_LINEAR)
|
||||||
|
{
|
||||||
|
// 如果高度相同,直接拼接
|
||||||
|
if (img1.rows == img2.rows)
|
||||||
|
{
|
||||||
|
cv::Mat result;
|
||||||
|
cv::hconcat(img1, img2, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算缩放比例
|
||||||
|
double scale = static_cast<double>(img1.rows) / img2.rows;
|
||||||
|
|
||||||
|
// 调整img2的高度
|
||||||
|
cv::Mat img2_resized;
|
||||||
|
cv::resize(img2, img2_resized, cv::Size(), scale, scale, interpolation);
|
||||||
|
|
||||||
|
// 拼接
|
||||||
|
cv::Mat result;
|
||||||
|
cv::hconcat(img1, img2_resized, result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
int ALLImgCheckAnalysisy::MergeShowImg(std::shared_ptr<Product> product)
|
||||||
|
{
|
||||||
|
int nDetCamNum = product->m_pCameraResultList.size();
|
||||||
|
// printf("MergeShowImg %s \n", product->productBaseResult->strproductName.c_str());
|
||||||
|
// 2个相机才操作
|
||||||
|
if (nDetCamNum == 2)
|
||||||
|
{
|
||||||
|
std::shared_ptr<CameraResult> pcam_0 = product->m_pCameraResultList.at(0);
|
||||||
|
std::shared_ptr<CameraResult> pcam_1 = product->m_pCameraResultList.at(1);
|
||||||
|
for (int i = 0; i < pcam_0->ImageALLDetResultList.size(); i++)
|
||||||
|
{
|
||||||
|
std::shared_ptr<CheckResult> pCheckResult_0 = pcam_0->ImageALLDetResultList.at(i)->result;
|
||||||
|
// printf("cam %s channel %s \n", pcam_0->cameraBaseResult->strCameraName.c_str(),
|
||||||
|
// pCheckResult_0->in_shareImage->strChannel.c_str());
|
||||||
|
for (int j = 0; j < pcam_1->ImageALLDetResultList.size(); j++)
|
||||||
|
{
|
||||||
|
std::shared_ptr<CheckResult> pCheckResult_1 = pcam_1->ImageALLDetResultList.at(j)->result;
|
||||||
|
|
||||||
|
if (pCheckResult_1->in_shareImage->strChannel == pCheckResult_0->in_shareImage->strChannel)
|
||||||
|
{
|
||||||
|
// printf("cam %s channel %s \n", pcam_1->cameraBaseResult->strCameraName.c_str(),
|
||||||
|
// pCheckResult_1->in_shareImage->strChannel.c_str());
|
||||||
|
|
||||||
|
if (!pCheckResult_0->resultimg.empty() && !pCheckResult_1->resultimg.empty())
|
||||||
|
{
|
||||||
|
cv::Mat meregeimg;
|
||||||
|
if (pCheckResult_0->in_shareImage->strCameraName == "left")
|
||||||
|
{
|
||||||
|
meregeimg = hconcatWithFirstBase(pCheckResult_0->resultimg, pCheckResult_1->resultimg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meregeimg = hconcatWithFirstBase(pCheckResult_1->resultimg, pCheckResult_0->resultimg);
|
||||||
|
}
|
||||||
|
|
||||||
|
pCheckResult_0->resultimg = meregeimg;
|
||||||
|
pCheckResult_1->resultimg = meregeimg;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ALLImgCheckAnalysisy::Run()
|
||||||
|
{
|
||||||
|
|
||||||
|
while (!m_bExit)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||||
|
|
||||||
|
std::shared_ptr<Product> product = GetProduct();
|
||||||
|
|
||||||
|
int re = Det_Product(product);
|
||||||
|
// // 检测失败
|
||||||
|
// if (re != 0)
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
SetSetComplet_New(product, re);
|
||||||
|
|
||||||
|
// 更新 产品队列
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mtx_ProductList); //
|
||||||
|
if (!m_ProductList.empty())
|
||||||
|
{
|
||||||
|
m_ProductList.erase(m_ProductList.begin());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int ALLImgCheckAnalysisy::set_cpu_id(const std::vector<int> &cpu_set_vec)
|
||||||
|
{
|
||||||
|
// for cpu affinity
|
||||||
|
int nRet = 0;
|
||||||
|
#ifdef __linux
|
||||||
|
cpu_set_t _cur_cpu_set;
|
||||||
|
CPU_ZERO(&_cur_cpu_set);
|
||||||
|
for (auto _id : cpu_set_vec)
|
||||||
|
{
|
||||||
|
CPU_SET(_id, &_cur_cpu_set);
|
||||||
|
}
|
||||||
|
if (0 > pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &_cur_cpu_set))
|
||||||
|
{
|
||||||
|
perror("set cpu affinity failed: ");
|
||||||
|
printf("Warning: set cpu affinity failed ... ...\n");
|
||||||
|
nRet = -1;
|
||||||
|
}
|
||||||
|
#endif //__linux
|
||||||
|
return nRet;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,250 @@
|
|||||||
|
/*
|
||||||
|
* @Author: xiewenji 527774126@qq.com
|
||||||
|
* @Date: 2025-09-13 20:39:37
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @LastEditTime: 2025-09-24 14:17:12
|
||||||
|
* @FilePath: /BOE_CELL_AOI_Detect/AlgorithmModule/src/CameraResult.cpp
|
||||||
|
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
*/
|
||||||
|
#include "CameraResult.h"
|
||||||
|
|
||||||
|
CameraResult::CameraResult()
|
||||||
|
{
|
||||||
|
cameraBaseResult = std::make_shared<CameraBaseResult>();
|
||||||
|
detlog = std::make_shared<DetLog>();
|
||||||
|
time_start = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CameraResult::~CameraResult()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraResult::AddLog(std::string str)
|
||||||
|
{
|
||||||
|
LogList.push_back(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CameraResult::AddDetImage(std::shared_ptr<shareImage> p)
|
||||||
|
{
|
||||||
|
if (time_start == 0)
|
||||||
|
{
|
||||||
|
time_start = CheckUtil::getcurTime();
|
||||||
|
/* code */
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<ImageAllResult> imgResult = std::make_shared<ImageAllResult>();
|
||||||
|
imgResult->cameraBaseResult = cameraBaseResult;
|
||||||
|
imgResult->productBaseResult = productBaseResult;
|
||||||
|
if (p->Det_Mode == DET_MODE_ReJson)
|
||||||
|
{
|
||||||
|
bJson = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
imgResult->AddDetImage(p);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_DetImageList);
|
||||||
|
ImageALLDetResultList.push_back(imgResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_Det);
|
||||||
|
|
||||||
|
if (p->strChannel == "L255")
|
||||||
|
{
|
||||||
|
bHave_L255 = true;
|
||||||
|
}
|
||||||
|
if (p->strChannel == "Down-Particle")
|
||||||
|
{
|
||||||
|
bHave_DP = true;
|
||||||
|
}
|
||||||
|
if (p->strChannel == "Up-Particle")
|
||||||
|
{
|
||||||
|
bHave_Up = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string strTimg = CheckUtil::getCurTimeHMS();
|
||||||
|
detlog->bPrintStr = false;
|
||||||
|
detlog->AddCheckstr(PrintLevel_0, "PushInImg", " product %s Cam %s add new image channel = %s sum img %ld %s",
|
||||||
|
productBaseResult->strproductName.c_str(),
|
||||||
|
cameraBaseResult->strCameraName.c_str(), imgResult->strChannel.c_str(), ImageALLDetResultList.size(), strTimg.c_str());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CameraResult::bCheckCamplate()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_Det);
|
||||||
|
|
||||||
|
if (checkStep == Check_Step_Complete)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Check_Step CameraResult::GetCheckStep()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_Det);
|
||||||
|
return checkStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraResult::SetCheckStep(Check_Step step)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_Det);
|
||||||
|
checkStep = step;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CameraResult::getImgPushComplate()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_Det);
|
||||||
|
return bIsImgComplete;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraResult::setImgPushComplate()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_Det);
|
||||||
|
bIsImgComplete = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CameraResult::IsHaveL255()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_Det);
|
||||||
|
return bHave_L255;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CameraResult::Have_EdgeImg(std::string strConfig_Channel)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_DetImageList);
|
||||||
|
for (auto ptr : ImageALLDetResultList)
|
||||||
|
{
|
||||||
|
if (ptr->IsChannel(strConfig_Channel))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraResult::SetHaveL255(bool b)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_Det);
|
||||||
|
bHave_L255 = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CameraResult::IsHaveDP()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_Det);
|
||||||
|
return bHave_DP;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraResult::SetHaveDP(bool b)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_Det);
|
||||||
|
bHave_DP = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CameraResult::IsHaveUp()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_Det);
|
||||||
|
return bHave_Up;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraResult::SetHaveUp(bool b)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_Det);
|
||||||
|
bHave_Up = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<ImageAllResult> CameraResult::GetNoDetImg()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_DetImageList);
|
||||||
|
|
||||||
|
// 优先 up 然后是 dp
|
||||||
|
for (auto ptr : ImageALLDetResultList)
|
||||||
|
{
|
||||||
|
if (ptr->IsChannel("Up-Particle"))
|
||||||
|
{
|
||||||
|
if (ptr->IsNotDet())
|
||||||
|
{
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto ptr : ImageALLDetResultList)
|
||||||
|
{
|
||||||
|
if (ptr->IsChannel("Down-Particle"))
|
||||||
|
{
|
||||||
|
if (ptr->IsNotDet())
|
||||||
|
{
|
||||||
|
bool bok = true;
|
||||||
|
|
||||||
|
if (ptr->config_update.wait_UP &&
|
||||||
|
cameraBaseResult->UpImg_Status != CameraBaseResult::ImageDet_Status_DetComplete)
|
||||||
|
{
|
||||||
|
bok = false;
|
||||||
|
}
|
||||||
|
if (bok)
|
||||||
|
{
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto ptr : ImageALLDetResultList)
|
||||||
|
{
|
||||||
|
// 参数更新过了
|
||||||
|
if (ptr->config_update.bUpdate)
|
||||||
|
{
|
||||||
|
// 未检测的
|
||||||
|
if (ptr->IsNotDet())
|
||||||
|
{
|
||||||
|
bool bok = true;
|
||||||
|
// // 等待DP DP 没有 检测完成
|
||||||
|
if (ptr->config_update.wait_DP &&
|
||||||
|
cameraBaseResult->DPImg_Status != CameraBaseResult::ImageDet_Status_DetComplete)
|
||||||
|
{
|
||||||
|
bok = false;
|
||||||
|
}
|
||||||
|
if (ptr->config_update.wait_UP &&
|
||||||
|
cameraBaseResult->UpImg_Status != CameraBaseResult::ImageDet_Status_DetComplete)
|
||||||
|
{
|
||||||
|
bok = false;
|
||||||
|
}
|
||||||
|
if (bok)
|
||||||
|
{
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<ImageAllResult> CameraResult::GetL255DetImg()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_DetImageList);
|
||||||
|
for (auto ptr : ImageALLDetResultList)
|
||||||
|
{
|
||||||
|
if (ptr->IsChannel("L255"))
|
||||||
|
{
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<ImageAllResult> CameraResult::GetEdgeChannel(std::string strConfig_Channel)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_DetImageList);
|
||||||
|
for (auto ptr : ImageALLDetResultList)
|
||||||
|
{
|
||||||
|
if (ptr->IsChannel(strConfig_Channel))
|
||||||
|
{
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
#include "CheckErrorCodeDefine.hpp"
|
||||||
|
std::string GetErrorCodeInfo(int nErrorCode)
|
||||||
|
{
|
||||||
|
std::string str = "";
|
||||||
|
switch (nErrorCode)
|
||||||
|
{
|
||||||
|
case CHECK_OK:
|
||||||
|
str = "OK";
|
||||||
|
break;
|
||||||
|
case CHECK_ERROR_VERSION:
|
||||||
|
str = "interface version or config version error";
|
||||||
|
break;
|
||||||
|
case CHECK_ERROR_Config_Null:
|
||||||
|
str = "prt* config is null";
|
||||||
|
break;
|
||||||
|
case CHECK_ERROR_Config_Value:
|
||||||
|
str = "config value error";
|
||||||
|
break;
|
||||||
|
case CHECK_ERROR_Path_NULL:
|
||||||
|
str = "file Path is Null";
|
||||||
|
break;
|
||||||
|
case CHECK_ERROR_Mask_Empty:
|
||||||
|
str = "mask Image is empty";
|
||||||
|
break;
|
||||||
|
case CHECK_ERROR_Config_cutRoi:
|
||||||
|
str = "config Rect Value error";
|
||||||
|
break;
|
||||||
|
case CHECK_ERROR_CheckImg_Empty:
|
||||||
|
str = "check image is empty";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
@ -0,0 +1,173 @@
|
|||||||
|
#include "CheckResultJson.h"
|
||||||
|
|
||||||
|
Json::Value CheckResultJson::toJsonValue()
|
||||||
|
{
|
||||||
|
Json::Value root;
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
root["cutRoi"]["x"] = m_pOneImgDetResult->CutRoi.x;
|
||||||
|
root["cutRoi"]["y"] = m_pOneImgDetResult->CutRoi.y;
|
||||||
|
root["cutRoi"]["width"] = m_pOneImgDetResult->CutRoi.width;
|
||||||
|
root["cutRoi"]["height"] = m_pOneImgDetResult->CutRoi.height;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
|
||||||
|
root["Param_CropRoi"]["x"] = m_pOneImgDetResult->Param_CropRoi.x;
|
||||||
|
root["Param_CropRoi"]["y"] = m_pOneImgDetResult->Param_CropRoi.y;
|
||||||
|
root["Param_CropRoi"]["width"] = m_pOneImgDetResult->Param_CropRoi.width;
|
||||||
|
root["Param_CropRoi"]["height"] = m_pOneImgDetResult->Param_CropRoi.height;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < m_pOneImgDetResult->pQx_ErrorList->size(); i++)
|
||||||
|
{
|
||||||
|
QX_ERROR_INFO_ *p = &m_pOneImgDetResult->pQx_ErrorList->at(i);
|
||||||
|
Json::Value value;
|
||||||
|
{
|
||||||
|
|
||||||
|
value["Idx"] = p->Idx;
|
||||||
|
value["result"] = p->result;
|
||||||
|
value["result_Name"] = p->result_name;
|
||||||
|
value["roi"]["x"] = p->roi.x;
|
||||||
|
value["roi"]["y"] = p->roi.y;
|
||||||
|
value["roi"]["width"] = p->roi.width;
|
||||||
|
value["roi"]["height"] = p->roi.height;
|
||||||
|
value["area"] = p->area;
|
||||||
|
value["energy"] = p->energy;
|
||||||
|
value["JudgArea"] = p->JudgArea;
|
||||||
|
value["JudgArea_second"] = p->JudgArea_second;
|
||||||
|
value["flen"] = p->flen;
|
||||||
|
value["nconfig_qx_type"] = p->nconfig_qx_type;
|
||||||
|
value["qx_name"] = p->qx_name;
|
||||||
|
value["maxValue"] = p->maxValue;
|
||||||
|
value["grayDis"] = p->grayDis;
|
||||||
|
value["fUpIou"] = p->fUpIou;
|
||||||
|
value["density"] = p->density;
|
||||||
|
// return root;
|
||||||
|
for (int jr = 0; jr < p->detRegionidxList.size(); jr++)
|
||||||
|
{
|
||||||
|
|
||||||
|
value["regionlist"].append(p->detRegionidxList[jr]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
root["Qx"].append(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckResultJson::toObjectFromValue(Json::Value root)
|
||||||
|
{
|
||||||
|
|
||||||
|
m_pOneImgDetResult = std::make_shared<One_Image_CheckResult_>();
|
||||||
|
m_pOneImgDetResult->pQx_ErrorList = std::make_shared<std::vector<QX_ERROR_INFO_>>();
|
||||||
|
// std::cout << root << std::endl;
|
||||||
|
|
||||||
|
{
|
||||||
|
auto value = root["cutRoi"];
|
||||||
|
if (value.isObject())
|
||||||
|
{
|
||||||
|
|
||||||
|
m_pOneImgDetResult->CutRoi.x = root["cutRoi"]["x"].asInt();
|
||||||
|
m_pOneImgDetResult->CutRoi.y = root["cutRoi"]["y"].asInt();
|
||||||
|
m_pOneImgDetResult->CutRoi.width = root["cutRoi"]["width"].asInt();
|
||||||
|
m_pOneImgDetResult->CutRoi.height = root["cutRoi"]["height"].asInt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto value = root["Param_CropRoi"];
|
||||||
|
if (value.isObject())
|
||||||
|
{
|
||||||
|
|
||||||
|
m_pOneImgDetResult->Param_CropRoi.x = root["Param_CropRoi"]["x"].asInt();
|
||||||
|
m_pOneImgDetResult->Param_CropRoi.y = root["Param_CropRoi"]["y"].asInt();
|
||||||
|
m_pOneImgDetResult->Param_CropRoi.width = root["Param_CropRoi"]["width"].asInt();
|
||||||
|
m_pOneImgDetResult->Param_CropRoi.height = root["Param_CropRoi"]["height"].asInt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
if (root.isMember("Qx"))
|
||||||
|
{
|
||||||
|
|
||||||
|
const Json::Value &errorList = root["Qx"];
|
||||||
|
for (const auto &errorJson : errorList)
|
||||||
|
{
|
||||||
|
|
||||||
|
QX_ERROR_INFO_ tem;
|
||||||
|
tem.Idx = errorJson["Idx"].asInt();
|
||||||
|
|
||||||
|
// tem.result = errorJson["result"].asInt();
|
||||||
|
// tem.result_name = errorJson["result_Name"].asString();
|
||||||
|
|
||||||
|
tem.roi.x = errorJson["roi"]["x"].asInt();
|
||||||
|
tem.roi.y = errorJson["roi"]["y"].asInt();
|
||||||
|
tem.roi.width = errorJson["roi"]["width"].asInt();
|
||||||
|
tem.roi.height = errorJson["roi"]["height"].asInt();
|
||||||
|
tem.area = errorJson["area"].asInt();
|
||||||
|
tem.energy = errorJson["energy"].asInt();
|
||||||
|
tem.JudgArea = errorJson["JudgArea"].asFloat();
|
||||||
|
if (errorJson["JudgArea_second"])
|
||||||
|
{
|
||||||
|
tem.JudgArea_second = errorJson["JudgArea_second"].asFloat();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tem.JudgArea_second = tem.JudgArea;
|
||||||
|
}
|
||||||
|
|
||||||
|
tem.flen = errorJson["flen"].asFloat();
|
||||||
|
tem.nconfig_qx_type = errorJson["nconfig_qx_type"].asInt();
|
||||||
|
tem.qx_name = errorJson["qx_name"].asString();
|
||||||
|
tem.maxValue = errorJson["maxValue"].asInt();
|
||||||
|
tem.grayDis = errorJson["grayDis"].asFloat();
|
||||||
|
tem.fUpIou = errorJson["fUpIou"].asFloat();
|
||||||
|
tem.density = errorJson["density"].asFloat();
|
||||||
|
|
||||||
|
const Json::Value ®ionvalue = errorJson["regionlist"];
|
||||||
|
|
||||||
|
if (regionvalue.isArray())
|
||||||
|
{
|
||||||
|
// std::cout<<regionvalue<<std::endl;
|
||||||
|
for (const auto ®ion : regionvalue)
|
||||||
|
{
|
||||||
|
tem.detRegionidxList.push_back(region.asInt());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pOneImgDetResult->pQx_ErrorList->push_back(tem);
|
||||||
|
|
||||||
|
// tem.print(std::to_string(m_pOneImgDetResult->pQx_ErrorList->size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int CheckResultJson::GetConfig(std::string strJson, std::shared_ptr<One_Image_CheckResult_> &pOneImgDetResult)
|
||||||
|
{
|
||||||
|
Json::CharReader *reader = readerBuilder.newCharReader();
|
||||||
|
string errs;
|
||||||
|
bool parsingSuccessful = reader->parse(strJson.c_str(), strJson.c_str() + strJson.size(), &root, &errs);
|
||||||
|
delete reader;
|
||||||
|
if (!parsingSuccessful)
|
||||||
|
{
|
||||||
|
cout << "Failed to parse JSON string: " << errs << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
toObjectFromValue(root);
|
||||||
|
pOneImgDetResult = m_pOneImgDetResult;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CheckResultJson::GetResultString(std::shared_ptr<One_Image_CheckResult_> &pOneImgDetResult)
|
||||||
|
{
|
||||||
|
m_pOneImgDetResult = pOneImgDetResult;
|
||||||
|
if (m_pOneImgDetResult == nullptr || m_pOneImgDetResult->pQx_ErrorList == nullptr)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value root = toJsonValue();
|
||||||
|
Json::StreamWriterBuilder writerBuilder;
|
||||||
|
std::string jsonString = Json::writeString(writerBuilder, root);
|
||||||
|
|
||||||
|
return jsonString;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
* @Author: xiewenji 527774126@qq.com
|
||||||
|
* @Date: 2025-09-13 20:39:37
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @LastEditTime: 2025-09-24 14:17:55
|
||||||
|
* @FilePath: /BOE_CELL_AOI_Detect/AlgorithmModule/src/CameraResult.cpp
|
||||||
|
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
*/
|
||||||
|
#include "ImageAllResult.h"
|
||||||
|
|
||||||
|
ImageAllResult::ImageAllResult()
|
||||||
|
{
|
||||||
|
detlog = std::make_shared<DetLog>();
|
||||||
|
pDetResult = std::make_shared<One_Image_CheckResult_>();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageAllResult::~ImageAllResult()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageAllResult::AddLog(std::string str)
|
||||||
|
{
|
||||||
|
LogList.push_back(str);
|
||||||
|
}
|
||||||
|
ImageAllResult::DetStep ImageAllResult::getStep()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_Det);
|
||||||
|
return m_step;
|
||||||
|
}
|
||||||
|
void ImageAllResult::setStep(DetStep step)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_Det);
|
||||||
|
m_step = step;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImageAllResult::IsNotDet()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_Det);
|
||||||
|
if (m_step == DetStep_NotDet)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImageAllResult::IsChannel(std::string strChannelName)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_Det);
|
||||||
|
if (strChannel == strChannelName)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ImageAllResult::AddDetImage(std::shared_ptr<shareImage> p)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock_cam(mtx_Det);
|
||||||
|
result = std::make_shared<CheckResult>();
|
||||||
|
p->time_PushIn = CheckUtil::getcurTime();
|
||||||
|
result->in_shareImage = p;
|
||||||
|
result->checkStatus = 1;
|
||||||
|
result->nDetStep = 0;
|
||||||
|
result->nresult = -1;
|
||||||
|
result->basicResult.img_id = p->img_id;
|
||||||
|
result->basicResult.imgtype = p->imgtype;
|
||||||
|
result->basicResult.imgstr = p->imgstr;
|
||||||
|
result->basicResult.strChannel = p->strChannel;
|
||||||
|
|
||||||
|
strChannel = p->strChannel;
|
||||||
|
|
||||||
|
if (strChannel == "Up-Particle")
|
||||||
|
{
|
||||||
|
cameraBaseResult->UpImg_Status = CameraBaseResult::ImageDet_Status_NoDet;
|
||||||
|
}
|
||||||
|
if (strChannel == "Down-Particle")
|
||||||
|
{
|
||||||
|
cameraBaseResult->DPImg_Status = CameraBaseResult::ImageDet_Status_NoDet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 需要指定 黑白画面
|
||||||
|
if (strChannel == "BTW" ||
|
||||||
|
strChannel == "WTB" ||
|
||||||
|
strChannel == "TBW" ||
|
||||||
|
strChannel == "HB3" ||
|
||||||
|
strChannel == "HB4")
|
||||||
|
{
|
||||||
|
bWhiteOrBlackImg = true;
|
||||||
|
}
|
||||||
|
strBaseInfo = productBaseResult->strproductName + " cam " + cameraBaseResult->strCameraName + " channel " + strChannel;
|
||||||
|
|
||||||
|
if (p->Det_Mode == DET_MODE_ReJson)
|
||||||
|
{
|
||||||
|
m_CheckResultJson.GetConfig(p->resultJson, pDetResult);
|
||||||
|
|
||||||
|
fscale_detToresult_x = 1;
|
||||||
|
fscale_detToresult_y = 1;
|
||||||
|
// 图片
|
||||||
|
if (!p->img.empty())
|
||||||
|
{
|
||||||
|
detImg = p->img;
|
||||||
|
/* code */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pDetResult->CutRoi.width > 0 && pDetResult->CutRoi.height > 0)
|
||||||
|
{
|
||||||
|
detImg = cv::Mat::zeros(pDetResult->CutRoi.height, pDetResult->CutRoi.width, CV_8UC1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
detImg = cv::Mat::zeros(1000, 2000, CV_8UC1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
cv::Size sz;
|
||||||
|
sz.width = RESIZE_IMAGE_WIDTH;
|
||||||
|
|
||||||
|
float fw = RESIZE_IMAGE_WIDTH * 1.0f / detImg.cols;
|
||||||
|
sz.height = int(detImg.rows * fw);
|
||||||
|
|
||||||
|
cv::resize(detImg, resultImg, sz);
|
||||||
|
if (resultImg.channels() == 1)
|
||||||
|
{
|
||||||
|
cv::cvtColor(resultImg, resultImg, cv::COLOR_GRAY2BGR);
|
||||||
|
}
|
||||||
|
|
||||||
|
result->resultimg = resultImg;
|
||||||
|
|
||||||
|
result->cutSrcimg = detImg;
|
||||||
|
|
||||||
|
fscale_detToresult_x = resultImg.cols * 1.0f / detImg.cols;
|
||||||
|
fscale_detToresult_y = resultImg.rows * 1.0f / detImg.rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pDetResult->print("result");
|
||||||
|
// getchar();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* @Author: your name
|
||||||
|
* @Date: 2022-04-20 15:50:00
|
||||||
|
* @LastEditTime: 2022-09-26 16:27:27
|
||||||
|
* @LastEditors: sueRimn
|
||||||
|
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
* @FilePath: /ZCXD_MonitorPlatform/src/CoreLogicModule/src/CamDeal.cpp
|
||||||
|
*/
|
||||||
|
#include "ImageDetBase.h"
|
||||||
|
#include "ImgCheckAnalysisy.hpp"
|
||||||
|
ImgCheckBase *ImgCheckBase::GetInstance()
|
||||||
|
{
|
||||||
|
return (ImgCheckBase *)new ImgCheckAnalysisy();
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
#include "ImageDetConfig.h"
|
||||||
|
#include "QX_Merge_Analysis.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
// ProductBaseResult::ProductBaseResult()
|
||||||
|
// {
|
||||||
|
// pQX_Merge_Analysis = QX_Merge_Analysis::GetInstance();
|
||||||
|
// pQX_Merge_Analysis->InitData();
|
||||||
|
// }
|
||||||
@ -0,0 +1,801 @@
|
|||||||
|
|
||||||
|
#include "ImageMerge.h"
|
||||||
|
#include "CheckUtil.hpp"
|
||||||
|
#include "CheckErrorCodeDefine.hpp"
|
||||||
|
|
||||||
|
ImageMerge::ImageMerge()
|
||||||
|
{
|
||||||
|
bshowimg = false;
|
||||||
|
m_bcalSucc = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageMerge::~ImageMerge() {}
|
||||||
|
|
||||||
|
int ImageMerge::CalMergeRoi(DetConfig *pDetConfig, cv::Mat &img1, const cv::Mat &img2)
|
||||||
|
{
|
||||||
|
// cv::imwrite("merge1.png", img1);
|
||||||
|
// cv::imwrite("merge2.png", img2);
|
||||||
|
m_bcalSucc = false;
|
||||||
|
std::cout << img1.size() << std::endl;
|
||||||
|
std::cout << img2.size() << std::endl;
|
||||||
|
// if (img1.size() != img2.size())
|
||||||
|
// {
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
long t1, t2;
|
||||||
|
t1 = CheckUtil::getcurTime();
|
||||||
|
int re = 0;
|
||||||
|
cv::Rect Left_Roi;
|
||||||
|
cv::Rect Right_Roi;
|
||||||
|
|
||||||
|
bool bleft = ProductSide_left(img1);
|
||||||
|
cv::Mat leftImg = img1;
|
||||||
|
cv::Mat rightImg = img2;
|
||||||
|
m_bleft_img1 = bleft;
|
||||||
|
if (bleft)
|
||||||
|
{
|
||||||
|
leftImg = img1;
|
||||||
|
rightImg = img2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
leftImg = img2;
|
||||||
|
rightImg = img1;
|
||||||
|
}
|
||||||
|
int max_len = img1.cols;
|
||||||
|
if (img2.cols > max_len)
|
||||||
|
{
|
||||||
|
max_len = img2.cols;
|
||||||
|
}
|
||||||
|
m_ALLImgSize.width = max_len * 2;
|
||||||
|
m_ALLImgSize.height = rightImg.rows;
|
||||||
|
|
||||||
|
// cv::Mat AllImg = cv::Mat::zeros(rightImg.rows, max_len * 2, rightImg.type());
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
cv::Rect Left_Tem_Roi;
|
||||||
|
cv::Point Left_Tem_Point_Up;
|
||||||
|
cv::Point Left_Tem_Point_Donw;
|
||||||
|
cv::Rect Right_Tem_Roi;
|
||||||
|
cv::Point Right_Tem_Point_Up;
|
||||||
|
cv::Point Right_Tem_Point_Donw;
|
||||||
|
// left Img
|
||||||
|
|
||||||
|
{
|
||||||
|
re = GetRectAndPoint(leftImg, Left_Tem_Roi, Left_Tem_Point_Up, Left_Tem_Point_Donw, true, pDetConfig->strcam, pDetConfig->strchannel + "left");
|
||||||
|
if (re != 0)
|
||||||
|
{
|
||||||
|
// m_pdetlog->AddCheckstr(PrintLevel_1, "Detect_Pre", "Cam %s Mergimg GetRectAndPoint TAA error %d", strcam.c_str(), re);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
re = GetRectAndPoint(rightImg, Right_Tem_Roi, Right_Tem_Point_Up, Right_Tem_Point_Donw, false, pDetConfig->strcam, pDetConfig->strchannel + "right");
|
||||||
|
if (re != 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
cv::Rect roi_right;
|
||||||
|
roi_right.x = 0;
|
||||||
|
roi_right.y = 0;
|
||||||
|
roi_right.height = rightImg.rows;
|
||||||
|
roi_right.width = rightImg.cols;
|
||||||
|
|
||||||
|
m_roi_right_img = roi_right;
|
||||||
|
m_roi_right_ALLimg = roi_right;
|
||||||
|
|
||||||
|
// rightImg(roi_right).copyTo(AllImg(roi_right));
|
||||||
|
|
||||||
|
int hlen_left = Left_Tem_Point_Donw.y - Left_Tem_Point_Up.y;
|
||||||
|
int hlen_right = Right_Tem_Point_Donw.y - Right_Tem_Point_Up.y;
|
||||||
|
float fhscle = hlen_right * 1.0f / hlen_left;
|
||||||
|
int dy = Right_Tem_Point_Up.y - Left_Tem_Point_Up.y;
|
||||||
|
cv::Rect allroi = Left_Tem_Roi;
|
||||||
|
allroi.height *= fhscle;
|
||||||
|
allroi.x = Right_Tem_Roi.x + Right_Tem_Roi.width;
|
||||||
|
allroi.y += dy;
|
||||||
|
|
||||||
|
// cv::Size sz;
|
||||||
|
// sz.width = allroi.width;
|
||||||
|
// sz.height = allroi.height;
|
||||||
|
m_roi_left_img = Left_Tem_Roi;
|
||||||
|
m_roi_left_ALLimg = allroi;
|
||||||
|
// cv::resize(leftImg(Left_Tem_Roi), AllImg(allroi), sz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bcalSucc = true;
|
||||||
|
re = detMergeImg(img1, img2);
|
||||||
|
if (re != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// img1 = AllImg;
|
||||||
|
t2 = CheckUtil::getcurTime();
|
||||||
|
//cv::imwrite(pDetConfig->strcam + pDetConfig->strchannel + "_merg.png", img1);
|
||||||
|
// m_pdetlog->AddCheckstr(PrintLevel_1, "Detect_Pre", "Cam %s Mergimg use time %ld ms", pDetConfig->strcam.c_str(), t2 - t1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ImageMerge::detMergeImg(cv::Mat &img1, const cv::Mat &img2)
|
||||||
|
{
|
||||||
|
if (m_bcalSucc == false)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
cv::Mat AllImg = cv::Mat::zeros(m_ALLImgSize.height, m_ALLImgSize.width, img1.type());
|
||||||
|
cv::Mat leftImg = img1;
|
||||||
|
cv::Mat rightImg = img2;
|
||||||
|
|
||||||
|
if (m_bleft_img1)
|
||||||
|
{
|
||||||
|
leftImg = img1;
|
||||||
|
rightImg = img2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
leftImg = img2;
|
||||||
|
rightImg = img1;
|
||||||
|
}
|
||||||
|
rightImg(m_roi_right_img).copyTo(AllImg(m_roi_right_ALLimg));
|
||||||
|
|
||||||
|
cv::Size sz;
|
||||||
|
sz.width = m_roi_left_ALLimg.width;
|
||||||
|
sz.height = m_roi_left_ALLimg.height;
|
||||||
|
|
||||||
|
cv::resize(leftImg(m_roi_left_img), AllImg(m_roi_left_ALLimg), sz);
|
||||||
|
img1 = AllImg;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ImageMerge::GetRectAndPoint(const cv::Mat &img, cv::Rect &roi, cv::Point &merg_p_up, cv::Point &merg_p_down, bool bleft, std::string strcam, std::string strchannel)
|
||||||
|
{
|
||||||
|
bshowimg = true;
|
||||||
|
|
||||||
|
int A_line_up = 0;
|
||||||
|
int A_line_down = 0;
|
||||||
|
|
||||||
|
Edge_Search_Config config;
|
||||||
|
|
||||||
|
if (bshowimg)
|
||||||
|
{
|
||||||
|
if (img.channels() != 1)
|
||||||
|
{
|
||||||
|
showimg = img.clone();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cv::cvtColor(img, showimg, cv::COLOR_GRAY2BGR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config.nSearchCount = 10;
|
||||||
|
config.strchannel = strchannel;
|
||||||
|
config.directSign = DirectSign_UP;
|
||||||
|
if (bleft)
|
||||||
|
{
|
||||||
|
config.roi = cv::Rect(0, 0, 200, img.rows * 0.8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
config.roi = cv::Rect(img.cols - 200, 0, 200, img.rows * 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
int re123 = GetEdgePoint(img, &config, A_line_up);
|
||||||
|
if (re123 != 0)
|
||||||
|
{
|
||||||
|
printf("DirectSign_UP::111111111111GetEdgePoint111111 A_line_up %d\n", re123);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
config.directSign = DirectSign_DOWN;
|
||||||
|
config.strchannel = strchannel + "ccc";
|
||||||
|
config.roi = cv::Rect(0, img.rows * 0.2, 200, img.rows * 0.8 - 1);
|
||||||
|
|
||||||
|
if (bleft)
|
||||||
|
{
|
||||||
|
config.roi = cv::Rect(0, img.rows * 0.2, 200, img.rows * 0.8 - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
config.roi = cv::Rect(img.cols - 200, img.rows * 0.2, 200, img.rows * 0.8 - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
re123 = GetEdgePoint(img, &config, A_line_down);
|
||||||
|
if (re123 != 0)
|
||||||
|
{
|
||||||
|
printf("DirectSign_UP::111111111111GetEdgePoint111111 A_line_down %d\n", re123);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
if (bshowimg)
|
||||||
|
{
|
||||||
|
cv::line(showimg, cv::Point(0, A_line_down), cv::Point(img.cols, A_line_down), cv::Scalar(0, 255, 0), 2);
|
||||||
|
cv::line(showimg, cv::Point(0, A_line_up), cv::Point(img.cols, A_line_up), cv::Scalar(0, 255, 0), 2);
|
||||||
|
|
||||||
|
cv::imwrite(strcam + strchannel + "_line.png", showimg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// printf("DirectSign_UP::111111111111111111 re123 %d\n", re123);
|
||||||
|
// getchar();
|
||||||
|
|
||||||
|
cv::Mat small, smallbin;
|
||||||
|
cv::resize(img, small, cv::Size(600, 1500));
|
||||||
|
|
||||||
|
cv::threshold(small, smallbin, 80, 255,
|
||||||
|
cv::THRESH_BINARY);
|
||||||
|
|
||||||
|
/* 3. contours */
|
||||||
|
std::vector<std::vector<cv::Point>> contours;
|
||||||
|
cv::findContours(smallbin, contours,
|
||||||
|
cv::RETR_EXTERNAL,
|
||||||
|
cv::CHAIN_APPROX_SIMPLE);
|
||||||
|
|
||||||
|
if (contours.empty())
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* 4. max contour */
|
||||||
|
double maxArea = 0;
|
||||||
|
int idx = -1;
|
||||||
|
for (int i = 0; i < contours.size(); i++)
|
||||||
|
{
|
||||||
|
double area = cv::contourArea(contours[i]);
|
||||||
|
if (area > maxArea)
|
||||||
|
{
|
||||||
|
maxArea = area;
|
||||||
|
idx = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx < 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
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;
|
||||||
|
cv::Rect rectInSrc;
|
||||||
|
|
||||||
|
rectInSrc.x = int(rSmall.x * sx) - 50;
|
||||||
|
rectInSrc.y = int(rSmall.y * sy) - 50;
|
||||||
|
rectInSrc.width = int(rSmall.width * sx) + 100;
|
||||||
|
rectInSrc.height = int(rSmall.height * sy) + 100;
|
||||||
|
|
||||||
|
if (rectInSrc.y >= A_line_up)
|
||||||
|
{
|
||||||
|
rectInSrc.y = A_line_up - 5;
|
||||||
|
}
|
||||||
|
if (rectInSrc.y + rectInSrc.height <= A_line_down)
|
||||||
|
{
|
||||||
|
rectInSrc.height = A_line_down + 5 - rectInSrc.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rectInSrc.x < 0)
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
rectInSrc.height = img.rows - rectInSrc.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
merg_p_up.y = A_line_up;
|
||||||
|
merg_p_up.x = img.cols;
|
||||||
|
merg_p_down.y = A_line_down;
|
||||||
|
merg_p_down.x = img.cols;
|
||||||
|
roi = rectInSrc;
|
||||||
|
|
||||||
|
if (bshowimg)
|
||||||
|
{
|
||||||
|
cv::rectangle(showimg, rectInSrc, cv::Scalar(0, 0, 255), 2);
|
||||||
|
cv::imwrite(strcam + strchannel + "_rect.png", showimg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ImageMerge::GetEdgePoint(const cv::Mat &img, Edge_Search_Config *pEdge_Search_Config, int &outP)
|
||||||
|
{
|
||||||
|
bool bdbuge = false;
|
||||||
|
bdbuge = bshowimg;
|
||||||
|
if (img.empty())
|
||||||
|
{
|
||||||
|
return -11;
|
||||||
|
}
|
||||||
|
if (img.channels() != 1)
|
||||||
|
{
|
||||||
|
printf("*****************************channels\n");
|
||||||
|
|
||||||
|
return -12;
|
||||||
|
}
|
||||||
|
// 检查roi;
|
||||||
|
if (!CheckUtil::RoiInImg(pEdge_Search_Config->roi, img))
|
||||||
|
{
|
||||||
|
return -13;
|
||||||
|
}
|
||||||
|
if (!pEdge_Search_Config->CheckConfigValid())
|
||||||
|
{
|
||||||
|
return -14;
|
||||||
|
}
|
||||||
|
std::vector<cv::Point> pointList;
|
||||||
|
bool search_UP_DOWN = false;
|
||||||
|
cv::Rect roi = pEdge_Search_Config->roi;
|
||||||
|
int sx = roi.x;
|
||||||
|
int ex = roi.x + roi.width;
|
||||||
|
int sy = roi.y;
|
||||||
|
int ey = roi.y + roi.height;
|
||||||
|
|
||||||
|
int nSearchLen = roi.width; // 搜索区域的长度
|
||||||
|
int nCurPoint_Step = pEdge_Search_Config->stepCount; // 当前点搜索的步长
|
||||||
|
|
||||||
|
// 搜索小范围确认
|
||||||
|
int nhalfrang = (int)pEdge_Search_Config->nSearchrange / 2;
|
||||||
|
int nrange_start = 0 - nhalfrang;
|
||||||
|
int nrange_end = 0 - nhalfrang;
|
||||||
|
int num = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
num++;
|
||||||
|
nrange_end++;
|
||||||
|
if (num >= pEdge_Search_Config->nSearchrange)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 判断方向
|
||||||
|
switch (pEdge_Search_Config->directSign)
|
||||||
|
{
|
||||||
|
case DirectSign_UP:
|
||||||
|
search_UP_DOWN = true;
|
||||||
|
nSearchLen = roi.width;
|
||||||
|
sx = roi.x;
|
||||||
|
ex = roi.x + roi.width;
|
||||||
|
sy = roi.y;
|
||||||
|
ey = roi.y + roi.height;
|
||||||
|
nCurPoint_Step = pEdge_Search_Config->stepCount;
|
||||||
|
break;
|
||||||
|
case DirectSign_DOWN:
|
||||||
|
search_UP_DOWN = true;
|
||||||
|
nSearchLen = roi.width;
|
||||||
|
nCurPoint_Step = -pEdge_Search_Config->stepCount;
|
||||||
|
|
||||||
|
sx = roi.x;
|
||||||
|
ex = roi.x + roi.width;
|
||||||
|
sy = roi.y + roi.height - 1;
|
||||||
|
ey = roi.y;
|
||||||
|
break;
|
||||||
|
case DirectSign_Left:
|
||||||
|
nSearchLen = roi.height;
|
||||||
|
search_UP_DOWN = false;
|
||||||
|
nCurPoint_Step = pEdge_Search_Config->stepCount;
|
||||||
|
|
||||||
|
sx = roi.x;
|
||||||
|
ex = roi.x + roi.width;
|
||||||
|
sy = roi.y;
|
||||||
|
ey = roi.y + roi.height;
|
||||||
|
break;
|
||||||
|
case DirectSign_Right:
|
||||||
|
nSearchLen = roi.height;
|
||||||
|
search_UP_DOWN = false;
|
||||||
|
nCurPoint_Step = -pEdge_Search_Config->stepCount;
|
||||||
|
|
||||||
|
sx = roi.x + roi.width - 1;
|
||||||
|
ex = roi.x;
|
||||||
|
sy = roi.y;
|
||||||
|
ey = roi.y + roi.height;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 搜索 点数
|
||||||
|
int nSearchPointNum = pEdge_Search_Config->nSearchCount;
|
||||||
|
// 搜素点的间隔
|
||||||
|
int nSearchPointStep = 1;
|
||||||
|
if (nSearchPointNum > 1)
|
||||||
|
{
|
||||||
|
nSearchPointStep = int(nSearchLen * 1.0f / (nSearchPointNum - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bdbuge)
|
||||||
|
{
|
||||||
|
cv::rectangle(showimg, roi, cv::Scalar(255, 0, 0), 2);
|
||||||
|
printf("nSearchPointStep %d nCurPoint_Step %d,nrange_start %d %d\n", nSearchPointStep, nCurPoint_Step, nrange_start, nrange_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
uchar *pdata = (uchar *)img.data;
|
||||||
|
int offt = 0;
|
||||||
|
// 搜索 上下边
|
||||||
|
if (search_UP_DOWN)
|
||||||
|
{
|
||||||
|
// 每个搜索点 分布在X方向。
|
||||||
|
for (int x = sx; x < ex; x = x + nSearchPointStep)
|
||||||
|
{
|
||||||
|
int bOKNum = 0;
|
||||||
|
int cur_x = x;
|
||||||
|
int cur_y = sy;
|
||||||
|
bool bSucc = false;
|
||||||
|
int succ_y = 0;
|
||||||
|
|
||||||
|
// 对每个搜索点进行 y方向搜索
|
||||||
|
for (int y = sy;; y = y + nCurPoint_Step)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (y < 0 || y >= img.rows)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (nCurPoint_Step > 0 && y > ey)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (nCurPoint_Step < 0 && y < ey)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
offt = y * img.cols;
|
||||||
|
int range_okNum = 0;
|
||||||
|
// 对一定范围的点进行判断
|
||||||
|
for (int k = nrange_start; k < nrange_end; k++)
|
||||||
|
{
|
||||||
|
int rangeX = x + k;
|
||||||
|
if (rangeX < 0 || rangeX >= img.cols)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
offt += rangeX;
|
||||||
|
if (offt < 0 || offt >= img.cols * img.rows)
|
||||||
|
{
|
||||||
|
printf("rangeX %d nCurPoint_Step %d off %d x %d y %d sy %d ey %d %d %d\n", rangeX, nCurPoint_Step, offt, x, y, sy, ey, img.cols, img.rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pdata[offt] >= pEdge_Search_Config->nValueThreshold) // 找到
|
||||||
|
{
|
||||||
|
range_okNum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (range_okNum >= pEdge_Search_Config->nSearchrange)
|
||||||
|
{
|
||||||
|
if (bdbuge)
|
||||||
|
{
|
||||||
|
cv::circle(showimg, cv::Point(x, y), 1, cv::Scalar(0, 0, 255));
|
||||||
|
}
|
||||||
|
if (bOKNum == 0)
|
||||||
|
{
|
||||||
|
cur_y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
bOKNum++;
|
||||||
|
|
||||||
|
// 连续搜索到 满足要求的点。
|
||||||
|
if (bOKNum >= pEdge_Search_Config->nLimit)
|
||||||
|
{
|
||||||
|
bSucc = true;
|
||||||
|
succ_y = y;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 如果有间断,需要重新计算连续情况。
|
||||||
|
bOKNum = 0;
|
||||||
|
if (bdbuge)
|
||||||
|
{
|
||||||
|
cv::circle(showimg, cv::Point(x, y), 1, cv::Scalar(0, 255, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bSucc)
|
||||||
|
{
|
||||||
|
cv::Point p(cur_x, cur_y);
|
||||||
|
if (bdbuge)
|
||||||
|
{
|
||||||
|
cv::circle(showimg, p, 3, cv::Scalar(255, 0, 0));
|
||||||
|
}
|
||||||
|
pointList.push_back(p);
|
||||||
|
|
||||||
|
if (pointList.size() > 5)
|
||||||
|
{
|
||||||
|
// printf("=============feeeee\n");
|
||||||
|
sy = succ_y - 100;
|
||||||
|
ey = succ_y + 100;
|
||||||
|
|
||||||
|
switch (pEdge_Search_Config->directSign)
|
||||||
|
{
|
||||||
|
case DirectSign_UP:
|
||||||
|
sy = succ_y - 100;
|
||||||
|
ey = succ_y + 100;
|
||||||
|
break;
|
||||||
|
case DirectSign_DOWN:
|
||||||
|
sy = succ_y + 100;
|
||||||
|
ey = succ_y - 100;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sy < 0)
|
||||||
|
{
|
||||||
|
sy = 0;
|
||||||
|
}
|
||||||
|
if (ey >= img.rows)
|
||||||
|
{
|
||||||
|
ey = img.rows - 1;
|
||||||
|
}
|
||||||
|
if (ey < 0)
|
||||||
|
{
|
||||||
|
ey = 0;
|
||||||
|
}
|
||||||
|
if (sy >= img.rows)
|
||||||
|
{
|
||||||
|
sy = img.rows - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // 搜索 左右边
|
||||||
|
{
|
||||||
|
// 每个搜索点 分布在X方向。
|
||||||
|
for (int y = sy; y < ey; y = y + nSearchPointStep)
|
||||||
|
{
|
||||||
|
int bOKNum = 0;
|
||||||
|
int cur_x = sx;
|
||||||
|
int cur_y = y;
|
||||||
|
bool bSucc = false;
|
||||||
|
int succ_x = 0;
|
||||||
|
|
||||||
|
// 对每个搜索点进行 y方向搜索
|
||||||
|
for (int x = sx;; x = x + nCurPoint_Step)
|
||||||
|
{
|
||||||
|
if (x < 0 || x >= img.cols)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
if (nCurPoint_Step > 0 && x > ex)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (nCurPoint_Step < 0 && x < ex)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int range_okNum = 0;
|
||||||
|
// 对一定范围的点进行判断
|
||||||
|
for (int k = nrange_start; k < nrange_end; k++)
|
||||||
|
{
|
||||||
|
int rangey = y + k;
|
||||||
|
if (rangey < 0 || rangey >= img.rows)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
offt = rangey * img.cols + x;
|
||||||
|
if (offt < 0 || offt >= img.cols * img.rows)
|
||||||
|
{
|
||||||
|
printf("rangey %d off %d x %d y %d ey %d %d %d\n", rangey, offt, x, y, ey, img.cols, img.rows);
|
||||||
|
}
|
||||||
|
if (pdata[offt] >= pEdge_Search_Config->nValueThreshold) // 找到
|
||||||
|
{
|
||||||
|
range_okNum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (range_okNum >= pEdge_Search_Config->nSearchrange)
|
||||||
|
{
|
||||||
|
if (bdbuge)
|
||||||
|
{
|
||||||
|
cv::circle(showimg, cv::Point(x, y), 1, cv::Scalar(0, 0, 255));
|
||||||
|
}
|
||||||
|
if (bOKNum == 0)
|
||||||
|
{
|
||||||
|
cur_x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
bOKNum++;
|
||||||
|
// 连续搜索到 满足要求的点。
|
||||||
|
if (bOKNum >= pEdge_Search_Config->nLimit)
|
||||||
|
{
|
||||||
|
bSucc = true;
|
||||||
|
succ_x = x;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 如果有间断,需要重新计算连续情况。
|
||||||
|
bOKNum = 0;
|
||||||
|
if (bdbuge)
|
||||||
|
{
|
||||||
|
cv::circle(showimg, cv::Point(x, y), 1, cv::Scalar(0, 255, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bSucc)
|
||||||
|
{
|
||||||
|
cv::Point p(cur_x, cur_y);
|
||||||
|
if (bdbuge)
|
||||||
|
{
|
||||||
|
cv::circle(showimg, p, 3, cv::Scalar(255, 0, 0));
|
||||||
|
}
|
||||||
|
pointList.push_back(p);
|
||||||
|
if (pointList.size() > 5)
|
||||||
|
{
|
||||||
|
// printf("=============feeeee\n");
|
||||||
|
sx = succ_x - 100;
|
||||||
|
ex = succ_x + 100;
|
||||||
|
if (sx < 0)
|
||||||
|
{
|
||||||
|
sx = 0;
|
||||||
|
}
|
||||||
|
if (ex >= img.cols)
|
||||||
|
{
|
||||||
|
ex = img.cols - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bdbuge)
|
||||||
|
{
|
||||||
|
cv::imwrite(pEdge_Search_Config->strchannel + "show.png", showimg);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const int maxDeviation = 10; // 可调阈值:最大允许偏离像素
|
||||||
|
|
||||||
|
std::vector<cv::Point> avgPoints;
|
||||||
|
|
||||||
|
int PNum = pointList.size();
|
||||||
|
// 第一次计算粗略均值
|
||||||
|
int sum_y = 0, sum_x = 0;
|
||||||
|
for (const auto &pt : pointList)
|
||||||
|
{
|
||||||
|
|
||||||
|
sum_x += pt.x;
|
||||||
|
sum_y += pt.y;
|
||||||
|
}
|
||||||
|
float avg_y = sum_y * 1.0f / PNum;
|
||||||
|
float avg_x = sum_x * 1.0f / PNum;
|
||||||
|
|
||||||
|
// 过滤异常点
|
||||||
|
std::vector<cv::Point> filtered;
|
||||||
|
for (const auto &pt : pointList)
|
||||||
|
{
|
||||||
|
if (search_UP_DOWN) // 横向:判断 y 偏差
|
||||||
|
{
|
||||||
|
|
||||||
|
if (std::abs(pt.y - avg_y) <= maxDeviation)
|
||||||
|
filtered.push_back(pt);
|
||||||
|
}
|
||||||
|
else // 纵向:判断 x 偏差
|
||||||
|
{
|
||||||
|
if (std::abs(pt.x - avg_x) <= maxDeviation)
|
||||||
|
filtered.push_back(pt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filtered.empty())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
int sum_fx = 0, sum_fy = 0;
|
||||||
|
for (const auto &pt : filtered)
|
||||||
|
{
|
||||||
|
sum_fx += pt.x;
|
||||||
|
sum_fy += pt.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (search_UP_DOWN) // 横向:判断 y 偏差
|
||||||
|
{
|
||||||
|
outP = sum_fy / (int)filtered.size();
|
||||||
|
}
|
||||||
|
else // 纵向:判断 x 偏差
|
||||||
|
{
|
||||||
|
outP = sum_fx / (int)filtered.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ImageMerge::GetLine(const cv::Mat &img, std::vector<cv::Point> &pointList, int lineNum, int xory, int &outP)
|
||||||
|
{
|
||||||
|
if (pointList.size() < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
const int maxDeviation = 10; // 可调阈值:最大允许偏离像素
|
||||||
|
|
||||||
|
std::vector<cv::Point> avgPoints;
|
||||||
|
|
||||||
|
int PNum = pointList.size();
|
||||||
|
// 第一次计算粗略均值
|
||||||
|
int sum_y = 0, sum_x = 0;
|
||||||
|
for (const auto &pt : pointList)
|
||||||
|
{
|
||||||
|
|
||||||
|
sum_x += pt.x;
|
||||||
|
sum_y += pt.y;
|
||||||
|
}
|
||||||
|
float avg_y = sum_y * 1.0f / PNum;
|
||||||
|
float avg_x = sum_x * 1.0f / PNum;
|
||||||
|
|
||||||
|
// 过滤异常点
|
||||||
|
std::vector<cv::Point> filtered;
|
||||||
|
for (const auto &pt : pointList)
|
||||||
|
{
|
||||||
|
if (xory == 0) // 横向:判断 y 偏差
|
||||||
|
{
|
||||||
|
if (std::abs(pt.y - avg_y) <= maxDeviation)
|
||||||
|
filtered.push_back(pt);
|
||||||
|
}
|
||||||
|
else // 纵向:判断 x 偏差
|
||||||
|
{
|
||||||
|
if (std::abs(pt.x - avg_x) <= maxDeviation)
|
||||||
|
filtered.push_back(pt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (filtered.empty())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
int sum_fx = 0, sum_fy = 0;
|
||||||
|
for (const auto &pt : filtered)
|
||||||
|
{
|
||||||
|
sum_fx += pt.x;
|
||||||
|
sum_fy += pt.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xory == 0) // 横向:判断 y 偏差
|
||||||
|
{
|
||||||
|
outP = sum_fy / (int)filtered.size();
|
||||||
|
}
|
||||||
|
else // 纵向:判断 x 偏差
|
||||||
|
{
|
||||||
|
outP = sum_fx / (int)filtered.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImageMerge::ProductSide_left(const cv::Mat &img)
|
||||||
|
{
|
||||||
|
|
||||||
|
cv::Rect Roi_left, Right_Roi;
|
||||||
|
Roi_left.x = 0;
|
||||||
|
Roi_left.y = 0;
|
||||||
|
Roi_left.width = img.cols * 0.1;
|
||||||
|
Roi_left.height = img.rows;
|
||||||
|
|
||||||
|
Right_Roi.x = img.cols - img.cols * 0.1;
|
||||||
|
Right_Roi.y = 0;
|
||||||
|
Right_Roi.width = img.cols * 0.1;
|
||||||
|
Right_Roi.height = img.rows;
|
||||||
|
|
||||||
|
cv::Mat left_img = img(Roi_left);
|
||||||
|
cv::Mat right_img = img(Right_Roi);
|
||||||
|
|
||||||
|
cv::Size sz = cv::Size(200, 600);
|
||||||
|
|
||||||
|
cv::resize(left_img, left_img, sz);
|
||||||
|
cv::resize(right_img, right_img, sz);
|
||||||
|
int nonZeroCount_left = cv::countNonZero(left_img);
|
||||||
|
int nonZeroCount_right = cv::countNonZero(right_img);
|
||||||
|
if (nonZeroCount_left >= nonZeroCount_right)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* @Author: xiewenji 527774126@qq.com
|
||||||
|
* @Date: 2025-09-11 15:32:52
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @LastEditTime: 2025-09-16 09:40:36
|
||||||
|
* @FilePath: /BOE_CELL_AOI_Detect/AlgorithmModule/src/ImageStorage.cpp
|
||||||
|
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
*/
|
||||||
|
#include "ImageStorage.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
|
||||||
|
ImageStorage *ImageStorage::instance = nullptr;
|
||||||
|
|
||||||
|
ImageStorage::ImageStorage() : stopFlag(false)
|
||||||
|
{
|
||||||
|
// 启动存储线程
|
||||||
|
storageThread = std::thread(&ImageStorage::storeImages, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageStorage::~ImageStorage()
|
||||||
|
{
|
||||||
|
stop(); // 在销毁时确保线程被正确停止
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取单例实例的静态方法
|
||||||
|
ImageStorage *ImageStorage::getInstance()
|
||||||
|
{
|
||||||
|
if (instance == nullptr)
|
||||||
|
{
|
||||||
|
instance = new ImageStorage(); // 如果实例为空,则创建新实例
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageStorage::storeImages()
|
||||||
|
{
|
||||||
|
while (!stopFlag)
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Sleep for 100 milliseconds
|
||||||
|
std::unique_lock<std::mutex> lock(queueMutex);
|
||||||
|
cv.wait(lock, [this]()
|
||||||
|
{ return !imageQueue.empty() || stopFlag; });
|
||||||
|
|
||||||
|
if (stopFlag && imageQueue.empty())
|
||||||
|
break;
|
||||||
|
|
||||||
|
auto item = imageQueue.front();
|
||||||
|
imageQueue.pop();
|
||||||
|
lock.unlock();
|
||||||
|
cv::Mat temimg = item.first;
|
||||||
|
if (!temimg.empty())
|
||||||
|
{
|
||||||
|
cv::imwrite(item.second, item.first); // 保存图片到文件
|
||||||
|
// std::cout << "Image saved to: " << item.second << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ImageStorage::addImage(const std::string &path, const cv::Mat &image, bool badd)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(queueMutex);
|
||||||
|
|
||||||
|
if (imageQueue.size() > 1000 && !badd)
|
||||||
|
{
|
||||||
|
std::cout << "Queue has more than 10 items, not adding new images." << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
imageQueue.push({image, path});
|
||||||
|
cv.notify_one(); // 通知存储线程处理新任务
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageStorage::stop()
|
||||||
|
{
|
||||||
|
stopFlag = true;
|
||||||
|
cv.notify_one(); // 通知存储线程停止
|
||||||
|
if (storageThread.joinable())
|
||||||
|
{
|
||||||
|
storageThread.join(); // 等待线程退出
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* @Author: your name
|
||||||
|
* @Date: 2022-04-20 15:50:00
|
||||||
|
* @LastEditTime: 2022-09-26 16:27:27
|
||||||
|
* @LastEditors: sueRimn
|
||||||
|
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
* @FilePath: /ZCXD_MonitorPlatform/src/CoreLogicModule/src/CamDeal.cpp
|
||||||
|
*/
|
||||||
|
#include "ImgCheckBase.h"
|
||||||
|
#include "ImgCheckAnalysisy.hpp"
|
||||||
|
#include "ImgCheckConfig.h"
|
||||||
|
#include "ALLImgCheckAnalysisy.hpp"
|
||||||
|
ALLImgCheckBase *ALLImgCheckBase::instance = nullptr;
|
||||||
|
ALLImgCheckBase *ALLImgCheckBase::GetInstance()
|
||||||
|
{
|
||||||
|
// if (instance == nullptr)
|
||||||
|
// {
|
||||||
|
// instance = (ALLImgCheckBase *)new ALLImgCheckAnalysisy();
|
||||||
|
// }
|
||||||
|
return (ALLImgCheckBase *)new ALLImgCheckAnalysisy();;
|
||||||
|
}
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
|
||||||
|
#include "OtherDetect.h"
|
||||||
|
#include "CheckErrorCodeDefine.hpp"
|
||||||
|
|
||||||
|
AIDetectBase ::AIDetectBase(/* args */)
|
||||||
|
{
|
||||||
|
m_pOtherDet_Config = NULL;
|
||||||
|
|
||||||
|
m_bInitialized = false;
|
||||||
|
m_bModelSucc = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
AIDetectBase ::~AIDetectBase()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
int AIDetectBase ::Init(OtherDet_Config *pOtherDet_Config)
|
||||||
|
{
|
||||||
|
m_pOtherDet_Config = pOtherDet_Config;
|
||||||
|
|
||||||
|
m_bInitialized = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LackPolDet::LackPolDet(/* args */)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LackPolDet::~LackPolDet()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
int LackPolDet::Init_LackPol()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int LackPolDet::InitModel_ALL()
|
||||||
|
{
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int LackPolDet::Detect(const cv::Mat &img, DetConfig *pDetConfig, cv::Mat &outMask)
|
||||||
|
{
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* @Author: xiewenji 527774126@qq.com
|
||||||
|
* @Date: 2025-09-13 19:26:19
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @LastEditTime: 2025-09-17 18:10:38
|
||||||
|
* @FilePath: /BOE_CELL_AOI_Detect/AlgorithmModule/src/Product.cpp
|
||||||
|
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "Product.h"
|
||||||
|
#include "QX_Merge_Analysis.h"
|
||||||
|
|
||||||
|
Product::Product(/* args */)
|
||||||
|
{
|
||||||
|
productBaseResult = std::make_shared<ProductBaseResult>();
|
||||||
|
productBaseResult->detlog = std::make_shared<DetLog>();
|
||||||
|
productBaseResult->pQX_Merge_Analysis = QX_Merge_Analysis::GetInstance();
|
||||||
|
productBaseResult->pQX_Merge_Analysis->InitData();
|
||||||
|
productBaseResult->detlog->AddCheckstr(PrintLevel_0, "PushInImg", "Product create %s productBaseResult ", CheckUtil::getCurTimeHMS().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
Product::~Product()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<CameraResult> Product::GetCameraResult(std::string strcameraName)
|
||||||
|
{
|
||||||
|
// 加锁保证多线程安全
|
||||||
|
std::lock_guard<std::mutex> lock(mtx_CameraResultList);
|
||||||
|
for (auto &ptr : m_pCameraResultList)
|
||||||
|
{
|
||||||
|
if (ptr->cameraBaseResult->strCameraName == strcameraName)
|
||||||
|
{
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
productBaseResult->detlog->bPrintStr = false;
|
||||||
|
// 不存在,创建新的 CameraResult 并插入 map
|
||||||
|
std::shared_ptr<CameraResult> newResult = std::make_shared<CameraResult>();
|
||||||
|
newResult->productBaseResult = productBaseResult;
|
||||||
|
newResult->cameraBaseResult->strCameraName = strcameraName;
|
||||||
|
m_pCameraResultList.push_back(newResult);
|
||||||
|
productBaseResult->detlog->AddCheckstr(PrintLevel_0, "PushInImg", "11111 Camera %s %s", strcameraName.c_str(), CheckUtil::getCurTimeHMS().c_str());
|
||||||
|
productBaseResult->pQX_Merge_Analysis->AddCamer(strcameraName);
|
||||||
|
productBaseResult->detlog->AddCheckstr(PrintLevel_0, "PushInImg", "22222 Camera %s %s", strcameraName.c_str(), CheckUtil::getCurTimeHMS().c_str());
|
||||||
|
productBaseResult->nCamera_Num = m_pCameraResultList.size();
|
||||||
|
productBaseResult->detlog->AddCheckstr(PrintLevel_0, "PushInImg", "add new Camera %s %s", strcameraName.c_str(), CheckUtil::getCurTimeHMS().c_str());
|
||||||
|
return newResult;
|
||||||
|
}
|
||||||
|
void Product::AddLog(std::string str)
|
||||||
|
{
|
||||||
|
LogList.push_back(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Product::UpdatePushStatus(int status)
|
||||||
|
{
|
||||||
|
if (IN_IMG_Status_End == status ||
|
||||||
|
IN_IMG_Status_OneImg == status ||
|
||||||
|
-1 == status)
|
||||||
|
{
|
||||||
|
bIsImgComplete = true;
|
||||||
|
std::lock_guard<std::mutex> lock(mtx_CameraResultList); // 加锁保护 map
|
||||||
|
|
||||||
|
for (auto &ptr : m_pCameraResultList)
|
||||||
|
{
|
||||||
|
// printf("===========1112\n");
|
||||||
|
ptr->setImgPushComplate();
|
||||||
|
}
|
||||||
|
std::string strTimg = CheckUtil::getCurTimeHMS();
|
||||||
|
productBaseResult->detlog->AddCheckstr(PrintLevel_0, "PushInImg", "%s Add ALL img end %s m_pCameraResultList %ld ",
|
||||||
|
productBaseResult->strproductName.c_str(), strTimg.c_str(), m_pCameraResultList.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Product::bCheckCamplate()
|
||||||
|
{
|
||||||
|
// 所有的图都送完了。
|
||||||
|
if (bIsImgComplete)
|
||||||
|
{
|
||||||
|
bool ballcomplate = true;
|
||||||
|
std::lock_guard<std::mutex> lock(mtx_CameraResultList); // 加锁保护 map
|
||||||
|
for (auto &ptr : m_pCameraResultList)
|
||||||
|
{
|
||||||
|
if (!ptr->bCheckCamplate())
|
||||||
|
{
|
||||||
|
ballcomplate = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ballcomplate)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,36 @@
|
|||||||
|
#include "Task.h"
|
||||||
|
|
||||||
|
Task::Task()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Task::~Task()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int Task::sendTask(std::shared_ptr<TaskInfo> task)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_task_mutex_);
|
||||||
|
task->SetStatus(TaskStep_Waite);
|
||||||
|
m_tasks_.push(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_task_cv_.notify_one();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<TaskInfo> Task::GetTask()
|
||||||
|
{
|
||||||
|
std::shared_ptr<TaskInfo> task;
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(m_task_mutex_);
|
||||||
|
m_task_cv_.wait(lock, [this]()
|
||||||
|
{ return !m_tasks_.empty(); });
|
||||||
|
|
||||||
|
task = std::move(m_tasks_.front());
|
||||||
|
m_tasks_.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return task;
|
||||||
|
}
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
#限定CMake的版本
|
||||||
|
cmake_minimum_required (VERSION 3.5)
|
||||||
|
|
||||||
|
project(rootproject)
|
||||||
|
set(CHECK_WORK_Value "CELL_ET")
|
||||||
|
|
||||||
|
if (DEFINED WORK)
|
||||||
|
set(CHECK_WORK_Value ${WORK})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# 根据宏设置编译时宏
|
||||||
|
add_definitions(-DCHECK_WORK="${CHECK_WORK_Value}")
|
||||||
|
|
||||||
|
message(STATUS "CHECK_WORK: ${CHECK_WORK_Value}")
|
||||||
|
|
||||||
|
find_package( OpenCV REQUIRED )
|
||||||
|
|
||||||
|
message(STATUS "oPENCV Library status:")
|
||||||
|
message(STATUS ">version:${OpenCV_VERSION}")
|
||||||
|
message(STATUS "Include:${OpenCV_INCLUDE_DIRS}")
|
||||||
|
|
||||||
|
set(CMAKE_BUILD_TYPE "release")
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON) # 要求编译器支持 C++17
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF) # 禁用 GNU 特定的扩展
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
#set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS}; --default-stream per-thread)
|
||||||
|
|
||||||
|
add_definitions(-DCUDA_API_PER_THREAD_DEFAULT_STREAM)
|
||||||
|
# PROJECT_INCLUDE_DIR当作全局头文件变量
|
||||||
|
set(PROJECT_INCLUDE_DIR c/include)
|
||||||
|
|
||||||
|
# x86_64,aarch64
|
||||||
|
set(BUILD_ARCH x86_64 CACHE STRING "Arch of this project" FORCE)
|
||||||
|
MESSAGE(STATUS "BUILD_ARCH : ${BUILD_ARCH}")
|
||||||
|
|
||||||
|
MESSAGE(STATUS "CMAKE_BUILD_TYPE : ${CMAKE_BUILD_TYPE}")
|
||||||
|
MESSAGE(STATUS "This is BINARY dir " ${PROJECT_BINARY_DIR})
|
||||||
|
MESSAGE(STATUS "This is SOURCE dir " ${PROJECT_SOURCE_DIR})
|
||||||
|
|
||||||
|
#包含通用的编译环境模块到顶层目录
|
||||||
|
include(${PROJECT_SOURCE_DIR}/cmake/default_variabes.cmake)
|
||||||
|
include(${PROJECT_SOURCE_DIR}/cmake/cpp_c_flags.cmake)
|
||||||
|
include(${PROJECT_SOURCE_DIR}/cmake/print_archs.cmake)
|
||||||
|
|
||||||
|
include_directories(${PROJECT_SOURCE_DIR}/include/)
|
||||||
|
include_directories(/usr/local/boost/include
|
||||||
|
/usr/include
|
||||||
|
${OpenCV_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
link_directories(
|
||||||
|
${PROJECT_SOURCE_DIR}/lib/x86_64/
|
||||||
|
/usr/local/boost/lib
|
||||||
|
)
|
||||||
|
|
||||||
|
#下一级的编译目录
|
||||||
|
|
||||||
|
MESSAGE("build dependent module - start")
|
||||||
|
#当程序执行命令 ADD_SUBDIRECTORY(src)时进入目录 src 对其中的 CMakeLists.txt 进行解析。
|
||||||
|
|
||||||
|
|
||||||
|
add_subdirectory(ConfigModule)
|
||||||
|
MESSAGE("ConfigModule")
|
||||||
|
|
||||||
|
# CommonUtil
|
||||||
|
add_subdirectory(AlgorithmModule)
|
||||||
|
MESSAGE("AlgorithmModule")
|
||||||
|
|
||||||
|
add_subdirectory(example)
|
||||||
|
MESSAGE("example")
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* @Author: your name
|
||||||
|
* @Date: 2022-04-20 15:49:50
|
||||||
|
* @LastEditTime: 2022-09-23 21:51:58
|
||||||
|
* @LastEditors: sueRimn
|
||||||
|
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
* @FilePath: /ZCXD_MonitorPlatform/src/CoreLogicModule/include/CamDeal.h
|
||||||
|
*/
|
||||||
|
#ifndef Base_Define_H_
|
||||||
|
#define Base_Define_H_
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#define RECT_TO_STRING(rect) \
|
||||||
|
"(x=" + std::to_string((rect).x) + ", y=" + std::to_string((rect).y) \
|
||||||
|
+ ", width=" + std::to_string((rect).width) + ", height=" + std::to_string((rect).height) + ")"
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
#版本限定
|
||||||
|
cmake_minimum_required (VERSION 3.5)
|
||||||
|
|
||||||
|
set(ModuleName "ConfigModule")
|
||||||
|
|
||||||
|
include(${PROJECT_SOURCE_DIR}/cmake/default_variabes.cmake)
|
||||||
|
include(${PROJECT_SOURCE_DIR}/cmake/cpp_c_flags.cmake)
|
||||||
|
include(${PROJECT_SOURCE_DIR}/cmake/print_archs.cmake)
|
||||||
|
|
||||||
|
|
||||||
|
#头文件
|
||||||
|
include_directories(
|
||||||
|
/usr/local/include
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
|
)
|
||||||
|
link_directories(
|
||||||
|
/usr/local/lib/
|
||||||
|
)
|
||||||
|
# 用set设置变量不能使用*.cpp
|
||||||
|
file(GLOB SRC_LISTS ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
|
||||||
|
|
||||||
|
add_library(Config SHARED ${SRC_LISTS})
|
||||||
|
|
||||||
|
target_link_libraries(Config
|
||||||
|
${OpenCV_LIBS}
|
||||||
|
)
|
||||||
|
set(ModuleName "")
|
||||||
|
|
||||||
|
#add_subdirectory(example)
|
||||||
|
|
||||||
|
# make install 安装到/usr/local下
|
||||||
|
# 自定义安装前缀
|
||||||
|
set(CMAKE_INSTALL_PREFIX /usr/local/cellet CACHE PATH "Install path prefix" FORCE)
|
||||||
|
set(HEADER_FILES include/ConfigBase.h)
|
||||||
|
# 安装动态库
|
||||||
|
install(TARGETS Config
|
||||||
|
LIBRARY DESTINATION lib # 安装到 CMAKE_INSTALL_PREFIX/lib
|
||||||
|
ARCHIVE DESTINATION lib/static
|
||||||
|
RUNTIME DESTINATION bin
|
||||||
|
PUBLIC_HEADER DESTINATION include) # 安装到 CMAKE_INSTALL_PREFIX/include
|
||||||
|
# 安装头文件
|
||||||
|
install(FILES ${HEADER_FILES} DESTINATION include)
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,86 @@
|
|||||||
|
#ifndef CamConfig_H
|
||||||
|
#define CamConfig_H
|
||||||
|
|
||||||
|
#include "JsonCoversion.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "CheckConfigDefine.h"
|
||||||
|
#include "Define.h"
|
||||||
|
|
||||||
|
class CommonParamJson : public JsonCoversion
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CommonParamJson() {}
|
||||||
|
virtual ~CommonParamJson() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual Json::Value toJsonValue();
|
||||||
|
virtual void toObjectFromValue(Json::Value root);
|
||||||
|
int GetConfig(CommonParamST &config);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CommonParamST _config;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CommonParamToCheckConfigJson : public JsonCoversion
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CommonParamToCheckConfigJson() {}
|
||||||
|
virtual ~CommonParamToCheckConfigJson() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual Json::Value toJsonValue();
|
||||||
|
virtual void toObjectFromValue(Json::Value root);
|
||||||
|
int GetConfig(CommonCheckConfigST &config);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CommonCheckConfigST _config;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CheckConfigJson : public JsonCoversion
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CheckConfigJson() {}
|
||||||
|
virtual ~CheckConfigJson() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual Json::Value toJsonValue();
|
||||||
|
virtual void toObjectFromValue(Json::Value root);
|
||||||
|
int GetConfig(CheckConfigST &config);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CheckConfigST _config;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ChannelFuntonConfigJson : public JsonCoversion
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ChannelFuntonConfigJson() {}
|
||||||
|
virtual ~ChannelFuntonConfigJson() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual Json::Value toJsonValue();
|
||||||
|
virtual void toObjectFromValue(Json::Value root);
|
||||||
|
int GetConfig(ALLChannelCheckFunction &config);
|
||||||
|
int GetFunction(Json::Value value, CheckFunction &function);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ALLChannelCheckFunction _config;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BaseFuntonConfigJson : public JsonCoversion
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BaseFuntonConfigJson() {}
|
||||||
|
virtual ~BaseFuntonConfigJson() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual Json::Value toJsonValue();
|
||||||
|
virtual void toObjectFromValue(Json::Value root);
|
||||||
|
int GetConfig(BaseCheckFunction &config);
|
||||||
|
int GetFunction(Json::Value value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BaseCheckFunction _config;
|
||||||
|
};
|
||||||
|
#endif //
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
#ifndef JsonCoversion_H
|
||||||
|
#define JsonCoversion_H
|
||||||
|
#include<iostream>
|
||||||
|
#include<memory>
|
||||||
|
#include<string>
|
||||||
|
#include "json/json.h"
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class JsonCoversion
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
Json::Value root;
|
||||||
|
|
||||||
|
// Json::FastWriter writer; //弃用 改用StreamWriterBuilder
|
||||||
|
Json::StreamWriterBuilder writerBuilder;
|
||||||
|
|
||||||
|
// Json::Reader reader; //弃用 改用CharReaderBuilder
|
||||||
|
Json::CharReaderBuilder readerBuilder;
|
||||||
|
public:
|
||||||
|
JsonCoversion();
|
||||||
|
virtual ~JsonCoversion();
|
||||||
|
protected:
|
||||||
|
public:
|
||||||
|
string toJson();
|
||||||
|
void toObject(string & strBuf);
|
||||||
|
protected:
|
||||||
|
virtual Json::Value toJsonValue() = 0;
|
||||||
|
virtual void toObjectFromValue(Json::Value root) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // JsonCoversion_H
|
||||||
@ -0,0 +1,346 @@
|
|||||||
|
/// Json-cpp amalgamated forward header (http://jsoncpp.sourceforge.net/).
|
||||||
|
/// It is intended to be used with #include "json/json-forwards.h"
|
||||||
|
/// This header provides forward declaration for all JsonCpp types.
|
||||||
|
|
||||||
|
// //////////////////////////////////////////////////////////////////////
|
||||||
|
// Beginning of content of file: LICENSE
|
||||||
|
// //////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
The JsonCpp library's source code, including accompanying documentation,
|
||||||
|
tests and demonstration applications, are licensed under the following
|
||||||
|
conditions...
|
||||||
|
|
||||||
|
Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all
|
||||||
|
jurisdictions which recognize such a disclaimer. In such jurisdictions,
|
||||||
|
this software is released into the Public Domain.
|
||||||
|
|
||||||
|
In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
|
||||||
|
2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and
|
||||||
|
The JsonCpp Authors, and is released under the terms of the MIT License (see below).
|
||||||
|
|
||||||
|
In jurisdictions which recognize Public Domain property, the user of this
|
||||||
|
software may choose to accept it either as 1) Public Domain, 2) under the
|
||||||
|
conditions of the MIT License (see below), or 3) under the terms of dual
|
||||||
|
Public Domain/MIT License conditions described here, as they choose.
|
||||||
|
|
||||||
|
The MIT License is about as close to Public Domain as a license can get, and is
|
||||||
|
described in clear, concise terms at:
|
||||||
|
|
||||||
|
http://en.wikipedia.org/wiki/MIT_License
|
||||||
|
|
||||||
|
The full text of the MIT License follows:
|
||||||
|
|
||||||
|
========================================================================
|
||||||
|
Copyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person
|
||||||
|
obtaining a copy of this software and associated documentation
|
||||||
|
files (the "Software"), to deal in the Software without
|
||||||
|
restriction, including without limitation the rights to use, copy,
|
||||||
|
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
========================================================================
|
||||||
|
(END LICENSE TEXT)
|
||||||
|
|
||||||
|
The MIT license is compatible with both the GPL and commercial
|
||||||
|
software, affording one all of the rights of Public Domain with the
|
||||||
|
minor nuisance of being required to keep the above copyright notice
|
||||||
|
and license text in the source code. Note also that by accepting the
|
||||||
|
Public Domain "license" you can re-license your copy using whatever
|
||||||
|
license you like.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// //////////////////////////////////////////////////////////////////////
|
||||||
|
// End of content of file: LICENSE
|
||||||
|
// //////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED
|
||||||
|
# define JSON_FORWARD_AMALGAMATED_H_INCLUDED
|
||||||
|
/// If defined, indicates that the source file is amalgamated
|
||||||
|
/// to prevent private header inclusion.
|
||||||
|
#define JSON_IS_AMALGAMATION
|
||||||
|
|
||||||
|
// //////////////////////////////////////////////////////////////////////
|
||||||
|
// Beginning of content of file: include/json/config.h
|
||||||
|
// //////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
|
||||||
|
// Distributed under MIT license, or public domain if desired and
|
||||||
|
// recognized in your jurisdiction.
|
||||||
|
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
|
||||||
|
|
||||||
|
#ifndef JSON_CONFIG_H_INCLUDED
|
||||||
|
#define JSON_CONFIG_H_INCLUDED
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h> //typedef int64_t, uint64_t
|
||||||
|
#include <string> //typedef String
|
||||||
|
|
||||||
|
/// If defined, indicates that json library is embedded in CppTL library.
|
||||||
|
//# define JSON_IN_CPPTL 1
|
||||||
|
|
||||||
|
/// If defined, indicates that json may leverage CppTL library
|
||||||
|
//# define JSON_USE_CPPTL 1
|
||||||
|
/// If defined, indicates that cpptl vector based map should be used instead of
|
||||||
|
/// std::map
|
||||||
|
/// as Value container.
|
||||||
|
//# define JSON_USE_CPPTL_SMALLMAP 1
|
||||||
|
|
||||||
|
// If non-zero, the library uses exceptions to report bad input instead of C
|
||||||
|
// assertion macros. The default is to use exceptions.
|
||||||
|
#ifndef JSON_USE_EXCEPTION
|
||||||
|
#define JSON_USE_EXCEPTION 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// If defined, indicates that the source file is amalgamated
|
||||||
|
/// to prevent private header inclusion.
|
||||||
|
/// Remarks: it is automatically defined in the generated amalgamated header.
|
||||||
|
// #define JSON_IS_AMALGAMATION
|
||||||
|
|
||||||
|
#ifdef JSON_IN_CPPTL
|
||||||
|
#include <cpptl/config.h>
|
||||||
|
#ifndef JSON_USE_CPPTL
|
||||||
|
#define JSON_USE_CPPTL 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef JSON_IN_CPPTL
|
||||||
|
#define JSON_API CPPTL_API
|
||||||
|
#elif defined(JSON_DLL_BUILD)
|
||||||
|
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||||
|
#define JSON_API __declspec(dllexport)
|
||||||
|
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
|
||||||
|
#endif // if defined(_MSC_VER)
|
||||||
|
#elif defined(JSON_DLL)
|
||||||
|
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||||
|
#define JSON_API __declspec(dllimport)
|
||||||
|
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
|
||||||
|
#endif // if defined(_MSC_VER)
|
||||||
|
#endif // ifdef JSON_IN_CPPTL
|
||||||
|
#if !defined(JSON_API)
|
||||||
|
#define JSON_API
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for
|
||||||
|
// integer
|
||||||
|
// Storages, and 64 bits integer support is disabled.
|
||||||
|
// #define JSON_NO_INT64 1
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) // MSVC
|
||||||
|
#if _MSC_VER <= 1200 // MSVC 6
|
||||||
|
// Microsoft Visual Studio 6 only support conversion from __int64 to double
|
||||||
|
// (no conversion from unsigned __int64).
|
||||||
|
#define JSON_USE_INT64_DOUBLE_CONVERSION 1
|
||||||
|
// Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
|
||||||
|
// characters in the debug information)
|
||||||
|
// All projects I've ever seen with VS6 were using this globally (not bothering
|
||||||
|
// with pragma push/pop).
|
||||||
|
#pragma warning(disable : 4786)
|
||||||
|
#endif // MSVC 6
|
||||||
|
|
||||||
|
#if _MSC_VER >= 1500 // MSVC 2008
|
||||||
|
/// Indicates that the following function is deprecated.
|
||||||
|
#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // defined(_MSC_VER)
|
||||||
|
|
||||||
|
// In c++11 the override keyword allows you to explicitly define that a function
|
||||||
|
// is intended to override the base-class version. This makes the code more
|
||||||
|
// manageable and fixes a set of common hard-to-find bugs.
|
||||||
|
#if __cplusplus >= 201103L
|
||||||
|
#define JSONCPP_OVERRIDE override
|
||||||
|
#define JSONCPP_NOEXCEPT noexcept
|
||||||
|
#define JSONCPP_OP_EXPLICIT explicit
|
||||||
|
#elif defined(_MSC_VER) && _MSC_VER > 1600 && _MSC_VER < 1900
|
||||||
|
#define JSONCPP_OVERRIDE override
|
||||||
|
#define JSONCPP_NOEXCEPT throw()
|
||||||
|
#if _MSC_VER >= 1800 // MSVC 2013
|
||||||
|
#define JSONCPP_OP_EXPLICIT explicit
|
||||||
|
#else
|
||||||
|
#define JSONCPP_OP_EXPLICIT
|
||||||
|
#endif
|
||||||
|
#elif defined(_MSC_VER) && _MSC_VER >= 1900
|
||||||
|
#define JSONCPP_OVERRIDE override
|
||||||
|
#define JSONCPP_NOEXCEPT noexcept
|
||||||
|
#define JSONCPP_OP_EXPLICIT explicit
|
||||||
|
#else
|
||||||
|
#define JSONCPP_OVERRIDE
|
||||||
|
#define JSONCPP_NOEXCEPT throw()
|
||||||
|
#define JSONCPP_OP_EXPLICIT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef JSON_HAS_RVALUE_REFERENCES
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010
|
||||||
|
#define JSON_HAS_RVALUE_REFERENCES 1
|
||||||
|
#endif // MSVC >= 2010
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
#if __has_feature(cxx_rvalue_references)
|
||||||
|
#define JSON_HAS_RVALUE_REFERENCES 1
|
||||||
|
#endif // has_feature
|
||||||
|
|
||||||
|
#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
|
||||||
|
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
|
||||||
|
#define JSON_HAS_RVALUE_REFERENCES 1
|
||||||
|
#endif // GXX_EXPERIMENTAL
|
||||||
|
|
||||||
|
#endif // __clang__ || __GNUC__
|
||||||
|
|
||||||
|
#endif // not defined JSON_HAS_RVALUE_REFERENCES
|
||||||
|
|
||||||
|
#ifndef JSON_HAS_RVALUE_REFERENCES
|
||||||
|
#define JSON_HAS_RVALUE_REFERENCES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
#if __has_extension(attribute_deprecated_with_message)
|
||||||
|
#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
|
||||||
|
#endif
|
||||||
|
#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
|
||||||
|
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
|
||||||
|
#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
|
||||||
|
#elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
|
||||||
|
#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
|
||||||
|
#endif // GNUC version
|
||||||
|
#endif // __clang__ || __GNUC__
|
||||||
|
|
||||||
|
#if !defined(JSONCPP_DEPRECATED)
|
||||||
|
#define JSONCPP_DEPRECATED(message)
|
||||||
|
#endif // if !defined(JSONCPP_DEPRECATED)
|
||||||
|
|
||||||
|
#if __GNUC__ >= 6
|
||||||
|
#define JSON_USE_INT64_DOUBLE_CONVERSION 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(JSON_IS_AMALGAMATION)
|
||||||
|
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
|
#if JSONCPP_USING_SECURE_MEMORY
|
||||||
|
#include "allocator.h" //typedef Allocator
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // if !defined(JSON_IS_AMALGAMATION)
|
||||||
|
|
||||||
|
namespace Json {
|
||||||
|
typedef int Int;
|
||||||
|
typedef unsigned int UInt;
|
||||||
|
#if defined(JSON_NO_INT64)
|
||||||
|
typedef int LargestInt;
|
||||||
|
typedef unsigned int LargestUInt;
|
||||||
|
#undef JSON_HAS_INT64
|
||||||
|
#else // if defined(JSON_NO_INT64)
|
||||||
|
// For Microsoft Visual use specific types as long long is not supported
|
||||||
|
#if defined(_MSC_VER) // Microsoft Visual Studio
|
||||||
|
typedef __int64 Int64;
|
||||||
|
typedef unsigned __int64 UInt64;
|
||||||
|
#else // if defined(_MSC_VER) // Other platforms, use long long
|
||||||
|
typedef int64_t Int64;
|
||||||
|
typedef uint64_t UInt64;
|
||||||
|
#endif // if defined(_MSC_VER)
|
||||||
|
typedef Int64 LargestInt;
|
||||||
|
typedef UInt64 LargestUInt;
|
||||||
|
#define JSON_HAS_INT64
|
||||||
|
#endif // if defined(JSON_NO_INT64)
|
||||||
|
#if JSONCPP_USING_SECURE_MEMORY
|
||||||
|
#define JSONCPP_STRING \
|
||||||
|
std::basic_string<char, std::char_traits<char>, Json::SecureAllocator<char> >
|
||||||
|
#define JSONCPP_OSTRINGSTREAM \
|
||||||
|
std::basic_ostringstream<char, std::char_traits<char>, \
|
||||||
|
Json::SecureAllocator<char> >
|
||||||
|
#define JSONCPP_OSTREAM std::basic_ostream<char, std::char_traits<char> >
|
||||||
|
#define JSONCPP_ISTRINGSTREAM \
|
||||||
|
std::basic_istringstream<char, std::char_traits<char>, \
|
||||||
|
Json::SecureAllocator<char> >
|
||||||
|
#define JSONCPP_ISTREAM std::istream
|
||||||
|
#else
|
||||||
|
#define JSONCPP_STRING std::string
|
||||||
|
#define JSONCPP_OSTRINGSTREAM std::ostringstream
|
||||||
|
#define JSONCPP_OSTREAM std::ostream
|
||||||
|
#define JSONCPP_ISTRINGSTREAM std::istringstream
|
||||||
|
#define JSONCPP_ISTREAM std::istream
|
||||||
|
#endif // if JSONCPP_USING_SECURE_MEMORY
|
||||||
|
} // end namespace Json
|
||||||
|
|
||||||
|
#endif // JSON_CONFIG_H_INCLUDED
|
||||||
|
|
||||||
|
// //////////////////////////////////////////////////////////////////////
|
||||||
|
// End of content of file: include/json/config.h
|
||||||
|
// //////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// //////////////////////////////////////////////////////////////////////
|
||||||
|
// Beginning of content of file: include/json/forwards.h
|
||||||
|
// //////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
|
||||||
|
// Distributed under MIT license, or public domain if desired and
|
||||||
|
// recognized in your jurisdiction.
|
||||||
|
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
|
||||||
|
|
||||||
|
#ifndef JSON_FORWARDS_H_INCLUDED
|
||||||
|
#define JSON_FORWARDS_H_INCLUDED
|
||||||
|
|
||||||
|
#if !defined(JSON_IS_AMALGAMATION)
|
||||||
|
#include "config.h"
|
||||||
|
#endif // if !defined(JSON_IS_AMALGAMATION)
|
||||||
|
|
||||||
|
namespace Json {
|
||||||
|
|
||||||
|
// writer.h
|
||||||
|
class FastWriter;
|
||||||
|
class StyledWriter;
|
||||||
|
|
||||||
|
// reader.h
|
||||||
|
class Reader;
|
||||||
|
|
||||||
|
// features.h
|
||||||
|
class Features;
|
||||||
|
|
||||||
|
// value.h
|
||||||
|
typedef unsigned int ArrayIndex;
|
||||||
|
class StaticString;
|
||||||
|
class Path;
|
||||||
|
class PathArgument;
|
||||||
|
class Value;
|
||||||
|
class ValueIteratorBase;
|
||||||
|
class ValueIterator;
|
||||||
|
class ValueConstIterator;
|
||||||
|
|
||||||
|
} // namespace Json
|
||||||
|
|
||||||
|
#endif // JSON_FORWARDS_H_INCLUDED
|
||||||
|
|
||||||
|
// //////////////////////////////////////////////////////////////////////
|
||||||
|
// End of content of file: include/json/forwards.h
|
||||||
|
// //////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif //ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* @Author: your name
|
||||||
|
* @Date: 2022-04-20 15:50:00
|
||||||
|
* @LastEditTime: 2025-09-11 18:42:03
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
* @FilePath: /ZCXD_MonitorPlatform/src/CoreLogicModule/src/CamDeal.cpp
|
||||||
|
*/
|
||||||
|
#include "ConfigBase.h"
|
||||||
|
#include "ConfigInstance.h"
|
||||||
|
#include "ConfigManager.h"
|
||||||
|
|
||||||
|
std::shared_ptr<ConfigBase> ConfigBase::GetInstance()
|
||||||
|
{
|
||||||
|
std::shared_ptr<ConfigBase> pInstance = std::make_shared<ConfigInstance>();
|
||||||
|
return pInstance;
|
||||||
|
}
|
||||||
|
bool compareBylay(const RegionConfigST &a, const RegionConfigST &b)
|
||||||
|
{
|
||||||
|
return a.basicInfo.lay < b.basicInfo.lay;
|
||||||
|
}
|
||||||
|
ConfigManagerBase *ConfigManagerBase::m_pInstance = nullptr;
|
||||||
|
ConfigManagerBase *ConfigManagerBase::GetInstance()
|
||||||
|
{
|
||||||
|
if (!m_pInstance)
|
||||||
|
{
|
||||||
|
m_pInstance = new ConfigManager();
|
||||||
|
}
|
||||||
|
return m_pInstance;
|
||||||
|
}
|
||||||
@ -0,0 +1,222 @@
|
|||||||
|
/*
|
||||||
|
* @Author: your name
|
||||||
|
* @Date: 2022-04-20 15:50:00
|
||||||
|
* @LastEditTime: 2025-09-25 09:15:15
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
* @FilePath: /ZCXD_MonitorPlatform/src/CoreLogicModule/src/CamDeal.cpp
|
||||||
|
*/
|
||||||
|
#include "ConfigInstance.h"
|
||||||
|
|
||||||
|
ConfigInstance::ConfigInstance()
|
||||||
|
{
|
||||||
|
m_ErrorValue = ERROR_Type_Ok;
|
||||||
|
m_nCurIdx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigInstance::~ConfigInstance()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConfigInstance::GetConfigIdx()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mtx_GetIdx);
|
||||||
|
int reidx = m_nCurIdx;
|
||||||
|
if (reidx < 0)
|
||||||
|
{
|
||||||
|
reidx = 0;
|
||||||
|
}
|
||||||
|
m_nCurIdx++;
|
||||||
|
if (m_nCurIdx >= MAX_USER_COUNT)
|
||||||
|
{
|
||||||
|
m_nCurIdx = MAX_USER_COUNT - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return reidx;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConfigInstance::GetConfigUpdataStatus(int nConfigType, int nidx)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_status);
|
||||||
|
|
||||||
|
if (nConfigType >= 0 && nConfigType < ConfigType_Count && nidx >= 0 && nidx < MAX_USER_COUNT)
|
||||||
|
{
|
||||||
|
m_ErrorValue = ERROR_Type_Ok;
|
||||||
|
bool status = m_USER_ConfigUpdataStatusList[nConfigType][nidx];
|
||||||
|
m_USER_ConfigUpdataStatusList[nConfigType][nidx] = false;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
m_ErrorValue = ERROR_Type_ConfigType;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConfigInstance::GetConfig(int nConfigType, void *pconfig)
|
||||||
|
{
|
||||||
|
if (nConfigType >= 0 && nConfigType < ConfigType_Count)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_ErrorValue = ERROR_Type_ConfigType;
|
||||||
|
return m_ErrorValue;
|
||||||
|
}
|
||||||
|
AnalysisyConfigST *p = (AnalysisyConfigST *)pconfig;
|
||||||
|
CheckConfigST *p1 = (CheckConfigST *)pconfig;
|
||||||
|
ImageInfo *pimg = (ImageInfo *)pconfig;
|
||||||
|
switch (nConfigType)
|
||||||
|
{
|
||||||
|
case ConfigType_Analysisy_Common_XL:
|
||||||
|
p->copy(m_AnalysisyConfig);
|
||||||
|
break;
|
||||||
|
case ConfigType_Check_XL:
|
||||||
|
p1->copy(m_CheckConfig);
|
||||||
|
break;
|
||||||
|
case ConfigType_Image_In:
|
||||||
|
pimg->copy(m_CheckConfig.Srcimg_in);
|
||||||
|
break;
|
||||||
|
case ConfigType_Image_out:
|
||||||
|
pimg->copy(m_CheckConfig.resultimg_out);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ErrorValue = ERROR_Type_Ok;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConfigInstance::UpdateConfig(void *pconfig, int nConfigType)
|
||||||
|
{
|
||||||
|
|
||||||
|
m_ErrorValue = ERROR_Type_Ok;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConfigInstance::UpdateJSONConfig(void *pconfig, int nConfigType)
|
||||||
|
{
|
||||||
|
if (pconfig == NULL)
|
||||||
|
{
|
||||||
|
m_ErrorValue = ERROR_Type_JsonNull;
|
||||||
|
return m_ErrorValue;
|
||||||
|
}
|
||||||
|
if (nConfigType < 0 || nConfigType >= ConfigType_Count)
|
||||||
|
{
|
||||||
|
m_ErrorValue = ERROR_Type_ConfigType;
|
||||||
|
return m_ErrorValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value *pJsonConfig = (Json::Value *)pconfig;
|
||||||
|
switch (nConfigType)
|
||||||
|
{
|
||||||
|
case ConfigType_Analysisy_Common_XL:
|
||||||
|
Updata_analysis(*pJsonConfig);
|
||||||
|
/* code */
|
||||||
|
break;
|
||||||
|
case ConfigType_Check_XL:
|
||||||
|
/* code */
|
||||||
|
Updata_Check(*pJsonConfig);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// getchar();
|
||||||
|
m_ErrorValue = ERROR_Type_Ok;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ConfigInstance::GetVersion()
|
||||||
|
{
|
||||||
|
m_ErrorValue = ERROR_Type_Ok;
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ConfigInstance::GetErrorInfo()
|
||||||
|
{
|
||||||
|
return ERROR_TYPE_Names[m_ErrorValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConfigInstance::Updata_analysis(Json::Value json_value)
|
||||||
|
{
|
||||||
|
|
||||||
|
// std::cout << json_value << std::endl;
|
||||||
|
CommonParamJson configJson;
|
||||||
|
configJson.toObjectFromValue(json_value);
|
||||||
|
CommonParamST config;
|
||||||
|
configJson.GetConfig(config);
|
||||||
|
|
||||||
|
printf("------config.skuName %s \n", config.skuName.c_str());
|
||||||
|
|
||||||
|
// 解析成对应的 参数
|
||||||
|
CommonParamToCheckConfigJson tp;
|
||||||
|
tp.toObjectFromValue(config.value);
|
||||||
|
|
||||||
|
tp.GetConfig(m_AnalysisyConfig.commonCheckConfig);
|
||||||
|
m_AnalysisyConfig.strSkuName = config.skuName;
|
||||||
|
|
||||||
|
int img_W = 0;
|
||||||
|
int img_H = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < m_AnalysisyConfig.commonCheckConfig.nodeConfigArr.size(); i++)
|
||||||
|
{
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
img_W = m_AnalysisyConfig.commonCheckConfig.nodeConfigArr.at(i).nodebasicConfog.img_width;
|
||||||
|
img_H = m_AnalysisyConfig.commonCheckConfig.nodeConfigArr.at(i).nodebasicConfog.img_height;
|
||||||
|
}
|
||||||
|
// m_AnalysisyConfig.commonCheckConfig.nodeConfigArr.at(i).ToMaskImg();
|
||||||
|
// std::string strpath = "mask_" + std::to_string(i) + ".jpg";
|
||||||
|
// if (!m_AnalysisyConfig.commonCheckConfig.nodeConfigArr.at(i).mask.empty())
|
||||||
|
// {
|
||||||
|
// cv::imwrite(strpath, m_AnalysisyConfig.commonCheckConfig.nodeConfigArr.at(i).mask);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析成对应的 参数
|
||||||
|
ChannelFuntonConfigJson jxjason;
|
||||||
|
jxjason.toObjectFromValue(config.value);
|
||||||
|
|
||||||
|
jxjason.GetConfig(m_AnalysisyConfig.checkFunction);
|
||||||
|
for (int i = 0; i < m_AnalysisyConfig.checkFunction.channelFunctionArr.size(); i++)
|
||||||
|
{
|
||||||
|
m_AnalysisyConfig.checkFunction.channelFunctionArr.at(i).function.f_ShieldRegion.ToMaskImg(img_W, img_H);
|
||||||
|
m_AnalysisyConfig.checkFunction.channelFunctionArr.at(i).function.f_EdgeROI.ToMaskImg(img_W, img_H);
|
||||||
|
m_AnalysisyConfig.checkFunction.channelFunctionArr.at(i).function.f_Image_Align.ToMaskImg(img_W, img_H);
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseFuntonConfigJson basefjason;
|
||||||
|
basefjason.toObjectFromValue(config.value);
|
||||||
|
|
||||||
|
basefjason.GetConfig(m_AnalysisyConfig.baseFunction);
|
||||||
|
|
||||||
|
// m_AnalysisyConfig.checkFunction.print("------------ChannelFunction---------------");
|
||||||
|
// getchar();
|
||||||
|
|
||||||
|
// 更新所有状态
|
||||||
|
SetStatus(ConfigType_Analysisy_Common_XL);
|
||||||
|
m_ErrorValue = ERROR_Type_Ok;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConfigInstance::Updata_Check(Json::Value json_value)
|
||||||
|
{
|
||||||
|
std::cout << json_value << std::endl;
|
||||||
|
|
||||||
|
// 解析成对应的 参数
|
||||||
|
CheckConfigJson tp;
|
||||||
|
tp.toObjectFromValue(json_value);
|
||||||
|
tp.GetConfig(m_CheckConfig);
|
||||||
|
// 更新所有状态
|
||||||
|
SetStatus(ConfigType_Check_XL);
|
||||||
|
|
||||||
|
m_ErrorValue = ERROR_Type_Ok;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConfigInstance::SetStatus(int nConfigType)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_USER_COUNT; i++)
|
||||||
|
{
|
||||||
|
m_USER_ConfigUpdataStatusList[nConfigType][i] = true;
|
||||||
|
}
|
||||||
|
m_ErrorValue = ERROR_Type_Ok;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,179 @@
|
|||||||
|
/*
|
||||||
|
* @Author: your name
|
||||||
|
* @Date: 2022-04-20 15:50:00
|
||||||
|
* @LastEditTime: 2025-09-11 22:03:50
|
||||||
|
* @LastEditors: xiewenji 527774126@qq.com
|
||||||
|
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
* @FilePath: /ZCXD_MonitorPlatform/src/CoreLogicModule/src/CamDeal.cpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ConfigManager.h"
|
||||||
|
#include <regex>
|
||||||
|
#include "ConfigBase.h"
|
||||||
|
|
||||||
|
ConfigManager::ConfigManager()
|
||||||
|
{
|
||||||
|
m_strConfigRootPath = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigManager::~ConfigManager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConfigManager::LoadParamConfig(std::shared_ptr<ConfigBase> &Config, std::string strConfigPath)
|
||||||
|
{
|
||||||
|
Json::Reader json_reader;
|
||||||
|
Json::Value json_value;
|
||||||
|
std::ifstream infile(strConfigPath, ios::binary);
|
||||||
|
printf("Analysis_Config_path========== %s \n", strConfigPath.c_str());
|
||||||
|
// getchar();
|
||||||
|
if (infile.is_open())
|
||||||
|
{
|
||||||
|
if (json_reader.parse(infile, json_value))
|
||||||
|
{
|
||||||
|
|
||||||
|
Config->UpdateJSONConfig((void *)&json_value, ConfigType_Analysisy_Common_XL);
|
||||||
|
|
||||||
|
printf("m_pConfig ConfigType_Analysisy_Common_XL %s\n", Config->GetErrorInfo().c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("****%s fail \n", strConfigPath.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("****%s fail \n", strConfigPath.c_str());
|
||||||
|
infile.close();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
infile.close();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int ConfigManager::LoadAnalysisConfig(std::string strConfigPath)
|
||||||
|
{
|
||||||
|
m_strConfigRootPath = strConfigPath;
|
||||||
|
int re = UpdateConfig();
|
||||||
|
return re;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConfigManager::UpdateConfig()
|
||||||
|
{
|
||||||
|
std::vector<CameraParam> camera_list;
|
||||||
|
int re = ReadParamName(camera_list);
|
||||||
|
if (re != 0)
|
||||||
|
{
|
||||||
|
printf("ConfigManager::UpdateConfig() ReadParamName error re = %d\n", re);
|
||||||
|
return re;
|
||||||
|
/* code */
|
||||||
|
}
|
||||||
|
for (auto &camera : camera_list)
|
||||||
|
{
|
||||||
|
std::string strConfigPath = m_strConfigRootPath + "/param_" + camera.code + ".json";
|
||||||
|
std::shared_ptr<ConfigBase> temConfig = ConfigBase::GetInstance();
|
||||||
|
re = LoadParamConfig(temConfig, strConfigPath);
|
||||||
|
if (re != 0)
|
||||||
|
{
|
||||||
|
printf("ConfigManager::UpdateConfig() LoadParamConfig %s error re = %d\n", strConfigPath.c_str(), re);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
AnalysisyConfigST p;
|
||||||
|
temConfig->GetConfig(ConfigType_Analysisy_Common_XL, &p);
|
||||||
|
printf("********* CamearName %s\n", p.commonCheckConfig.baseConfig.strCamearName.c_str());
|
||||||
|
if (p.commonCheckConfig.baseConfig.strCamearName == "")
|
||||||
|
{
|
||||||
|
printf("Error >>>> camear Name is empty \n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Config_instances_[p.commonCheckConfig.baseConfig.strCamearName] = temConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
// getchar();
|
||||||
|
|
||||||
|
// std::regex pattern(R"(param_[0-9]\.json)");
|
||||||
|
// if (!fs::exists(m_strConfigRootPath))
|
||||||
|
// {
|
||||||
|
// std::cerr << "目录不存在: " << m_strConfigRootPath << std::endl;
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
// Config_instances_.clear();
|
||||||
|
// for (const auto &entry : fs::directory_iterator(m_strConfigRootPath))
|
||||||
|
// {
|
||||||
|
// if (entry.is_regular_file())
|
||||||
|
// {
|
||||||
|
// std::string filename = entry.path().filename().string();
|
||||||
|
// if (std::regex_match(filename, pattern))
|
||||||
|
// {
|
||||||
|
// std::cout << "匹配文件: " << entry.path() << std::endl;
|
||||||
|
// std::shared_ptr<ConfigBase> temConfig = ConfigBase::GetInstance();
|
||||||
|
// int re = LoadParamConfig(temConfig, entry.path());
|
||||||
|
// if (re != 0)
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// AnalysisyConfigST p;
|
||||||
|
// temConfig->GetConfig(ConfigType_Analysisy_Common_XL, &p);
|
||||||
|
// printf("********* CamearName %s\n", p.commonCheckConfig.baseConfig.strCamearName.c_str());
|
||||||
|
// if (p.commonCheckConfig.baseConfig.strCamearName == "")
|
||||||
|
// {
|
||||||
|
// printf("Error >>>> camear Name is empty \n");
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// Config_instances_[p.commonCheckConfig.baseConfig.strCamearName] = temConfig;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// std::cerr << "config error 2: " << m_strConfigRootPath << std::endl;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int ConfigManager::GetConfig(int nConfigType, void *pconfig)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConfigManager::ReadParamName(std::vector<CameraParam> &camera_list)
|
||||||
|
{
|
||||||
|
std::string file_path = m_strConfigRootPath + "/camera_list.json";
|
||||||
|
|
||||||
|
Json::Reader json_reader;
|
||||||
|
Json::Value json_value;
|
||||||
|
std::ifstream infile(file_path, ios::binary);
|
||||||
|
|
||||||
|
if (!infile.is_open())
|
||||||
|
{
|
||||||
|
printf("****%s open fail\n", file_path.c_str());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!json_reader.parse(infile, json_value))
|
||||||
|
{
|
||||||
|
printf("****%s parse fail\n", file_path.c_str());
|
||||||
|
infile.close();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
infile.close();
|
||||||
|
|
||||||
|
camera_list.clear();
|
||||||
|
for (const auto &camera : json_value)
|
||||||
|
{
|
||||||
|
CameraParam param;
|
||||||
|
param.identity = camera["identity"].asString();
|
||||||
|
param.code = camera["code"].asString();
|
||||||
|
param.desc = camera["desc"].asString();
|
||||||
|
param.name = camera["name"].asString();
|
||||||
|
param.created_at = camera["created_at"].asInt64();
|
||||||
|
|
||||||
|
printf("Camera: identity=%s, code=%s, name=%s, desc=%s, created_at=%ld\n",
|
||||||
|
param.identity.c_str(), param.code.c_str(), param.name.c_str(), param.desc.c_str(), param.created_at);
|
||||||
|
|
||||||
|
camera_list.push_back(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
#include "Define.h"
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,35 @@
|
|||||||
|
#include "JsonCoversion.h"
|
||||||
|
|
||||||
|
JsonCoversion::JsonCoversion()
|
||||||
|
{
|
||||||
|
//ctor
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonCoversion::~JsonCoversion()
|
||||||
|
{
|
||||||
|
//dtor
|
||||||
|
}
|
||||||
|
string JsonCoversion::toJson()
|
||||||
|
{
|
||||||
|
toJsonValue();
|
||||||
|
|
||||||
|
std::unique_ptr<Json::StreamWriter> jsonWriter(writerBuilder.newStreamWriter());
|
||||||
|
std::ostringstream os;
|
||||||
|
std::string jsonStr;
|
||||||
|
jsonWriter->write(root,&os);
|
||||||
|
jsonStr = os.str();
|
||||||
|
return jsonStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsonCoversion::toObject(string & strBuf)
|
||||||
|
{
|
||||||
|
std::unique_ptr<Json::CharReader> const jsonReader(readerBuilder.newCharReader());
|
||||||
|
|
||||||
|
JSONCPP_STRING errs;
|
||||||
|
bool res = jsonReader->parse(strBuf.c_str(), strBuf.c_str()+strBuf.length(), &root, &errs);
|
||||||
|
if (!res || !errs.empty())
|
||||||
|
{
|
||||||
|
std::cout << "parseJson err. " << errs << std::endl;
|
||||||
|
}
|
||||||
|
toObjectFromValue(root);
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,41 @@
|
|||||||
|
if(CMAKE_BUILD_TYPE MATCHES "(Release|RELEASE|release)")
|
||||||
|
# release mode
|
||||||
|
set(CMAKE_BUILD_TYPE "release")
|
||||||
|
else()
|
||||||
|
set(CMAKE_BUILD_TYPE "debug")
|
||||||
|
# debug mode
|
||||||
|
if(NOT (${CMAKE_C_FLAGS} MATCHES "-g"))
|
||||||
|
add_compile_options(-g)
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g")
|
||||||
|
endif()
|
||||||
|
if(NOT (${CMAKE_CXX_FLAGS} MATCHES "-g"))
|
||||||
|
add_compile_options(-g)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
#---------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
#++++++add c++11 standard and c99 standard
|
||||||
|
if(NOT (${CMAKE_C_FLAGS} MATCHES "-std="))
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT (${CMAKE_CXX_FLAGS} MATCHES "-std="))
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
|
||||||
|
endif()
|
||||||
|
#---------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
#++++++add path of link library
|
||||||
|
if(NOT (${CMAKE_C_FLAGS} MATCHES "-Wl,-rpath,"))
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-rpath,.:lib/:lib/${BUILD_ARCH}/:../lib/${BUILD_ARCH}/:../lib/${BUILD_ARCH}/HK/:../lib/${BUILD_ARCH}/HK/HCNetSDKCom")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT (${CMAKE_CXX_FLAGS} MATCHES "-Wl,-rpath,"))
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,-rpath,.:lib/:lib/${BUILD_ARCH}/:../lib/${BUILD_ARCH}/:../lib/${BUILD_ARCH}/HK/:../lib/${BUILD_ARCH}/HK/HCNetSDKCom")
|
||||||
|
endif()
|
||||||
|
#---------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# message(STATUS "CMAKE_CXX_FLAGS:${CMAKE_CXX_FLAGS}")
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue