first commit

master
xiewenji 1 month ago
commit ed9bca34db

6
.gitignore vendored

@ -0,0 +1,6 @@
/build
/lib
/include
/data
/SaveImg
.vscode/launch.json

@ -0,0 +1,18 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/usr/local/include/opencv4"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c17",
"cppStandard": "gnu++14",
"cppStandard": "c++17",
"intelliSenseMode": "linux-gcc-x64"
}
],
"version": 4
}

@ -0,0 +1,65 @@
{
"files.associations": {
"thread": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"array": "cpp",
"atomic": "cpp",
"bitset": "cpp",
"chrono": "cpp",
"complex": "cpp",
"condition_variable": "cpp",
"cstdint": "cpp",
"deque": "cpp",
"list": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"map": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"set": "cpp",
"string": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"fstream": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"ostream": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"cinttypes": "cpp",
"typeindex": "cpp",
"typeinfo": "cpp",
"variant": "cpp",
"bit": "cpp",
"codecvt": "cpp",
"filesystem": "cpp"
}
}

@ -0,0 +1,81 @@
cmake_minimum_required (VERSION 3.5)
set(ModuleName "TY_CheckModule")
#==============TensorRT ====================
# TensorRT
find_path(TENSORRT_INCLUDE_DIR
NAMES NvInfer.h
PATHS /usr/include/x86_64-linux-gnu /usr/local/include
)
if(NOT TENSORRT_INCLUDE_DIR)
message(FATAL_ERROR "TensorRT headers not found")
endif()
message(STATUS "TENSORRT_INCLUDE_DIR: " ${TENSORRT_INCLUDE_DIR})
#
file(READ "${TENSORRT_INCLUDE_DIR}/NvInferVersion.h" TENSORRT_VERSION_CONTENTS)
string(REGEX MATCH "#define NV_TENSORRT_MAJOR ([0-9]+)" _ ${TENSORRT_VERSION_CONTENTS})
set(TRT_MAJOR_VERSION ${CMAKE_MATCH_1})
message(STATUS "Found TensorRT v${TRT_MAJOR_VERSION}")
#
if(TRT_MAJOR_VERSION VERSION_LESS 10)
message(STATUS " close //#define USE_TERNSORRT10_BIGMODEL")
else()
add_definitions(-DUSE_TERNSORRT10_BIGMODEL=${TEST_VALUE})
message(STATUS "#define USE_TERNSORRT10_BIGMODEL")
endif()
#==============TensorRT ====================
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(
/usr/local/include
/usr/include
#/usr/local/cuda-11.3/targets/x86_64-linux/include
${CMAKE_CURRENT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/include/TensorRT
${PROJECT_SOURCE_DIR}/ConfigModule/include
${PROJECT_SOURCE_DIR}/Common/include
)
link_directories(
/usr/local/lib/
)
set(CMAKE_CUDA_ARCHITECTURES 86)
set(CMAKE_CUDA_COMPILER "/usr/local/cuda/bin/nvcc")
enable_language(CUDA)
# set使*.cpp
file(GLOB SRC_LISTS ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/*.c ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cu)
add_library(TY_Check SHARED ${SRC_LISTS})
target_link_libraries(TY_Check
nvinfer
Config
${OpenCV_LIBS}
${CUDA_LIBRARIES}
)
set(ModuleName "")
add_subdirectory(example)
# make install /usr/local
#
set(CMAKE_INSTALL_PREFIX /usr/local/polet CACHE PATH "Install path prefix" FORCE)
set(HEADER_FILES include/ImgCheckBase.h include/ImgCheckConfig.h)
#
install(TARGETS TY_Check
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)

@ -0,0 +1,54 @@
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}")
if(CHECK_WORK_Value STREQUAL "POL_ET")
set(PROJECT_NAME "test_POL_ET")
elseif(CHECK_WORK_Value STREQUAL "CELL_ET")
set(PROJECT_NAME "test_CELL_ET")
elseif(CHECK_WORK_Value STREQUAL "FOG_ET")
set(PROJECT_NAME "test_FOG_ET")
else()
set(PROJECT_NAME "test_POL_ET")
endif()
#
project(${PROJECT_NAME})
set(ModuleName "${PROJECT_NAME}")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "-Wno-error=deprecated-declarations -Wno-deprecated-declarations")
include_directories(
/usr/local/include
#/usr/local/cuda-12.1/targets/x86_64-linux/include
${CMAKE_CURRENT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/ConfigModule/include
)
link_directories(
/usr/local/lib/
)
file(GLOB SRC_LISTS ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
add_executable(${PROJECT_NAME} ${SRC_LISTS})
target_link_libraries(${PROJECT_NAME}
pthread
z
nvinfer
TY_Check
Config
#/usr/local/cuda-12.1/targets/x86_64-linux/lib/libcudart.so
${OpenCV_LIBS}
)
# RPATH
set_target_properties(${PROJECT_NAME} PROPERTIES
BUILD_RPATH "\$ORIGIN"
)
set(ModuleName "")

@ -0,0 +1,49 @@
/*
* @Descripttion:
* @version:
* @Author: sueRimn
* @Date: 2022-03-16 17:09:11
* @LastEditors: sueRimn
* @LastEditTime: 2022-09-23 17:43:15
*/
#ifndef _CheckDefine_HPP_
#define _CheckDefine_HPP_
#include <opencv2/opencv.hpp>
#include "BlobBase.h"
#define SRC_IMAGE_WIDTH 14192
#define SRC_IMAGE_HEIGHT 10640
#define SRC_IMAGE_SIZE 1*SRC_IMAGE_WIDTH *SRC_IMAGE_HEIGHT
#define AI_BATCH_SIZE 1
enum ERRORDEFINE
{
RESULT_OK,
ERROR_CHECK_IMG_NULL, // 检测图片为空
ERROR_CHECK_RESOURCE_NULL, // 检测资源为空
ERROR_PRECHECK_IMG_NULL, // 预检测图片 异常
};
// 检测控制参数
struct CheckControlConfigSt
{
CheckControlConfigSt()
{
}
};
// 系统运行控制参数
struct SystmeControlConfigST
{
CheckControlConfigSt checkControlConfig; //// 检测控制参数
SystmeControlConfigST()
{
}
};
#endif //_CORELOGICFACTORY_HPP_

@ -0,0 +1,187 @@
#include "ConfigDeal.h"
/******************************************************************************
*
*
*
*
******************************************************************************/
CIni::CIni()
{
memset(m_szKey, 0, sizeof(m_szKey));
m_fp = NULL;
}
/******************************************************************************
*
*
*
*
******************************************************************************/
CIni::~CIni()
{
m_Map.clear();
}
/******************************************************************************
*
*
*
*
******************************************************************************/
INI_RES CIni::OpenFile(const char* pathName, const char* type)
{
string szLine, szMainKey, szLastMainKey, szSubKey;
char strLine[CONFIGLEN] = { 0 };
KEYMAP mLastMap;
int nIndexPos = -1;
int nLeftPos = -1;
int nRightPos = -1;
m_fp = fopen(pathName, type);
if (m_fp == NULL)
{
printf("open inifile %s error!\n", pathName);
return INI_OPENFILE_ERROR;
}
m_Map.clear();
while (fgets(strLine, CONFIGLEN, m_fp))
{
szLine.assign(strLine);
//删除字符串中的非必要字符
nLeftPos = szLine.find("\n");
if (string::npos != nLeftPos)
{
szLine.erase(nLeftPos, 1);
}
nLeftPos = szLine.find("\r");
if (string::npos != nLeftPos)
{
szLine.erase(nLeftPos, 1);
}
//判断是否是主键
nLeftPos = szLine.find("[");
nRightPos = szLine.find("]");
if (nLeftPos != string::npos && nRightPos != string::npos)
{
szLine.erase(nLeftPos, 1);
/*nRightPos-;*/
nRightPos--;
szLine.erase(nRightPos, 1);
m_Map[szLastMainKey] = mLastMap;
mLastMap.clear();
szLastMainKey = szLine;
}
else
{
//是否是子键
if (nIndexPos = szLine.find("="), string::npos != nIndexPos)
{
string szSubKey, szSubValue;
szSubKey = szLine.substr(0, nIndexPos);
szSubValue = szLine.substr(nIndexPos + 1, szLine.length() - nIndexPos - 1);
mLastMap[szSubKey] = szSubValue;
}
else
{
//TODO:不符合ini键值模板的内容 如注释等
}
}
}
//插入最后一次主键
m_Map[szLastMainKey] = mLastMap;
fclose(m_fp);
m_fp = NULL; /* 需要指向空,否则会指向原打开文件地址 */
return INI_SUCCESS;
}
/******************************************************************************
*
*
*
*
******************************************************************************/
INI_RES CIni::CloseFile()
{
if (m_fp != NULL)
{
fclose(m_fp);
m_fp = NULL;
}
return INI_SUCCESS;
}
/******************************************************************************
* [SECTION]
*
* char* mAttr
* char* cAttr
* char* value
*
*
******************************************************************************/
INI_RES CIni::GetKey(const char* mAttr, const char* cAttr, char* pValue)
{
KEYMAP mKey = m_Map[mAttr];
string sTemp = mKey[cAttr];
//printf("___ %s \n", sTemp.c_str());
strcpy(pValue, sTemp.c_str());
return INI_SUCCESS;
}
/******************************************************************************
*
*
* cAttr
* cAttr
* 0(0)
*
******************************************************************************/
int CIni::GetInt(const char* mAttr, const char* cAttr)
{
int nRes = 0;
memset(m_szKey, 0, sizeof(m_szKey));
if (INI_SUCCESS == GetKey(mAttr, cAttr, m_szKey))
{
nRes = atoi(m_szKey);
}
return nRes;
}
/******************************************************************************
*
*
* cAttr
* cAttr
* "NULL"
*
******************************************************************************/
char *CIni::GetStr(const char* mAttr, const char* cAttr)
{
memset(m_szKey, 0, sizeof(m_szKey));
if (INI_SUCCESS != GetKey(mAttr, cAttr, m_szKey))
{
strcpy(m_szKey, "NULL");
}
return m_szKey;
}

@ -0,0 +1,59 @@
#ifndef _CONFIGDEAL_HPP_
#define _CONFIGDEAL_HPP_
#include <map>
#include <iostream>
#include <string>
#include <string.h>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
#define CONFIGLEN 256
#define CheckData_CONFIG_File "../DataConfig/CheckData_Config.ini"
enum INI_RES
{
INI_SUCCESS, //成功
INI_ERROR, //普通错误
INI_OPENFILE_ERROR, //打开文件失败
INI_NO_ATTR //无对应的键值
};
// 子键索引 子键值
typedef map<std::string, std::string> KEYMAP;
// 主键索引 主键值
typedef map<std::string, KEYMAP> MAINKEYMAP;
// config 文件的基本操作类
class CIni
{
public:
// 构造函数
CIni();
// 析够函数
virtual ~CIni();
public:
//获取整形的键值
int GetInt(const char* mAttr, const char* cAttr);
//获取键值的字符串
char *GetStr(const char* mAttr, const char* cAttr);
// 打开config 文件
INI_RES OpenFile(const char* pathName, const char* type);
// 关闭config 文件
INI_RES CloseFile();
protected:
// 读取config文件
INI_RES GetKey(const char* mAttr, const char* cAttr, char* value);
protected:
// 被打开的文件局柄
FILE* m_fp;
char m_szKey[CONFIGLEN];
MAINKEYMAP m_Map;
};
#endif //_CORELOGICFACTORY_HPP_

@ -0,0 +1,129 @@
#include "Image_ReadAndChange.h"
#include "json/json.h"
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string>
#include <map>
#include <iostream>
#include <string>
#include <string.h>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <mutex>
#include <unistd.h>
Image_ReadChannel::Image_ReadChannel()
{
m_ChannelNameList.clear();
}
Image_ReadChannel::~Image_ReadChannel()
{
}
bool Image_ReadChannel::containsChinese(const std::string &str)
{
for (size_t i = 0; i < str.size(); ++i)
{
if ((unsigned char)str[i] >= 0x80)
{
return true; // 如果有非ASCII字符可能是中文
}
}
return false;
}
bool Image_ReadChannel::CompareIgnoreCase(const std::string &str1, const std::string &str2)
{
// 将 str1 和 str2 转换为小写后进行比较
std::string lower_str1 = str1;
std::string lower_str2 = str2;
// 使用 std::transform 将字符串转换为小写
std::transform(lower_str1.begin(), lower_str1.end(), lower_str1.begin(), ::tolower);
std::transform(lower_str2.begin(), lower_str2.end(), lower_str2.begin(), ::tolower);
// 比较两个转换后的字符串
return lower_str1 == lower_str2;
}
int Image_ReadChannel::ReadJsonConfig(std::string json_path)
{
m_ChannelNameList.erase(m_ChannelNameList.begin(), m_ChannelNameList.end());
std::string strPath = json_path;
printf("ReadJsonConfig path %s\n", strPath.c_str());
Json::CharReaderBuilder builder;
builder["collectComments"] = true;
Json::Value root;
std::string err;
std::ifstream ifs(strPath);
if (!ifs.is_open())
{
printf("error:file is open\n");
return false;
}
if (!Json::parseFromStream(builder, ifs, &root, &err))
{
printf("error:parseFromStream\n");
return false;
}
for (int i = 0; i < root.size(); i++)
{
printf("Node idx %d /%d \n", i, root.size());
ReadImageName tem;
tem.strDetChannle = root[i]["code"].asString();
std::string strimgname = root[i]["image_name"].asString();
{
std::istringstream stream(strimgname);
std::string token;
// 使用 getline 按照分号分割
while (std::getline(stream, token, ';'))
{
tem.strImgNameList.push_back(token);
}
}
printf("det name %s img name Num %d \n", tem.strDetChannle.c_str(), tem.strImgNameList.size());
// 输出分割后的结果
for (const auto &str : tem.strImgNameList)
{
std::cout << str << std::endl;
}
m_ChannelNameList.push_back(tem);
}
return 0;
}
std::string Image_ReadChannel::strDetName(std::string strImageName)
{
std::string strDetName = "";
for (const auto name : m_ChannelNameList)
{
for (int i = 0; i < name.strImgNameList.size(); i++)
{
// 包含中文
if (containsChinese(strImageName))
{
// printf("strImageName %s name.strImgNameList.at(i) %s\n",strImageName.c_str(), name.strImgNameList.at(i).c_str());
if (strImageName == name.strImgNameList.at(i))
{
return name.strDetChannle;
}
}
else
{
if (CompareIgnoreCase(strImageName, name.strImgNameList.at(i)))
{
return name.strDetChannle;
}
}
}
}
return strDetName;
}

@ -0,0 +1,56 @@
/*
* @Author: xiewenji 527774126@qq.com
* @Date: 2025-07-25 09:14:25
* @LastEditors: xiewenji 527774126@qq.com
* @LastEditTime: 2025-07-26 10:51:45
* @FilePath: /BOE_CELL_ET/AlgorithmModule/example/Image_ReadAndChange.h
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
/*
//图片基本处理
*/
#ifndef Image_ReadAndChange_H_
#define Image_ReadAndChange_H_
#include <vector>
#include <thread>
#include "CheckDefine.h"
#include "ImgCheckConfig.h"
using namespace std;
// 图片读取的通道
class Image_ReadChannel
{
public:
struct ReadImageName
{
std::string strDetChannle;
std::vector<std::string> strImgNameList;
ReadImageName()
{
strImgNameList.clear();
strDetChannle = "";
}
};
private:
/* data */
public:
Image_ReadChannel(/* args */);
~Image_ReadChannel();
bool containsChinese(const std::string &str);
int ReadJsonConfig(std::string json_path); // 加载检测图片名称配置参数
bool CompareIgnoreCase(const std::string &str1, const std::string &str2);
std::string strDetName(std::string strImageName);
private:
std::vector<ReadImageName> m_ChannelNameList;
};
#endif

@ -0,0 +1,166 @@
/*
* @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 "ImgBasicDeal.h"
ImgBasicDeal::ImgBasicDeal()
{
// DrawBlobErrorCorleList[ERROR_TYPE_OK] = cv::Scalar(128, 128, 128);
// DrawBlobErrorCorleList[ERROR_TYPE_yc] = cv::Scalar(255, 0, 0);
}
ImgBasicDeal::~ImgBasicDeal()
{
}
int ImgBasicDeal::DrawResult(cv::Mat &image_draw, CheckResult result)
{
// if (resultimg.channels() == 1)
// {
// cv::cvtColor(resultimg, image_draw, cv::COLOR_GRAY2RGB); // 彩色 可选项
// }
// else
// {
// image_draw = resultimg.clone();
// }
// printf("result.blobResult.blobNum %d\n", result.blobResult.blobNum);
// for (int i = 0; i < result.blobResult.blobNum; i++)
// {
// // if (blobs.Pass[i])
// {
// auto enType = result.blobResult.bloblist[i].UserErrorType;
// if (result.blobResult.bloblist[i].UserErrorType == 0)
// {
// continue;
// }
// cv::Rect roi = result.blobResult.bloblist[i].blob_ResizeImg;
// cv::Point pc;
// pc.x = roi.x + roi.width * 0.5;
// pc.y = roi.y + roi.height * 0.5;
// int rw = roi.width * 0.5;
// int rh = roi.height * 0.5;
// int r = std::sqrt(rw * rw + rh * rh) * 1.1 + 8;
// cv::circle(image_draw, pc, r, DrawBlobErrorCorleList[result.blobResult.bloblist[i].UserErrorType]);
// // 设置绘制文本的相关参数
// std::string text = std::to_string(result.blobResult.bloblist[i].UserErrorType) + " A: " + std::to_string(result.blobResult.bloblist[i].JudgArea) + " E: " + std::to_string(result.blobResult.bloblist[i].energy);
// int baseline;
// // 获取文本框的长宽
// cv::Size text_size = cv::getTextSize(text, font_face, font_scale, thickness, &baseline);
// // 将文本框居中绘制
// cv::Point origin = CalcTextPosition(pc, r, text_size, image_draw.size(), (ERROR_TYPE_)enType);
// cv::putText(image_draw, text, origin, font_face, font_scale, cv::Scalar(255, 0, 0), thickness, 1, 0);
// }
// }
return 0;
}
cv::Point ImgBasicDeal::CalcTextPosition(cv::Point pt, int radius, cv::Size text_size, cv::Size image_size, ERROR_TYPE_ type)
{
cv::Point dst;
int y_offset = 0;
// switch (type)
// {
// case ERROR_TYPE_OK:
// y_offset = 20;
// break;
// case ERROR_TYPE_yc:
// y_offset = 40;
// break;
// default:
// break;
// }
dst.y = (pt.y - y_offset > text_size.height) ? pt.y - y_offset : pt.y + y_offset;
if (dst.y >= image_size.height)
{
dst.y = image_size.height - 1;
}
dst.x = (pt.x + radius + text_size.width > image_size.width) ? pt.x - text_size.width - radius : pt.x + radius;
if (dst.x < 0)
{
dst.x = 0;
}
return dst;
}
int ImgBasicDeal::DrawResult_small(cv::Mat &image_draw, int i, int j, CheckResult result)
{
// cv::cvtColor(result.SamllImgList[i][j].img, image_draw, cv::COLOR_GRAY2RGB); // 彩色 可选项
// for (int k = 0; k < result.SamllImgList[i][j].qxIndexArr.size(); k++)
// {
// int idx = result.SamllImgList[i][j].qxIndexArr.at(k);
// {
// float energy;
// float hj;
// cv::Rect roi = result.qxiImageResult.at(idx).SmallImgroi;
// cv::Point pc;
// pc.x = roi.x + roi.width * 0.5;
// pc.y = roi.y + roi.height * 0.5;
// int rw = roi.width * 0.5;
// int rh = roi.height * 0.5;
// int r = std::sqrt(rw * rw + rh * rh) * 1.5 + 12;
// cv::Scalar dcolor = cv::Scalar(0, 0, 255);
// if (result.qxiImageResult.at(idx).type == 0)
// {
// dcolor = cv::Scalar(0, 255, 0);
// }
// cv::circle(image_draw, pc, r, dcolor);
// // 设置绘制文本的相关参数
// char text[1024] = {0};
// sprintf(text, "A:%.2f E:%.0f", result.qxiImageResult.at(idx).area, result.qxiImageResult.at(idx).energy);
// int baseline;
// int font_face = cv::FONT_HERSHEY_SIMPLEX;
// double font_scale = 0.5;
// int thickness = 1;
// // 获取文本框的长宽
// cv::Size text_size = cv::getTextSize(text, font_face, font_scale, thickness, &baseline);
// // 将文本框居中绘制
// cv::Point origin = cv::Point(roi.x, roi.y - 10);
// if (origin.x + text_size.width > image_draw.cols)
// {
// origin.x = image_draw.cols - text_size.width;
// }
// if (origin.y < 10)
// {
// origin.y = 10;
// }
// cv::putText(image_draw, text, origin, font_face, font_scale, cv::Scalar(255, 0, 0), thickness, 1, 0);
// }
// }
return 0;
}
int ImgBasicDeal::DrawPointList(cv::Mat &image_draw, std::vector<cv::Point> plist)
{
return 0;
}
int ImgBasicDeal::preDealImg(cv::Mat &srcimg, cv::Mat &image_resize, bool bfilpSrcImg)
{
return 0;
}

@ -0,0 +1,44 @@
/*
//图片基本处理
*/
#ifndef ImgBasicDeal_H_
#define ImgBasicDeal_H_
#include <vector>
#include <thread>
#include "CheckDefine.h"
#include "ImgCheckConfig.h"
using namespace std;
class ImgBasicDeal
{
public:
ImgBasicDeal();
~ImgBasicDeal();
/// @brief 画结果信息到图片上
/// @return
int DrawResult(cv::Mat &image_draw, CheckResult result);
/// @brief 对图像预处理
/// @param srcimg 原始图 输出 原始图或镜像图
/// @param resizeimg 裁剪resize到 固定大小的图片
/// @param bfilpSrcimg 是否镜像原始图
/// @return
int DrawResult_small(cv::Mat &image_draw, int i, int j, CheckResult result);
int preDealImg(cv::Mat &srcimg, cv::Mat &image_resize, bool bfilpSrcImg = true);
int DrawPointList(cv::Mat &image_draw, std::vector<cv::Point> plist);
cv::Point CalcTextPosition(cv::Point pt, int radius, cv::Size text_size, cv::Size image_size, ERROR_TYPE_ type);
public:
int font_face = cv::FONT_HERSHEY_SIMPLEX;
double font_scale = 0.5;
int thickness = 1;
cv::Scalar Color_Brightness_roi = cv::Scalar(0, 255, 0);
cv::Scalar Color_Brightness_text = cv::Scalar(0, 255, 0);
cv::Scalar DrawBlobErrorCorleList[ERROR_TYPE_COUNT];
private:
};
#endif

@ -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);
}

@ -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,470 @@
#include "Read_Image.h"
#include <filesystem>
// 转小写
std::string toLower(const std::string &str)
{
std::string lower = str;
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
return lower;
}
int Extract_Name_Base::Read_Product_Image(std::string strPath)
{
return 0;
}
int Extract_Name_Base::Read_Camera_Product_Image(std::string strPath, int userflag)
{
std::vector<cv::String> img_paths;
std::cout << strPath << std::endl;
cv::glob(strPath, img_paths, true);
for (int i = 0; i < img_paths.size(); i++)
{
string strImagePath = img_paths[i];
Extract_Info(strImagePath, userflag);
}
return 0;
}
int Extract_Name_Base::Read_Product_Camera_Image(std::string strPath)
{
return 0;
}
std::shared_ptr<Product_File_Info> Extract_Name_Base::GetProduct(std::string strProductID)
{
for (int i = 0; i < m_product_Camera_List.size(); i++)
{
if (m_product_Camera_List[i]->strProductID == strProductID)
{
return m_product_Camera_List[i];
}
}
return std::shared_ptr<Product_File_Info>();
}
std::shared_ptr<Camera_File_Info> Extract_Name_Base::GetCamera(std::string strProductID, std::string strCamName)
{
for (int i = 0; i < m_product_Camera_List.size(); i++)
{
if (m_product_Camera_List[i]->strProductID == strProductID)
{
for (int j = 0; j < m_product_Camera_List[i]->camera_list.size(); j++)
{
if (m_product_Camera_List[i]->camera_list[j]->strCamName == strCamName)
{
return m_product_Camera_List[i]->camera_list[j];
}
}
}
}
return std::shared_ptr<Camera_File_Info>();
}
std::shared_ptr<Camera_File_Info> Extract_Name_Base::GetCamera(std::shared_ptr<Product_File_Info> product, std::string strCamName)
{
for (int i = 0; i < product->camera_list.size(); i++)
{
if (product->camera_list[i]->strCamName == strCamName)
{
return product->camera_list[i];
}
}
return std::shared_ptr<Camera_File_Info>();
}
// 判断目录部分是否包含某些关键词(不区分大小写)
bool Extract_Name_Base::dirPathContains(const fs::path &fullPath, const std::string KeyName)
{
fs::path parentDir = fullPath.parent_path();
std::string lowKeyName = toLower(KeyName);
for (const auto &dir : parentDir)
{
std::string dirName = toLower(dir.string());
if (dirName == lowKeyName)
{
return true;
}
}
return false;
}
Read_Image::Read_Image(/* args */)
{
}
Read_Image::~Read_Image()
{
}
int Read_Image::Read_Image_List(std::string strPath)
{
m_extract_CELL_ET.pimage_ReadChannel = pimage_ReadChannel;
m_extract_CELL_ET.m_product_Camera_List.clear();
int re = m_extract_CELL_ET.Read_Image_List(strPath);
if (re != 0)
{
return re;
}
m_product_Camera_List.clear();
m_product_Camera_List.assign(m_extract_CELL_ET.m_product_Camera_List.begin(), m_extract_CELL_ET.m_product_Camera_List.end());
for (int i = 0; i < m_extract_CELL_ET.m_product_Camera_List.size(); i++)
{
m_extract_CELL_ET.m_product_Camera_List[i]->print();
}
// m_extract_BD.m_product_Camera_List.clear();
// int re = m_extract_BD.Read_Image_List(strPath);
// if (re != 0)
// {
// return re;
// }
// m_product_Camera_List.clear();
// m_product_Camera_List.assign(m_extract_BD.m_product_Camera_List.begin(), m_extract_BD.m_product_Camera_List.end());
// for (int i = 0; i < m_extract_BD.m_product_Camera_List.size(); i++)
// {
// m_extract_BD.m_product_Camera_List[i]->print();
// }
return 0;
}
int Extract_CELL_ET::Extract_Info(std::string strPath, int userflag)
{
std::cout << strPath << std::endl;
// 1、获取 产品名称
std::string strProductName = Extract_Product_Name(strPath, userflag);
if (strProductName.empty())
{
return -1;
}
std::shared_ptr<Product_File_Info> pProduct = GetProduct(strProductName);
if (pProduct.get() == nullptr)
{
printf("pProduct %s is NULL \n", strProductName.c_str());
pProduct = std::make_shared<Product_File_Info>();
pProduct->strProductID = strProductName;
m_product_Camera_List.push_back(pProduct);
}
// 2、获取 相机名称
std::string strCameraName = Extract_Camera_Name(strPath, userflag);
if (strCameraName.empty())
{
printf("strCameraName is error \n");
return -1;
}
std::shared_ptr<Camera_File_Info> pCamera = GetCamera(pProduct, strCameraName);
if (pCamera.get() == nullptr)
{
printf("pCamera %s is NULL \n", strCameraName.c_str());
pCamera = std::make_shared<Camera_File_Info>();
pCamera->strCamName = strCameraName;
pProduct->camera_list.push_back(pCamera);
}
// 3、获取 通道
std::string strChannelName = Extract_Channel_Name(strPath,userflag);
if (strChannelName.empty())
{
printf("strChannelName is NULL \n");
return -1;
}
fs::path p = fs::path(strPath);
std::string filenameWithoutExt = p.stem().string();
std::shared_ptr<Image_Info> pImage = std::make_shared<Image_Info>();
pImage->strProductID = strProductName;
pImage->strCamID = strCameraName;
pImage->strchannelName = strChannelName;
pImage->strName = filenameWithoutExt;
pImage->strPath = strPath;
pCamera->image_list.push_back(pImage);
return 0;
}
std::string Extract_CELL_ET::Extract_Camera_Name(std::string strPath, int userflag)
{
if (userflag == 1)
{
std::string prefix = "_0_";
bool bleft = false;
size_t pos1 = strPath.rfind(prefix);
if (pos1 != std::string::npos)
{
bleft = true;
}
std::string prefix1 = "工位左";
bool bleft1 = false;
size_t pos2 = strPath.rfind(prefix1);
if (pos2 != std::string::npos)
{
bleft1 = true;
}
if (bleft || bleft1)
{
return "left";
}
else
{
std::string prefix = "_1_";
bool bright = false;
size_t pos1 = strPath.rfind(prefix);
if (pos1 != std::string::npos)
{
bright = true;
}
std::string prefix1 = "工位右";
bool bright1 = false;
size_t pos2 = strPath.rfind(prefix1);
if (pos2 != std::string::npos)
{
bright1 = true;
}
if (bright || bright1)
{
return "right";
}
}
}
else
{
fs::path p = fs::path(strPath);
bool bleft = dirPathContains(p, "left");
bool bleft1 = dirPathContains(p, "shard_left");
if (bleft || bleft1)
{
return "left";
}
else
{
bool bright = dirPathContains(p, "right");
bool bright1 = dirPathContains(p, "shard_right");
if (bright || bright1)
{
return "right";
}
}
}
return "";
}
std::string Extract_CELL_ET::Extract_Product_Name(std::string strPath, int userflag)
{
if (userflag == 0)
{
/* code */
// std::cout << strPath << std::endl;
fs::path p = fs::path(strPath);
fs::path lastDir = p.parent_path().filename();
std::string name = lastDir.string();
if (name.empty())
{
return "";
}
std::string prefix = "__DB__";
if (name.rfind(prefix, 0) == 0)
{ // 判断是否以 "__DB__" 开头
std::string result = name.substr(prefix.length());
std::cout << "Product name: " << result << std::endl;
return result;
}
else
{
std::cout << "Product name error: " << name << std::endl;
}
}
else if (userflag == 1)
{
fs::path p = fs::path(strPath);
fs::path lastDir = p.parent_path().filename();
std::string name = lastDir.string();
if (name.empty() || name != "OriginalImage")
{
return "";
}
fs::path lastDir123 = p.parent_path().parent_path().filename();
std::string sproduct = lastDir123.string();
// std::cout << "Product name error: " << sproduct << std::endl;
size_t lastUnderscore = sproduct.find('_');
if (lastUnderscore == std::string::npos)
return "";
std::string strImageproduct = sproduct.substr(0, lastUnderscore);
// printf("strImageChannel %s\n", strImageproduct.c_str());
return strImageproduct;
}
// // 独特判断
// if (name.find("__DB__") != std::string::npos)
// {
// }
return "";
}
std::string Extract_CELL_ET::Extract_Channel_Name(std::string strPath, int userflag)
{
std::string strchannelName = "";
if (userflag == 1)
{
fs::path p = fs::path(strPath);
std::string filenameWithoutExt = p.stem().string();
std::cout << "提取的内容: " << filenameWithoutExt << std::endl;
if (pimage_ReadChannel)
{
strchannelName = pimage_ReadChannel->strDetName(filenameWithoutExt);
}
}
else
{
fs::path p = fs::path(strPath);
std::string filenameWithoutExt = p.stem().string();
// std::cout << "提取的内容: " << filenameWithoutExt << std::endl;
std::string strexName = "";
size_t pos = filenameWithoutExt.find('^');
if (pos != std::string::npos && pos + 1 < filenameWithoutExt.size())
{
strexName = filenameWithoutExt.substr(pos + 1);
std::cout << "提取到的字符串: " << strexName << std::endl;
}
if (pimage_ReadChannel)
{
strchannelName = pimage_ReadChannel->strDetName(strexName);
}
}
return strchannelName;
}
int Extract_CELL_ET::Read_Image_List(std::string strPath)
{
std::string strSearchImgPath = strPath + "/*.tif";
Read_Camera_Product_Image(strSearchImgPath, 0);
strSearchImgPath = strPath + "/*.png";
Read_Camera_Product_Image(strSearchImgPath, 1);
return 0;
}
int Extract_BD::Extract_Info(std::string strPath, int userflag)
{
std::cout << strPath << std::endl;
// 1、获取 产品名称
std::string strProductName = Extract_Product_Name(strPath);
if (strProductName.empty())
{
return -1;
}
std::shared_ptr<Product_File_Info> pProduct = GetProduct(strProductName);
if (pProduct.get() == nullptr)
{
printf("pProduct %s is NULL \n", strProductName.c_str());
pProduct = std::make_shared<Product_File_Info>();
pProduct->strProductID = strProductName;
m_product_Camera_List.push_back(pProduct);
}
// 2、获取 相机名称
std::string strCameraName = Extract_Camera_Name(strPath);
if (strCameraName.empty())
{
return -1;
}
std::shared_ptr<Camera_File_Info> pCamera = GetCamera(pProduct, strCameraName);
if (pCamera.get() == nullptr)
{
printf("pCamera %s is NULL \n", strCameraName.c_str());
pCamera = std::make_shared<Camera_File_Info>();
pCamera->strCamName = strCameraName;
pProduct->camera_list.push_back(pCamera);
}
// 3、获取 通道
std::string strChannelName = Extract_Channel_Name(strPath);
if (strChannelName.empty())
{
return -1;
}
fs::path p = fs::path(strPath);
std::string filenameWithoutExt = p.stem().string();
std::shared_ptr<Image_Info> pImage = std::make_shared<Image_Info>();
pImage->strProductID = strProductName;
pImage->strCamID = strCameraName;
pImage->strchannelName = strChannelName;
pImage->strName = filenameWithoutExt;
pImage->strPath = strPath;
pCamera->image_list.push_back(pImage);
return 0;
return 0;
}
std::string Extract_BD::Extract_Camera_Name(std::string strPath, int userflag)
{
fs::path p = fs::path(strPath);
return "";
}
std::string Extract_BD::Extract_Product_Name(std::string strPath, int userflag)
{
fs::path p = fs::path(strPath);
fs::path lastDir = p.parent_path().filename();
std::string name = lastDir.string();
if (name.empty())
{
return "";
}
size_t pos = name.rfind('-'); // 找最后一个 '-'
if (pos != std::string::npos && pos + 1 < name.size())
{
return name.substr(pos + 1);
}
return ""; // 没有找到 '-' 或后面没有字符
}
std::string Extract_BD::Extract_Channel_Name(std::string strPath, int userflag)
{
return "";
}
int Extract_BD::Read_Image_List(std::string strPath)
{
std::string strSearchImgPath = strPath + "/*.jpg";
Read_Camera_Product_Image(strSearchImgPath, 0);
return 0;
}

@ -0,0 +1,192 @@
#ifndef Read_Image_HPP_
#define Read_Image_HPP_
#include <map>
#include <iostream>
#include <string>
#include <string.h>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <filesystem>
#include <opencv2/opencv.hpp>
#include "Image_ReadAndChange.h"
namespace fs = std::filesystem;
using namespace std;
// 图片信息
struct Image_Info
{
std::string strProductID; // 产品ID
std::string strCamID; // 相机名称
std::string strchannelName; // 通道名称
std::string strPath; // 完整路径
std::string strName; // 图片名称
cv::Mat img; // 图像数据
long readImg_start; // 读取开始时间
long readImg_end; // 读取结束时间
// 构造函数,调用 Init 初始化
Image_Info()
{
Init();
}
// 初始化函数,重置所有成员变量
void Init()
{
strProductID = "";
strCamID = "";
strchannelName = "";
strPath = "";
strName = "";
img.release(); // 释放图像内存
readImg_start = 0;
readImg_end = 0;
}
void print()
{
std::cout << "Product ID: " << strProductID << std::endl;
std::cout << "Camera ID: " << strCamID << std::endl;
std::cout << "Channel Name: " << strchannelName << std::endl;
std::cout << "Image Path: " << strPath << std::endl;
std::cout << "Image Name: " << strName << std::endl;
std::cout << "Read Start Time: " << readImg_start << std::endl;
std::cout << "Read End Time: " << readImg_end << std::endl;
}
};
// 相机信息
struct Camera_File_Info
{
std::string strCamName; // 相机名称
std::string strCamPath; // 相机路径
vector<std::shared_ptr<Image_Info>> image_list; // 图片信息列表
Camera_File_Info()
{
Init();
}
void Init()
{
strCamName = "";
strCamPath = "";
}
int getImgNum()
{
int num = 0;
for (auto item : image_list)
{
num++;
}
return num;
}
void print()
{
printf("************CamName: %s img num %ld\n", strCamName.c_str(), image_list.size());
// for (auto &item : image_list)
// {
// // item->print();
// }
}
};
// 产品信息
struct Product_File_Info
{
std::string strProductID; // 产品ID
std::string strProductPath; // 产品路径
vector<std::shared_ptr<Camera_File_Info>> camera_list; // 相机信息列表
Product_File_Info()
{
Init();
}
void Init()
{
strProductID = "";
strProductPath = "";
}
int getImgNum()
{
int num = 0;
for (auto item : camera_list)
{
num += item->getImgNum();
}
return num;
}
void print()
{
printf("***strProductID: %s\n", strProductID.c_str());
for (auto &item : camera_list)
{
item->print();
}
}
};
class Extract_Name_Base
{
public:
virtual int Extract_Info(std::string strPath,int userflag) = 0;
virtual std::string Extract_Camera_Name(std::string strPath,int userflag = 0) = 0;
virtual std::string Extract_Product_Name(std::string strPath,int userflag = 0) = 0;
virtual std::string Extract_Channel_Name(std::string strPath,int userflag = 0) = 0;
virtual int Read_Image_List(std::string strPath) = 0;
int Read_Product_Image(std::string strPath);
int Read_Camera_Product_Image(std::string strPath,int userflag) ;
int Read_Product_Camera_Image(std::string strPath);
std::shared_ptr<Product_File_Info> GetProduct(std::string strProductID);
std::shared_ptr<Camera_File_Info> GetCamera(std::string strProductID, std::string strCamName);
std::shared_ptr<Camera_File_Info> GetCamera(std::shared_ptr<Product_File_Info> product, std::string strCamName);
bool dirPathContains(const fs::path &fullPath, const std::string KeyName);
vector<std::shared_ptr<Product_File_Info>> m_product_Camera_List;
Image_ReadChannel *pimage_ReadChannel;
};
class Extract_CELL_ET : public Extract_Name_Base
{
public:
int Extract_Info(std::string strPath,int userflag = 0);
std::string Extract_Camera_Name(std::string strPath,int userflag = 0);
std::string Extract_Product_Name(std::string strPath,int userflag = 0);
std::string Extract_Channel_Name(std::string strPath,int userflag = 0);
int Read_Image_List(std::string strPath);
};
class Extract_BD : public Extract_Name_Base
{
public:
int Extract_Info(std::string strPath,int userflag );
std::string Extract_Camera_Name(std::string strPath,int userflag = 0);
std::string Extract_Product_Name(std::string strPath,int userflag = 0);
std::string Extract_Channel_Name(std::string strPath,int userflag = 0);
int Read_Image_List(std::string strPath);
};
class Read_Image
{
public:
// 图片文件的格式
enum Image_File_TYPE_
{
Image_File_Product_Image, // 产品-图片格式
Image_File_Camera_Product_Image, // 相机-产品-图片格式
Image_File_Product_Camera_Image, // 产品-相机-图片格式
};
public:
Read_Image(/* args */);
~Read_Image();
int Read_Image_List(std::string strPath);
Extract_CELL_ET m_extract_CELL_ET;
Extract_BD m_extract_BD;
Image_ReadChannel *pimage_ReadChannel;
private:
public:
vector<std::shared_ptr<Product_File_Info>> m_product_Camera_List; // 产品相机列表
};
#endif

@ -0,0 +1,177 @@
/*
* @Descripttion:
* @version:
* @Author: sueRimn
* @Date: 2022-03-16 17:09:11
* @LastEditors: sueRimn
* @LastEditTime: 2022-09-23 17:43:15
*/
#ifndef _SYSTEMCOMMONDEFIN1_HPP_
#define _SYSTEMCOMMONDEFIN1_HPP_
#include <string>
// working:”检测”, ready:”就绪”, check: “自检”, bad: “故障”, close: “关闭”
// 系统运行状态定义
enum SYSTEMRUNTYPE_
{
SYSTEM_RUN_TYPE_null,
SYSTEM_RUN_TYPE_working, // ”检测”
SYSTEM_RUN_TYPE_ready, // ”就绪”
SYSTEM_RUN_TYPE_check, // “自检”
SYSTEM_RUN_TYPE_bad, // “故障”
SYSTEM_RUN_TYPE_close, // “关闭”
SYSTEM_RUN_TYPE_count,
};
//
// 检测状态 离线检测 在线检测
enum CHECKIMGTRUNTYP_
{
CHECK_TYPE_ONLING, // 在线检测
CHECK_TYPE_OFFLING, // 离线检测
};
enum Check_Work_Type
{
Check_Work_NULL,
Check_Work_POL_ET,
Check_Work_CELL_ET,
Check_Work_FOG_ET,
Check_Work_COUNT,
};
static const std::string Check_Work_Name[] =
{
"NULL",
"POL_ET",
"CELL_ET",
"FOG_ET",
};
//------------------------config file define----------------------------------------
#define FILE_SYSTEM_RUN_CONFIG "../data/system_param.json"
#define FILE_THRESHOLDPARARM "/var/aidlux/efs/jdf/model/param.json"
#define FILE_CAM_ROI_PARARM "/var/aidlux/aid-cms/model/roi.json"
#define FILE_AIMODEL_FILE_PATH "/var/aidlux/aid-cms/model/config.json"
#define FILE_CONFIG_ROOR_PATH "/var/aidlux/aid-cms/model/"
#define FILE_AI_defect_BOE_MODEL_PATH "/home/aidlux/BOE/UseModel/defect.engine"
#define FILE_AI_classis_BOE_MODEL_PATH "/home/aidlux/BOE/UseModel/class.engine"
#define FILE_CHECKIMG_CONFIG "../DataConfig/check_Config.ini"
#define FILE_SAVEOKIMG_PATH "/home/aidlux/xwj/OKImg/"
// #define FILE_SAVEALLIMG_PATH "/home/aidlux/JBL/imageData/"
#define FILE_SAVEALLIMG_PATH "/ssd/SaveImg/"
#define FILE_SAVENGIMG_PATH "/ssd/NGImg/"
// #define MAX_NAM_LEN 64
// 字符长度
#define MAX_STR_LEN 128
// url长度
#define MAX_ULR_LEN 256
#define MAX_GPU_NUM 2
// ncnn 行人检测 跟踪 检测最大 线程个数
#define MAX_PERSONTRACKER_THREAD_NUM 4
// 共享内存检测最大 线程个数
#define MAX_SHARMEMORYCHECK_THREAD_NUM 2
// 行人+跌倒检测 算法 资源 起止
#define SHARMEMORYCHECK_THREAD_PERSON_IDX_START 0
#define SHARMEMORYCHECK_THREAD_PERSON_IDX_END 6
// 离岗行人 算法 资源 起止
#define SHARMEMORYCHECK_THREAD_Departure_PERSON_IDX_START 7
#define SHARMEMORYCHECK_THREAD_Departure_PERSON_IDX_END 7
// 属性检测 算法 资源 起止
#define SHARMEMORYCHECK_THREAD_ATTRIBUTE_IDX_START 9
#define SHARMEMORYCHECK_THREAD_ATTRIBUTE_IDX_END 9
#define USERSHAREKEY 476550
#define SHARED_MEM_LEN IMAGE_WIDTH *IMAGE_HEIGHT * 3
#define HTTP_SERVER_PATTERN_CAMCONFIG "/api/camera/param"
#define HTTP_SERVER_PATTERN_CAMCHECKROI "/api/camera/roi"
#define HTTP_SERVER_PATTERN_PARAM_ADD "/param/add"
#define HTTP_SERVER_PATTERN_PREVIEW "/preview"
#define HTTP_SERVER_PATTERN_SWITCH "/switch"
#define HTTP_SERVER_PATTERN_DETECT_OPEN_ALL "/api/detect/open/all"
#define HTTP_SERVER_PATTERN_PLC_STATE "/api/plc/state"
#define HTTP_SERVER_PATTERN_PLC_SET_STATE "/api/plc/set/state"
#define IMAGE_SIZE (2048 * 1792)
enum START_SYSTEM_STEP_
{
START_SYSTEM_STEP_LoadConfig,
START_SYSTEM_STEP_InitCheck,
START_SYSTEM_STEP_PreCheck,
START_SYSTEM_STEP_CamIO,
START_SYSTEM_STEP_Complete,
};
struct SystemConfigParam
{
std::string Analysis_Config_path;
std::string Analysis_Config_path_Cam2;
std::string Check_Config_path;
std::string channel_Config_path;
std::string preCheckImg_Path; // 预处理图片
int Use_CPU_StartIdx; // 使用 CPU的开始核
int preCHeck_YX; // 异显检测 1 用异显1模型 检测; 2用异显2模型 检测; 其他:不进行异显检测
int preCHeck_defect; // 缺陷检测模型1用wtb btw hb4 等进检测; 其他 用模型进行检测
SystemConfigParam()
{
Use_CPU_StartIdx = 0;
preCheckImg_Path = "../data/t1.tif";
preCHeck_YX = 0;
preCHeck_defect = 0;
channel_Config_path = "";
}
bool valid()
{
if (Analysis_Config_path.size() &&
Check_Config_path.size() &&
preCheckImg_Path.size() &&
Use_CPU_StartIdx >= 0)
{
return true;
}
return false;
}
};
enum THREAD_CPU_
{
THREAD_CPU_Main_Det,
THREAD_CPU_Main_readImg,
THREAD_CPU_Main_saveImg,
THREAD_CPU_CheckSo,
THREAD_CPU_Count,
};
struct CPU_ID_INFO_
{
int startIdx;
int num;
CPU_ID_INFO_()
{
startIdx = 0;
num = 0;
}
void set(int sidx, int num)
{
this->startIdx = sidx;
this->num = num;
}
};
#endif //_CORELOGICFACTORY_HPP_

File diff suppressed because it is too large Load Diff

@ -0,0 +1,704 @@
#ifndef _deal_HPP_
#define _deal_HPP_
#include <map>
#include <iostream>
#include <string>
#include <string.h>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <mutex>
#include <unistd.h>
#include "ImgBasicDeal.h"
#include "SystemCommonDefine.h"
#include "ImgCheckBase.h"
#include "ImgCheckConfig.h"
#include "ImgBasicDeal.h"
#include "ConfigBase.h"
#include <mutex>
#include <condition_variable>
#include <string>
#include "Image_ReadAndChange.h"
#include <filesystem>
#include "Read_Image.h"
namespace fs = std::filesystem;
enum Thread_Status_
{
Thread_Status_IDE,
Thread_Status_READY,
Thread_Status_BUSY,
Thread_Status_COMMPLET,
};
enum Thread_ReadImg_Status_
{
ReadImg_Status_IDE,
ReadImg_Status_Read,
ReadImg_Status_COMMPLET,
};
// 各种线程处理状态信息
enum DET_Status_Type_
{
Status_Type_ReadAndDet, // 读取图和处理
Status_Type_PullPath, // 读取图片路径
Status_Type_Count,
};
enum Mutex_Type_
{
Mutex_Type_ReadImgThread, // 读图线程
Mutex_Type_DetStatus,
Mutex_Type_DetResult,
Mutex_Type_Count,
};
// 读线程,处理类型。
enum READ_THREAD_TYPE_
{
READ_THREAD_TYPE_NULL,
READ_THREAD_TYPE_READIMG, // 读图
READ_THREAD_Detect, // 检测模式
READ_THREAD_TYPE_COUNT,
};
// 线程运行模式
enum THREAD_RUN_TYPE
{
THREAD_RUN_Only_ReadImg, // 仅读图
THREAD_RUN_ALL, // 所有
};
#define READ_IMG_THREAD_NUM 12
#define Save_IMG_THREAD_NUM 5
using namespace std;
enum RUNTYPE_
{
RUNTYPE_RUN_Pre_BigImg,
RUNTYPE_RUN_Pre_BigImg_Cam2,
RUNTYPE_RUN_File_BigImg,
RUNTYPE_RUN_File_CEEL_ET,
RUNTYPE_RUN_File_BigImg_WHJC_Date,
RUNTYPE_RUN_File_BigImg_WHJC_EDGE_TEST,
RUNTYPE_RUN_File_BigImg_WHJC_EDGE_AI_TEST,
RUNTYPE_RUN_Ong_BigImg_WHJC_EDGE_TEST,
RUNTYPE_RUN_File_BigImg_WHJC_ZF_TEST,
RUNTYPE_RUN_File_MarkLine_Test,
RUNTYPE_RUN_Align,
};
struct JC_IMAGE_INFO_
{
enum Status_
{
STATUS_Image_IDE,
STATUS_Image_READ,
STATUS_Image_COMMPLET,
STATUS_Det_Start,
};
std::string strProductID; // 产品ID
std::string strCamID; // 相机名称
std::string strchannelName; // 通道名称
std::string strPath; // 完整路径
std::string strName; // 图片名称
cv::Mat img; // 图像数据
Status_ status; // 状态
long readImg_start; // 读取开始时间
long readImg_end; // 读取结束时间
// 构造函数,调用 Init 初始化
JC_IMAGE_INFO_()
{
Init();
}
// 初始化函数,重置所有成员变量
void Init()
{
strProductID = "";
strCamID = "";
strchannelName = "";
strPath = "";
strName = "";
img.release(); // 释放图像内存
status = STATUS_Image_IDE;
readImg_start = 0;
readImg_end = 0;
}
// 拷贝函数,将传入的结构体内容复制到当前对象
void copy(JC_IMAGE_INFO_ tem)
{
this->strProductID = tem.strProductID;
this->strCamID = tem.strCamID;
this->strchannelName = tem.strchannelName;
this->strPath = tem.strPath;
this->strName = tem.strName;
if (!tem.img.empty())
{
this->img = tem.img.clone(); // 深拷贝图像数据
}
this->status = tem.status;
this->readImg_start = tem.readImg_start;
this->readImg_end = tem.readImg_end;
}
// 打印信息函数(可选)
void print()
{
std::cout << "Product ID: " << strProductID << std::endl;
std::cout << "Camera ID: " << strCamID << std::endl;
std::cout << "Channel Name: " << strchannelName << std::endl;
std::cout << "Image Path: " << strPath << std::endl;
std::cout << "Image Name: " << strName << std::endl;
std::cout << "Status: " << status << std::endl;
std::cout << "Read Start Time: " << readImg_start << std::endl;
std::cout << "Read End Time: " << readImg_end << std::endl;
}
};
struct Det_single_img_Result_Info
{
int result;
std::string name;
std::string qx_name;
Det_single_img_Result_Info()
{
Init();
}
void Init()
{
name = "";
result = 0;
qx_name = "NO";
}
};
struct Det_One_Result_Info
{
int result;
long time_s;
long time_e;
std::string Product_ID;
std::vector<Det_single_img_Result_Info> img_result_list;
Det_One_Result_Info()
{
Init();
}
void Init()
{
Product_ID = "";
time_s = 0;
time_e = 0;
result = 0;
img_result_list.erase(img_result_list.begin(), img_result_list.end());
img_result_list.clear();
}
std::string print()
{
std::string str = "";
// printf("%s:result %d | ", Product_ID.c_str(), result);
char buffer[64];
sprintf(buffer, "%s:result %d time %ld | ", Product_ID.c_str(), result, time_e - time_s);
std::string st1 = buffer;
str += st1;
for (size_t i = 0; i < img_result_list.size(); i++)
{
str += img_result_list.at(i).name + " " + img_result_list.at(i).qx_name + " | ";
}
// str += str;
return str;
// printf("%s\n", str.c_str());
}
};
struct Det_File_qx_Info
{
std::string qx_name;
int num;
Det_File_qx_Info()
{
Init();
}
void Init()
{
qx_name = "";
num = 0;
}
};
// 套图检测 统计结果信息
struct Det_File_Result_Info
{
int det_num_all;
int det_num_ok;
int det_num_ng;
int det_num_error;
float sumtime_S;
long startTime_S;
float mean_time;
std::vector<Det_One_Result_Info> one_result_list;
std::vector<std::string> strlist;
std::vector<Det_File_qx_Info> qx_result_list;
Det_File_Result_Info()
{
Init();
}
void Init()
{
det_num_all = 0;
det_num_ok = 0;
det_num_ng = 0;
det_num_error = 0;
sumtime_S = 0;
startTime_S = 0;
mean_time = 0;
one_result_list.erase(one_result_list.begin(), one_result_list.end());
one_result_list.clear();
strlist.erase(strlist.begin(), strlist.end());
strlist.clear();
qx_result_list.erase(qx_result_list.begin(), qx_result_list.end());
qx_result_list.clear();
}
void updata(std::string productid, std::string imgname, int nresult, long t)
{
sumtime_S = t - startTime_S;
sumtime_S /= 1000;
if (det_num_all > 0)
{
mean_time = sumtime_S / det_num_all;
}
for (int i = 0; i < one_result_list.size(); i++)
{
if (one_result_list.at(i).Product_ID == productid)
{
// if (one_result_list.at(i).result < 0)
// {
// one_result_list.at(i).result = 0;
// }
one_result_list.at(i).time_e = t;
for (size_t j = 0; j < one_result_list.at(i).img_result_list.size(); j++)
{
if (one_result_list.at(i).img_result_list.at(j).name == imgname)
{
one_result_list.at(i).img_result_list.at(j).result = nresult;
if (nresult == 0)
{
one_result_list.at(i).img_result_list.at(j).qx_name = "OK";
}
else if (nresult > 0)
{
one_result_list.at(i).img_result_list.at(j).qx_name = "NG";
if (one_result_list.at(i).result == 0)
{
one_result_list.at(i).result = 1;
}
}
else
{
one_result_list.at(i).img_result_list.at(j).qx_name = "ER";
one_result_list.at(i).result = -1;
}
}
}
}
}
}
void update_qx(std::string qx_name, int num)
{
for (int i = 0; i < qx_result_list.size(); i++)
{
if (qx_result_list.at(i).qx_name == qx_name)
{
qx_result_list.at(i).num += num;
return;
}
}
Det_File_qx_Info tem;
tem.qx_name = qx_name;
tem.num = num;
qx_result_list.push_back(tem);
}
void print(bool show = true)
{
strlist.erase(strlist.begin(), strlist.end());
strlist.clear();
det_num_ok = 0;
det_num_ng = 0;
det_num_error = 0;
std::string str = "";
str = "*****************************************************************************";
strlist.push_back(str);
str = "*****************************detect result***********************************";
strlist.push_back(str);
float fok = 0;
float fng = 0;
float ferror = 0;
// printf("one_result_list.size() %d \n", one_result_list.size());
for (int i = 0; i < one_result_list.size(); i++)
{
if (one_result_list.at(i).result == 0)
{
det_num_ok++;
}
else if (one_result_list.at(i).result > 0)
{
det_num_ng++;
}
else
{
det_num_error++;
}
}
if (det_num_all > 0)
{
fok = det_num_ok * 1.0f / det_num_all * 100;
fng = det_num_ng * 1.0f / det_num_all * 100;
ferror = det_num_error * 1.0f / det_num_all * 100;
}
char buffer[64];
sprintf(buffer, "ALL:%d OK:%d %.1f%% NG:%d %.1f%% Error:%d %.1f%%", det_num_all, det_num_ok, fok, det_num_ng, fng, det_num_error, ferror);
std::string st1 = buffer;
strlist.push_back(st1);
sprintf(buffer, "Use time %f s mean time %f s", sumtime_S, mean_time);
std::string st2 = buffer;
strlist.push_back(st2);
// printf("%s\n", st1.c_str());
// printf("------------------------------------------------------------------------------\n");
str = "------------------------------------------------------------------------------";
strlist.push_back(str);
{
int qx_all_num = 0;
for (size_t i = 0; i < qx_result_list.size(); i++)
{
qx_all_num += qx_result_list.at(i).num;
}
for (size_t i = 0; i < qx_result_list.size(); i++)
{
float fr = qx_result_list.at(i).num * 1.0 / qx_all_num * 100;
std::string str_qx = "";
// printf("len %d \n", qx_result_list.at(i).qx_name.length());
for (int k = 0; k < (20 - qx_result_list.at(i).qx_name.length()); k++)
{
str_qx += " ";
}
str_qx += qx_result_list.at(i).qx_name;
char buffer123[64];
sprintf(buffer123, ":%d %.1f%% ", qx_result_list.at(i).num, fr);
std::string st1 = buffer123;
str_qx += st1;
int nlen = fr;
for (int j = 0; j < nlen; j++)
{
str_qx += "|";
}
strlist.push_back(str_qx);
}
}
str = "------------------------------------------------------------------------------";
strlist.push_back(str);
for (int i = 0; i < one_result_list.size(); i++)
{
st1 = one_result_list.at(i).print();
strlist.push_back(st1);
}
str = "*****************************************************************************";
strlist.push_back(str);
// printf("*****************************************************************************\n");
if (show)
{
for (size_t i = 0; i < strlist.size(); i++)
{
printf("%s\n", strlist.at(i).c_str());
}
}
}
};
struct IMG_BASE_INFO_
{
std::string strPath;
std::string strChannel;
std::string strImgSN;
IMG_BASE_INFO_()
{
strPath = "";
strImgSN = "";
strChannel = "";
}
};
struct ReadImgInfo
{
std::string strPath;
std::string strChannel;
int stype;
int status;
std::string strImgSN;
int idx;
int sumNUm;
cv::Rect cutRoi;
std::vector<IMG_BASE_INFO_> imglist;
ReadImgInfo()
{
strPath = "";
strImgSN = "";
stype = 0;
status = 0;
idx = 0;
imglist.clear();
cutRoi = cv::Rect(0, 0, 0, 0);
sumNUm = 0;
}
};
struct AI_Det_Path
{
std::string strPath_CutImg;
std::string strPath_AIMask;
/* data */
};
struct AI_Det_Channel_
{
std::string strChannel;
AI_Det_Path path;
/* data */
};
struct Json_Det_Path
{
std::string strPath_CutImg;
std::string strPath_Json;
/* data */
};
struct READ_IMG_INFO
{
std::string strpath= "";
std::string strproduct = "";
};
class deal
{
public:
// 构造函数
deal();
~deal();
int start();
private:
// 检测参数
int LoadCheckImgConfig();
// 初始化检测分析线程类
int InitCheckAnalysisy();
int InitConfig();
// 初始化 检查存图路径
int InitSaveImgPath();
int LoadCheckConfig();
// 分析参数
int LoadAnalysisConfig();
// 开启线程
int StartThread(THREAD_RUN_TYPE type);
// 停止线程
int StopThread();
int preCheck();
std::string readTestImg();
int readTestImg(READ_IMG_INFO& read);
// 重复检测
int repeatCheck();
int saveImg(std::string strpath, std::shared_ptr<CheckResult> result);
int writeLog(std::string strSavePath, std::vector<std::string> logList);
int WriteJsonString(std::string strSavePath, std::string strjson);
int DelImg_Cell_ET();
int Det_OneProduct_Cell_ET(std::shared_ptr<Product_File_Info> product, int Idx);
// 获取图片路径
int GetDetImageInfo(std::string strProductID, std::string strSearchImg, std::vector<JC_IMAGE_INFO_> &jcImageInfoList);
// 解析图片的信息 -- cell et
int GetImgInfo_POL_ET(std::string strImgPath, JC_IMAGE_INFO_ *pImageInfo);
int GetImgInfo_POL_ET_PNG(std::string strImgPath, JC_IMAGE_INFO_ *pImageInfo);
int Det_Edge_Test_OneImg();
// 功能测试
int Det_Funtion_Test();
// 边缘测试
int Det_Funtion_Edge();
// 测试mark线
int Det_Funtion_MarkLine();
int LoadSingleImgList(std::string strSearchPath, std::string strChannle, std::vector<std::string> &imgList);
// 随机绘制错误
int RandDrawImg(cv::Mat srcimg, cv::Mat &randErrorImg);
int LoadOfflineCheckImg(std::string strImgPath);
int LoadImgPath_JCSN(std::string strImgPath);
bool isValidString(const std::string &str);
int LoadProductID(std::string strImgPath);
int set_cpu_id(const std::vector<int> &cpu_set_vec);
void GetDealResultToQueu();
// 加载系统配置文件
bool ReadSystemConfig(const std::string &strPath);
int GetJcImageInfo(std::string strpath, std::vector<JC_IMAGE_INFO_> &jcImageInfoList);
int ReadTestImgaData();
// 处理前,初始化部分数据
int InitDetData();
// 检测结果 插入结果队列
int InsertDetResult(ReadImgInfo tem);
int GetUpMaskImg(cv::Mat inImg, cv::Rect roi, cv::Mat &maskimg);
// 送图去检测
int SendImgToCheck(std::shared_ptr<JC_IMAGE_INFO_> pDetImageInfo, IN_IMG_Status_ status);
private:
// 处理调度线程
std::shared_ptr<std::thread> ptr_DealImgthread;
void DealImg();
std::vector<std::string> extractAllDirectories(const std::string &path);
// 结果处理线程
// std::shared_ptr<std::thread> ptr_Resultthread;
std::vector<std::shared_ptr<std::thread>> ptr_ResultthreadList;
void ResultThread(int id);
// 结果拷贝线程
std::shared_ptr<std::thread> ptr_GetResultthread;
void GetResultThread();
std::vector<std::shared_ptr<std::thread>> threadArray;
void ReadImgThread(int id);
void testimg(cv::Mat img);
int updataResltInfo(std::shared_ptr<CheckResult> result);
void slidingWindowAutoThreshold(const cv::Mat &src, cv::Mat &dst, int windowSize, int step, double C);
int testimgUP(cv::Mat img);
int test_ZF(ReadImgInfo tem, int id);
int SetStatus(int type, int status);
int GetStatus(int type);
bool IsStatus(int type, int status);
int SetStatus_List(int idx, Thread_Status_ status);
int GetStatus_List(int idx);
bool IsStatus_List(int idx, Thread_Status_ status);
int setReadThreadStart();
int GetReadImgCompleteThreadIdx(); // 获取读取完成后的idx
bool IsALLComplete();
int InitCPUIDX();
// 线程读图
void Thread_ReadImg(int id);
int InsertReadImgInfo(std::shared_ptr<JC_IMAGE_INFO_> pImageInfo);
int GetReadImgInfo(std::shared_ptr<JC_IMAGE_INFO_> &pImageInfo);
public:
std::vector<cv::Mat> m_OffLineCheckImgList; // 离线检测图片列表
std::vector<std::string> m_OffLineCheckImgNameList; // 离线检测图片列表
std::vector<std::string> m_OffImageSNPathList; // 离线检测图片列表
// std::vector<std::string> m_product_ID_List; // 离线检测图片列表
vector<std::shared_ptr<Product_File_Info>> m_product_Camera_List; // 产品相机列表
ALLImgCheckBase *m_pALLImgCheckAnalysisy;
// ALLImgCheckBase *m_pResultJsonCheckAnalysisy;
// ImgCheckAnalysisy m_ImgCheckAnalysisy[IMGCHECKANALYSISY_NUM];
std::vector<std::string> m_TestJC_ImageDate; // 离线检测图片列表
std::string m_strCurDate;
int m_nSystemCheckType;
bool m_bExit;
int nLastCheckAnalysisyThreadIdx;
RunInfoST m_RunConfig; // 检测基本参数
ImgBasicDeal m_imgBasicDeal;
std::mutex mutex_Result_list;
std::queue<std::shared_ptr<CheckResult>> m_Result_list;
// 检测区域list
std::vector<cv::Point> m_DetRoiMaskPointList;
// 检测区域list
std::vector<cv::Point> m_CoreMaskPointList;
int m_nTestAI;
int m_nRunType;
int m_nTestNum;
std::string m_strCheckFilePath;
std::string m_strSaveImgPath;
ConfigBase *m_pConfig;
ConfigBase *m_pConfig_Cam2;
SystemConfigParam m_system_param;
int m_nCurUseCPUIDX;
int m_nCamIdx;
ImageInfo m_ImgInfo_src;
ImageInfo m_ImgInfo_result;
int m_nSaveDetprocessImg;
cv::Rect m_CutRoi;
int nn;
int nddd;
int kkd;
int maxidx;
Det_File_Result_Info m_DetResult;
std::vector<JC_IMAGE_INFO_> m_ImageInfoList;
std::queue<std::shared_ptr<JC_IMAGE_INFO_>> m_ReadImg_queue; // 读图队列
std::mutex mutex_ReadImgList;
std::condition_variable cv_ReadImgList;
int m_nReadStausList[READ_IMG_THREAD_NUM];
// 读图线程状态
std::shared_ptr<JC_IMAGE_INFO_> m_ReadImgThread_Result[READ_IMG_THREAD_NUM];
READ_THREAD_TYPE_ m_nReadThread_type;
bool m_nreadImg_Stop;
std::mutex mutex_DetResult_;
std::queue<ReadImgInfo> m_DetImgQueue; // 存储生产者生产的数据
std::mutex mtx_DetImgQueue; // 互斥量,保护共享资源
std::mutex mtx_DetImgQueue_edge; // 互斥量,保护共享资源
std::condition_variable cv; // 条件变量,用于线程间通信
std::mutex mtx_DetImgQueue_com; //
int m_read_ImgNum;
long m_readImgStarttime;
int m_DetStatusList[Status_Type_Count]; // 各种需要线程同步的状态信息
std::mutex mtx_List[Mutex_Type_Count]; // 互斥量
std::vector<ReadImgInfo> m_DetResultList;
CPU_ID_INFO_ m_CPUInfo[THREAD_CPU_Count];
Check_Work_Type m_check_Work_Type; // 系统运行模式
Image_ReadChannel m_image_ReadChannel;
};
#endif //_CORELOGICFACTORY_HPP_

@ -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

File diff suppressed because it is too large Load Diff

@ -0,0 +1,357 @@
#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 "Read_Image.h"
void handler(int sig)
{
printf("Get handler sig");
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 redimg_16()
{
std::string strImgPath = "/home/aidlux/BOE_CELL_ET/Image/20250718/left/__DB__6LQR560030C6BBA/*.tif";
// std::cout << strImgPath << std::endl;
std::vector<cv::String> img_paths;
cv::glob(strImgPath, img_paths, true);
for (int i = 0; i < img_paths.size(); i++)
{
std::string filename = img_paths[i];
std::cout << filename << std::endl;
size_t pos1 = filename.find('^');
size_t pos2 = filename.rfind(".tif"); // 或 ".tif" 的起始位置
std::string result;
if (pos1 != std::string::npos && pos2 != std::string::npos && pos2 > pos1)
{
result = filename.substr(pos1 + 1, pos2 - pos1 - 1);
std::cout << "提取的内容: " << result << std::endl;
}
else
{
std::cerr << "格式不匹配,无法提取" << std::endl;
}
cv::Mat img16 = cv::imread(filename, cv::IMREAD_UNCHANGED);
if (img16.empty())
{
std::cerr << "无法读取图像: " << filename << std::endl;
return -1;
}
cv::Mat img8;
if (img16.type() == CV_16U)
{
cv::normalize(img16, img8, 0, 255, cv::NORM_MINMAX);
img8.convertTo(img8, CV_8U);
}
else if (img16.type() == CV_8U)
{
img8 = img16;
}
else
{
std::cerr << "图像不是 16 / 8位灰度图type = " << img16.type() << std::endl;
continue;
}
std::cout << "读取成功: " << img16.cols << " x " << img16.rows << ",类型: CV_16U" << std::endl;
// 方式一线性映射缩放到0~255
// double minVal, maxVal;
// cv::minMaxLoc(img16, &minVal, &maxVal);
// std::cout << "图像值范围: [" << minVal << ", " << maxVal << "]" << std::endl;
// cv::Mat img8;
// img16.convertTo(img8, CV_8U, 255.0 / (maxVal - minVal), -minVal * 255.0 / (maxVal - minVal));
// 方式二(如果你知道最大值就是 65535也可以直接缩放
// img16.convertTo(img8, CV_8U, 1.0 / 256.0); // 65536 -> 256 缩放
// 保存或显示结果
cv::imwrite(result + "o11utput_8bit_gray.png", img8);
}
getchar();
std::string filename = "/home/aidlux/BOE_CELL_ET/Image/20250718/left/__DB__6LQR560030C6BBA/6LQR560030C6BBA^L127.tif";
// 使用 IMREAD_UNCHANGED 保留原始位深
cv::Mat img16 = cv::imread(filename, cv::IMREAD_UNCHANGED);
if (img16.empty())
{
std::cerr << "无法读取图像: " << filename << std::endl;
return -1;
}
// 检查是否是 16 位灰度图
if (img16.type() != CV_16U)
{
std::cerr << "图像不是 16 位灰度图type = " << img16.type() << std::endl;
return -1;
}
std::cout << "读取成功: " << img16.cols << " x " << img16.rows << ",类型: CV_16U" << std::endl;
// 方式一线性映射缩放到0~255
double minVal, maxVal;
cv::minMaxLoc(img16, &minVal, &maxVal);
std::cout << "图像值范围: [" << minVal << ", " << maxVal << "]" << std::endl;
cv::Mat img8;
img16.convertTo(img8, CV_8U, 255.0 / (maxVal - minVal), -minVal * 255.0 / (maxVal - minVal));
// 方式二(如果你知道最大值就是 65535也可以直接缩放
// img16.convertTo(img8, CV_8U, 1.0 / 256.0); // 65536 -> 256 缩放
// 保存或显示结果
cv::imwrite("output_8bit_gray.png", img8);
// cv::imshow("8-bit Gray", img8);
// cv::waitKey(0);
return 0;
}
int main(int argc, char *argv[])
{
std::cout << "CHECK_WORK: " << CHECK_WORK << std::endl;
deal test;
for (int i = 0; i < Check_Work_COUNT; i++)
{
if (CHECK_WORK == Check_Work_Name[i])
{
test.m_check_Work_Type = static_cast<Check_Work_Type>(i);
break;
}
}
if (test.m_check_Work_Type == Check_Work_NULL)
{
cout << "***********************work type Error *******************************" << endl;
return 0;
}
if (argc > 1 && string(argv[1]) == "-h")
{
cout << "******************************************************" << endl;
cout << "*** 1、./test_JBL_Check: 默认处理一套图 图片文件夹位于 ../data/img/t1结果位于/home/aidlux/BOE/testresult" << endl;
cout << "*** 2、./test_JBL_Check -s: 1 的基础上增加 过程存图包括edge 和字符检测的中间结果存图,图片位于 当前文件夹。" << endl;
cout << "*** 3、./test_JBL_Check -fjc filepath: 处理精测套图大图 结果位于/home/aidlux/BOE/ResultImg" << endl;
cout << "*** 4、./test_JBL_Check -feai filepath num: 批量测试边缘检测算法num 至多处理张数,结果:/home/aidlux/BOE/Edge" << endl;
cout << "*** 5、./test_JBL_Check -falign filepath num : 批量测试定位算法num 至多处理张数,结果:/home/aidlux/BOE/Align" << endl;
cout << "*** 6、./test_JBL_Check -rjson filepath: 单张复测filepath xx/xx/3A3K380001B1DK_20240408_152157_Main_0_2_L255" << endl;
cout << "*** 6、./test_JBL_Check -rjsonall filepath: 一套图复测filepath xx/xx/" << endl;
cout << "******************************************************" << endl;
return 0;
}
// redimg_16();
// Read_Image dfe;
// dfe.Read_Image_List("../data/img/pre");
// //dfe.Read_Image_List("/home/aidlux/BD_AOI/Data/SmallImage/60HW");
// getchar();
printf("argc = %d\n", argc);
for (int i = 0; i < argc; i++)
{
printf("argv[%d]=%s\n", i, argv[i]);
}
test.m_nRunType = RUNTYPE_RUN_Pre_BigImg; // 大图
test.m_strCheckFilePath = "";
if (argc > 1 && string(argv[1]) != "-h")
{
{
if (string(argv[1]) == "-f") // 遍历检查武汉精测图片
{
test.m_nRunType = RUNTYPE_RUN_File_BigImg; // 大图
if (argc == 3)
{
test.m_strCheckFilePath = string(argv[2]);
}
else
{
cout << "参数错误 ------- " << endl;
return 0;
}
}
else if (string(argv[1]) == "-fai") // 遍历检查武汉精测图片
{
test.m_nRunType = RUNTYPE_RUN_File_BigImg; // 大图
test.m_nTestAI = 1;
if (argc == 3)
{
test.m_strCheckFilePath = string(argv[2]);
}
else
{
cout << "参数错误 ------- " << endl;
return 0;
}
}
else if (string(argv[1]) == "-fc2")
{
test.m_nRunType = RUNTYPE_RUN_Pre_BigImg_Cam2; //
if (argc == 3)
{
if (string(argv[1]) == "-s")
{
test.m_nSaveDetprocessImg = 1;
}
}
}
else if (string(argv[1]) == "-fmark")
{
test.m_nRunType = RUNTYPE_RUN_File_MarkLine_Test; //
if (argc == 3)
{
test.m_strCheckFilePath = string(argv[2]);
test.m_nTestNum == 9999999;
}
else
{
cout << "参数错误 ------- " << endl;
return 0;
}
}
else if (string(argv[1]) == "-fe")
{
test.m_nRunType = RUNTYPE_RUN_File_BigImg_WHJC_EDGE_TEST; //
if (argc == 3)
{
test.m_strCheckFilePath = string(argv[2]);
test.m_nTestNum == 9999999;
}
else
{
cout << "参数错误 ------- " << endl;
return 0;
}
}
else if (string(argv[1]) == "-fcell")
{
test.m_nRunType = RUNTYPE_RUN_File_CEEL_ET; //
if (argc == 3)
{
test.m_strCheckFilePath = string(argv[2]);
}
else
{
cout << "参数错误 ------- " << endl;
return 0;
}
}
else if (string(argv[1]) == "-feai")
{
test.m_nRunType = RUNTYPE_RUN_File_BigImg_WHJC_EDGE_AI_TEST; //
if (argc == 3)
{
test.m_strCheckFilePath = string(argv[2]);
test.m_nTestNum == 9999999;
}
else if (argc == 4)
{
test.m_strCheckFilePath = string(argv[2]);
std::string strnum = string(argv[3]);
test.m_nTestNum = atoi(strnum.c_str());
}
else
{
cout << "参数错误 ------- " << endl;
return 0;
}
}
else
{
if (string(argv[1]) == "-s")
{
test.m_nSaveDetprocessImg = 1;
}
else
{
cout << "参数错误 ------- " << endl;
return 0;
}
}
}
}
for (int i = 0; i < argc; ++i)
{
std::cout << "Argument #" << i << ": " << argv[i] << std::endl;
}
printf("m_nRunType %d m_nSaveDetprocessImg %d path %s\n", test.m_nRunType, test.m_nSaveDetprocessImg, test.m_strCheckFilePath.c_str());
// getchar();
signal(SIGINT, handler);
test.start();
while (true)
{
usleep(10 * 1000);
}
return 0;
}

@ -0,0 +1,216 @@
/*
* @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 AICheck_H_
#define AICheck_H_
// #define USE_TERNSORRT10_BIGMODEL
#define CUDA_API_PER_THREAD_DEFAULT_STREAM 1
#include <vector>
#include <thread>
#include <mutex>
#ifdef USE_TERNSORRT10_BIGMODEL
#include "NvInfer.h"
#include "cuda_runtime_api.h"
using namespace nvinfer1;
#else
#include "argsParser.h"
#include "buffers.h"
#include "common.h"
#include "logger.h"
#include "NvCaffeParser.h"
#include "NvInfer.h"
#include "cuda_runtime_api.h"
#endif
using namespace std;
#define MAX_AI_BUFFER_SIZE 5
enum AIBufferType_
{
AIBufferType_NULL, // default
AIBufferType_IN, // 输入
AIBufferType_OUT, // 输出
};
struct AIBuffer
{
int ntype; // 数据类型 AIBufferType_
int ndatalength; // 数据长度
int ndataSize; // 数据字节大小 ndatalength*sizeof(float)
int nuchardataSize; // 数据字节大小 ndatalength*sizeof(char)
std::string strName; // 名称
AIBuffer()
{
ntype = AIBufferType_NULL;
ndatalength = 0;
ndataSize = 0;
nuchardataSize = 0;
strName = "";
}
void copy(AIBuffer tem)
{
this->ntype = tem.ntype;
this->ndatalength = tem.ndatalength;
this->ndataSize = tem.ndataSize;
this->nuchardataSize = tem.nuchardataSize;
this->strName = tem.strName;
}
void print(std::string str = "")
{
printf("ntype %d strName %s ndatalength %d ndataSize %d nuchardataSize %d\n", ntype, strName.c_str(), ndatalength, ndataSize, nuchardataSize);
}
};
struct AIInitConfig
{
int nGpuIdx;
AIBuffer bufferList[MAX_AI_BUFFER_SIZE];
std::string engine_file_path;
AIInitConfig()
{
nGpuIdx = -1;
engine_file_path = "";
}
void copy(AIInitConfig tem)
{
this->nGpuIdx = tem.nGpuIdx;
this->engine_file_path = tem.engine_file_path;
for (int i = 0; i < MAX_AI_BUFFER_SIZE; i++)
{
this->bufferList[i].copy(tem.bufferList[i]);
}
}
bool Checking()
{
if (nGpuIdx < 0 || nGpuIdx > 4)
{
return false;
}
if (engine_file_path.empty())
{
return false;
}
// 第一个不是 输入
if (bufferList[0].ntype != AIBufferType_IN)
{
return false;
}
// 第二个是 空
if (bufferList[1].ntype == AIBufferType_NULL)
{
return false;
}
bool bhaveout = false;
int npretype = AIBufferType_IN;
for (int i = 1; i < MAX_AI_BUFFER_SIZE; i++)
{
// 前序是in
if (npretype == AIBufferType_IN)
{
if (bufferList[i].ntype == AIBufferType_IN)
{
continue;
}
else if (bufferList[i].ntype == AIBufferType_OUT)
{
npretype = AIBufferType_OUT;
bhaveout = true;
}
else
{
return false;
}
}
else if (npretype == AIBufferType_OUT)
{
if (bufferList[i].ntype == AIBufferType_IN)
{
return false;
}
else if (bufferList[i].ntype == AIBufferType_OUT)
{
continue;
}
else
{
npretype = AIBufferType_NULL;
}
}
else
{
if (bufferList[i].ntype == AIBufferType_IN)
{
return false;
}
else if (bufferList[i].ntype == AIBufferType_OUT)
{
return false;
}
else
{
npretype = AIBufferType_NULL;
}
}
}
if (!bhaveout)
{
return false;
}
return true;
}
void CalSize(int mulSzie)
{
for (int i = 0; i < MAX_AI_BUFFER_SIZE; i++)
{
if (bufferList[i].ntype == AIBufferType_NULL)
{
continue;
}
bufferList[i].ndataSize = bufferList[i].ndatalength * mulSzie;
bufferList[i].nuchardataSize = bufferList[i].ndatalength * sizeof(unsigned char);
}
}
};
class AI_defect
{
public:
AI_defect();
~AI_defect();
int model_init(AIInitConfig config);
int model_Cuda_AI_In_1_Out_1(unsigned char *p_indata_0, unsigned char *p_outdata_1);
int model_Cuda_AI_In_1_Out_1_float(unsigned char *p_indata_0, float *p_outdata_1);
private:
void destroy();
private:
IRuntime *runtime;
ICudaEngine *engine;
IExecutionContext *context;
void *buffers[MAX_AI_BUFFER_SIZE];
void *ImgData[MAX_AI_BUFFER_SIZE]; // uchar
const int BATCH_SIZE = 1;
bool m_bInitialized;
std::mutex g_mutex;
AIInitConfig m_config;
float* floatData[MAX_AI_BUFFER_SIZE];
int kk = 0;
};
#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);
private:
cv::Rect GetCutRoi(cv::Rect roi, const cv::Mat &img);
// 获取检测roi list
private:
};
#endif

@ -0,0 +1,231 @@
/*
* @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 AICommonDefine_H_
#define AICommonDefine_H_
// nf 输入图片尺寸
#define AI_NF_IN_0_IMAGE_WIDTH 1024
#define AI_NF_IN_0_IMAGE_HEIGHT 1024
#define AI_NF_IN_0_IMAGE_CHANNEL 1
#define AI_NF_IN_0_DATA_LENGTH AI_NF_IN_0_IMAGE_WIDTH *AI_NF_IN_0_IMAGE_HEIGHT *AI_NF_IN_0_IMAGE_CHANNEL
#define AI_NF_IN_0_IMAGE_Name "0"
// nf 输入图片尺寸
#define AI_NF_out_0_IMAGE_WIDTH 512
#define AI_NF_out_0_IMAGE_HEIGHT 512
#define AI_NF_out_0_IMAGE_CHANNEL 1
#define AI_NF_out_0_DATA_LENGTH AI_NF_out_0_IMAGE_WIDTH *AI_NF_out_0_IMAGE_HEIGHT *AI_NF_out_0_IMAGE_CHANNEL
#define AI_NF_out_0_IMAGE_Name "491"
// nf 输入图片尺寸
#define AI_NF_out_1_IMAGE_WIDTH 512
#define AI_NF_out_1_IMAGE_HEIGHT 512
#define AI_NF_out_1_IMAGE_CHANNEL 1
#define AI_NF_out_1_DATA_LENGTH AI_NF_out_1_IMAGE_WIDTH *AI_NF_out_1_IMAGE_HEIGHT *AI_NF_out_1_IMAGE_CHANNEL
// YS 输入图片尺寸
#define AI_YX_IN_0_IMAGE_WIDTH 1024
#define AI_YX_IN_0_IMAGE_HEIGHT 640
#define AI_YX_IN_0_IMAGE_CHANNEL 1
#define AI_YX_IN_0_DATA_LENGTH AI_YX_IN_0_IMAGE_WIDTH *AI_YX_IN_0_IMAGE_HEIGHT *AI_YX_IN_0_IMAGE_CHANNEL
#define AI_YX_IN_0_IMAGE_Name "0"
// nf 输入图片尺寸
#define AI_YX_out_0_IMAGE_WIDTH 1024
#define AI_YX_out_0_IMAGE_HEIGHT 640
#define AI_YX_out_0_IMAGE_CHANNEL 1
#define AI_YX_out_0_DATA_LENGTH AI_YX_out_0_IMAGE_WIDTH *AI_YX_out_0_IMAGE_HEIGHT *AI_YX_out_0_IMAGE_CHANNEL
#define AI_YX_out_0_IMAGE_Name "480"
#define USE_WHITEBACK_CLASS 1
// 1023
#define AI_Cls_IN_0_IMAGE_WIDTH 160
#define AI_Cls_IN_0_IMAGE_HEIGHT 160
#define AICls_IN_0_IMAGE_CHANNEL 3
#define AI_Cls_IN_0_IMAGE_DATA_LENGTH AI_Cls_IN_0_IMAGE_WIDTH *AI_Cls_IN_0_IMAGE_HEIGHT *AICls_IN_0_IMAGE_CHANNEL
#define AI_Cls_IN_0_IMAGE_Name "0"
// #define AI_Cls_out_0_IMAGE_WIDTH 5 //5---9---20231118
// #define AI_Cls_out_0_IMAGE_WIDTH 9 //5---9---20231118
#define AI_Cls_out_0_IMAGE_WIDTH 16 // 9---10---20231126
#define AI_Cls_out_0_IMAGE_HEIGHT 1
#define AI_Cls_out_0_IMAGE_CHANNEL 1
#define AI_Cls_out_0_IMAGE_DATA_LENGTH AI_Cls_out_0_IMAGE_WIDTH *AI_Cls_out_0_IMAGE_HEIGHT *AI_Cls_out_0_IMAGE_CHANNEL
#define AI_Cls_out_0_IMAGE_Name "570"
#define AI_Cls_14_out_0_IMAGE_WIDTH 14 // 9---10---20231126
#define AI_Cls_14_out_0_IMAGE_HEIGHT 1
#define AI_Cls_14_out_0_IMAGE_CHANNEL 1
#define AI_Cls_14_out_0_IMAGE_DATA_LENGTH AI_Cls_14_out_0_IMAGE_WIDTH *AI_Cls_14_out_0_IMAGE_HEIGHT *AI_Cls_14_out_0_IMAGE_CHANNEL
#define AI_Cls_14_out_0_IMAGE_Name "570"
// 1023
// YS 输入图片尺寸
#define AI_ZF_IN_0_IMAGE_WIDTH 1280
#define AI_ZF_IN_0_IMAGE_HEIGHT 800
#define AI_ZF_IN_0_IMAGE_CHANNEL 1
#define AI_ZF_IN_0_DATA_LENGTH AI_ZF_IN_0_IMAGE_WIDTH *AI_ZF_IN_0_IMAGE_HEIGHT *AI_ZF_IN_0_IMAGE_CHANNEL
#define AI_ZF_IN_0_IMAGE_Name "0"
// nf 输入ZF片尺寸
#define AI_ZF_out_0_IMAGE_WIDTH 1280
#define AI_ZF_out_0_IMAGE_HEIGHT 800
#define AI_ZF_out_0_IMAGE_CHANNEL 1
#define AI_ZF_out_0_DATA_LENGTH AI_ZF_out_0_IMAGE_WIDTH *AI_ZF_out_0_IMAGE_HEIGHT *AI_ZF_out_0_IMAGE_CHANNEL
#define AI_ZF_out_0_IMAGE_Name "491"
#define str_AI_127Cell_Model_Path "/home/aidlux/BOE/UseModel/defect_L127.engine"
// 127Cell 输入图片尺寸
#define AI_127Cell_IN_0_IMAGE_WIDTH 1024
#define AI_127Cell_IN_0_IMAGE_HEIGHT 1024
#define AI_127Cell_IN_0_IMAGE_CHANNEL 1
#define AI_127Cell_IN_0_DATA_LENGTH AI_127Cell_IN_0_IMAGE_WIDTH *AI_127Cell_IN_0_IMAGE_HEIGHT *AI_127Cell_IN_0_IMAGE_CHANNEL
#define AI_127Cell_IN_0_IMAGE_Name "0"
// nf 输入图片尺寸
#define AI_127Cell_out_0_IMAGE_WIDTH 512
#define AI_127Cell_out_0_IMAGE_HEIGHT 512
#define AI_127Cell_out_0_IMAGE_CHANNEL 1
#define AI_127Cell_out_0_DATA_LENGTH AI_127Cell_out_0_IMAGE_WIDTH *AI_127Cell_out_0_IMAGE_HEIGHT *AI_127Cell_out_0_IMAGE_CHANNEL
#define AI_127Cell_out_0_IMAGE_Name "491"
#define str_AI_RE_POL_Model_Path "/home/aidlux/BOE/UseModel/BOE_POL_128x128.engine"
#define str_AI_RE_AD_Model_Path "/home/aidlux/BOE/UseModel/BOE_AD_128x128.engine"
// POL 二次计算面积 输入图片尺寸
#define str_AI_RE_POL_IN_0_IMAGE_WIDTH 128
#define str_AI_RE_POL_IN_0_IMAGE_HEIGHT 128
#define str_AI_RE_POL_IN_0_IMAGE_CHANNEL 1
#define str_AI_RE_POL_IN_0_DATA_LENGTH str_AI_RE_POL_IN_0_IMAGE_WIDTH *str_AI_RE_POL_IN_0_IMAGE_HEIGHT *str_AI_RE_POL_IN_0_IMAGE_CHANNEL
#define str_AI_RE_POL_IN_0_IMAGE_Name "0"
// nf 输入图片尺寸
#define str_AI_RE_POL_out_0_IMAGE_WIDTH 128
#define str_AI_RE_POL_out_0_IMAGE_HEIGHT 128
#define str_AI_RE_POL_out_0_IMAGE_CHANNEL 1
#define str_AI_RE_POL_out_0_DATA_LENGTH str_AI_RE_POL_out_0_IMAGE_WIDTH *str_AI_RE_POL_out_0_IMAGE_HEIGHT *str_AI_RE_POL_out_0_IMAGE_CHANNEL
#define str_AI_RE_POL_out_0_IMAGE_Name "491"
// POL 二次计算面积 输入图片尺寸
#define str_AI_RE_AD_IN_0_IMAGE_WIDTH 128
#define str_AI_RE_AD_IN_0_IMAGE_HEIGHT 128
#define str_AI_RE_AD_IN_0_IMAGE_CHANNEL 1
#define str_AI_RE_AD_IN_0_DATA_LENGTH str_AI_RE_AD_IN_0_IMAGE_WIDTH *str_AI_RE_AD_IN_0_IMAGE_HEIGHT *str_AI_RE_AD_IN_0_IMAGE_CHANNEL
#define str_AI_RE_AD_IN_0_IMAGE_Name "0"
// nf 输入图片尺寸
#define str_AI_RE_AD_out_0_IMAGE_WIDTH 128
#define str_AI_RE_AD_out_0_IMAGE_HEIGHT 128
#define str_AI_RE_AD_out_0_IMAGE_CHANNEL 1
#define str_AI_RE_AD_out_0_DATA_LENGTH str_AI_RE_AD_out_0_IMAGE_WIDTH *str_AI_RE_AD_out_0_IMAGE_HEIGHT *str_AI_RE_AD_out_0_IMAGE_CHANNEL
#define str_AI_RE_AD_out_0_IMAGE_Name "491"
// Edge 定位
#define str_AI_EDGE_Big_Model_Path "/home/aidlux/BOE/UseModel/Edge_Big.engine"
#define str_AI_EDGE_Small_Model_Path "/home/aidlux/BOE/UseModel/Edge_Small.engine"
// POL 二次计算面积 输入图片尺寸
#define str_AI_EDGE_Big_IN_0_IMAGE_WIDTH 1024
#define str_AI_EDGE_Big_IN_0_IMAGE_HEIGHT 736
#define str_AI_EDGE_Big_IN_0_IMAGE_CHANNEL 1
#define str_AI_EDGE_Big_IN_0_DATA_LENGTH str_AI_EDGE_Big_IN_0_IMAGE_WIDTH *str_AI_EDGE_Big_IN_0_IMAGE_HEIGHT *str_AI_EDGE_Big_IN_0_IMAGE_CHANNEL
#define str_AI_EDGE_Big_IN_0_IMAGE_Name "image"
// nf 输入图片尺寸
#define str_AI_EDGE_Big_out_0_IMAGE_WIDTH 1024
#define str_AI_EDGE_Big_out_0_IMAGE_HEIGHT 736
#define str_AI_EDGE_Big_out_0_IMAGE_CHANNEL 1
#define str_AI_EDGE_Big_out_0_DATA_LENGTH str_AI_EDGE_Big_out_0_IMAGE_WIDTH *str_AI_EDGE_Big_out_0_IMAGE_HEIGHT *str_AI_EDGE_Big_out_0_IMAGE_CHANNEL
#define str_AI_EDGE_Big_out_0_IMAGE_Name "mask"
// POL 二次计算面积 输入图片尺寸
#define str_AI_EDGE_Small_IN_0_IMAGE_WIDTH 320
#define str_AI_EDGE_Small_IN_0_IMAGE_HEIGHT 320
#define str_AI_EDGE_Small_IN_0_IMAGE_CHANNEL 1
#define str_AI_EDGE_Small_IN_0_DATA_LENGTH str_AI_EDGE_Small_IN_0_IMAGE_WIDTH *str_AI_EDGE_Small_IN_0_IMAGE_HEIGHT *str_AI_EDGE_Small_IN_0_IMAGE_CHANNEL
#define str_AI_EDGE_Small_IN_0_IMAGE_Name "image"
// nf 输入图片尺寸
#define str_AI_EDGE_Small_out_0_IMAGE_WIDTH 320
#define str_AI_EDGE_Small_out_0_IMAGE_HEIGHT 320
#define str_AI_EDGE_Small_out_0_IMAGE_CHANNEL 1
#define str_AI_EDGE_Small_out_0_DATA_LENGTH str_AI_EDGE_Small_out_0_IMAGE_WIDTH *str_AI_EDGE_Small_out_0_IMAGE_HEIGHT *str_AI_EDGE_Small_out_0_IMAGE_CHANNEL
#define str_AI_EDGE_Small_out_0_IMAGE_Name "mask"
// 缺pol 检测
#define str_AI_LOSSPOL_Model_Path "/home/aidlux/BOE/UseModel/BOE_LOSSPOL.engine"
// 输入图片尺寸
#define str_AI_LOSSPOL_IN_0_IMAGE_WIDTH 1024
#define str_AI_LOSSPOL_IN_0_IMAGE_HEIGHT 640
#define str_AI_LOSSPOL_IN_0_IMAGE_CHANNEL 1
#define str_AI_LOSSPOL_IN_0_DATA_LENGTH str_AI_LOSSPOL_IN_0_IMAGE_WIDTH *str_AI_LOSSPOL_IN_0_IMAGE_HEIGHT *str_AI_LOSSPOL_IN_0_IMAGE_CHANNEL
// nf 输入图片尺寸
#define str_AI_LOSSPOL_out_0_IMAGE_WIDTH 1024
#define str_AI_LOSSPOL_out_0_IMAGE_HEIGHT 640
#define str_AI_LOSSPOL_out_0_IMAGE_CHANNEL 1
#define str_AI_LOSSPOL_out_0_DATA_LENGTH str_AI_LOSSPOL_out_0_IMAGE_WIDTH *str_AI_LOSSPOL_out_0_IMAGE_HEIGHT *str_AI_LOSSPOL_out_0_IMAGE_CHANNEL
// Mark 检测
#define str_AI_Mark_Model_Path "/home/aidlux/BOE/UseModel/defect_MARK_LINE.engine"
// 输入图片尺寸
#define str_AI_Mark_IN_0_IMAGE_WIDTH 512
#define str_AI_Mark_IN_0_IMAGE_HEIGHT 512
#define str_AI_Mark_IN_0_IMAGE_CHANNEL 1
#define str_AI_Mark_IN_0_DATA_LENGTH str_AI_Mark_IN_0_IMAGE_WIDTH *str_AI_Mark_IN_0_IMAGE_HEIGHT *str_AI_Mark_IN_0_IMAGE_CHANNEL
// nf 输入图片尺寸
#define str_AI_Mark_out_0_IMAGE_WIDTH 512
#define str_AI_Mark_out_0_IMAGE_HEIGHT 512
#define str_AI_Mark_out_0_IMAGE_CHANNEL 1
#define str_AI_Mark_out_0_DATA_LENGTH str_AI_Mark_out_0_IMAGE_WIDTH *str_AI_Mark_out_0_IMAGE_HEIGHT *str_AI_Mark_out_0_IMAGE_CHANNEL
#define QX_SAMLLIMG_WIDTH 160
#define QX_SAMLLIMG_HEIGHT 160
// 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,98 @@
/*
* @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 AIIMGDeal_H_
#define AIIMGDeal_H_
#include <vector>
#include <thread>
#include <mutex>
#include <string>
#include <iostream>
#include <memory>
#include <opencv2/opencv.hpp>
#include "SingleGPU.h"
#include "AICommonDefine.h"
using namespace std;
class AI_IMG_deal
{
public:
AI_IMG_deal();
~AI_IMG_deal();
int Init(int nGpuIdx);
private:
int m_nGpuIdx;
private:
// new Data
int NewData();
// Delete Data
int DelteData();
public:
// 初始化
int Init_BOE(AIInitConfig config);
int Init_127Cell(AIInitConfig config);
int Init_BOE_Type2(AIInitConfig config);
int Init_BOE_UP(AIInitConfig config);
int Init_BOE_Chess(AIInitConfig config);
int Init_YX_1(AIInitConfig config);
int Init_YX_2(AIInitConfig config);
int Init_Cls(AIInitConfig config, int ntype); // 1023
int Init_zf(AIInitConfig config); // 1023
int Init_RE_POL(AIInitConfig config); // 1023
int Init_RE_AD(AIInitConfig config); // 1023
int Init_Edge_Big(AIInitConfig config); // 1023
int Init_Edge_Small(AIInitConfig config); // 1023
int Init_LackPol(AIInitConfig config);
int Init_MarkLine(AIInitConfig config);
// 检测
int AICheck_BOE(cv::Mat inImg, cv::Mat &outImg_1);
int AICheck_BOE_Type2(cv::Mat inImg, cv::Mat &outImg_1);
int AICheck_BOE_Chess(cv::Mat inImg, cv::Mat &outImg_1);
int AICheck_BOE_UP(cv::Mat inImg, cv::Mat &outImg_1);
int AICheck_YX_1(cv::Mat inImg, cv::Mat &outImg_1);
int AICheck_YX_2(cv::Mat inImg, cv::Mat &outImg_1);
int AICheck_Cls(cv::Mat inImg, int ntype, float *fmaxScore); // 1023
int AICheck_zf(cv::Mat inImg, cv::Mat &outImg_1);
int AICheck_127Cell(cv::Mat inImg, cv::Mat &outImg_1);
int AICheck_RE_POL(cv::Mat inImg, cv::Mat &outImg_1);
int AICheck_RE_AD(cv::Mat inImg, cv::Mat &outImg_1);
int AICheck_Edge_Big(cv::Mat inImg, cv::Mat &outImg_1);
int AICheck_Edge_Small(cv::Mat inImg, cv::Mat &outImg_1);
int AICheck_LackPol(cv::Mat inImg, cv::Mat &outImg_1);
int AICheck_MarkLine(cv::Mat inImg, cv::Mat &outImg_1);
private:
cv::Mat F2M(float *data, int clannel, int w, int h);
cv::Mat InitMat(int channel, int w, int h);
int F2softmaxId(float *data, int class_num, float *fmaxScore); // 1024dyy-add
private:
AI_SingleGPU *m_pAI_SingleGPU;
float *AI_DATA_Cls_OUT_0;
float *AI_DATA_Cls_L0_OUT_0;
bool bInitSucc_127Cell;
bool bInitSucc_re_Pol;
bool bInitSucc_re_AD;
bool bInitSucc_MarkLine;
bool bInitSucc_Edge_big;
bool bInitSucc_Edge_Samll;
bool bInitSucc_LackPol;
};
#endif

@ -0,0 +1,178 @@
/*
//实现对部分缺陷 需要进行 数量 和距离上分析的
*/
#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"
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; // 原图上产品区域
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();
}
}
};
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 bSaveResultImg; // 保存结果图片
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;
bSaveResultImg = 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(bSaveResultImg), 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 Init(OtherDet_Config *pOtherDet_Config);
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, cv::Rect &bigRoi, cv::Mat &big_mask);
private:
bool m_bInitSucc; // 是否初始化成功
// 检测结果
// std::shared_ptr<Edge_AI_Result> m_pCheckResult_Aling;
OtherDet_Config *m_pOtherDet_Config;
DetConfig *m_pDetConfig;
AI_IMG_deal *m_pAIDeal;
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,79 @@
/*
//实现对部分缺陷 需要进行 数量 和距离上分析的
*/
#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"
using namespace std;
using namespace cv;
// 二次分割求面积
class AI_Mark_Det : public AIDetectBase
{
public:
// 检测参数和结果
struct DetConfigResult
{
int ncamID;
int nresult;
cv::Rect searchroi;
std::string strChannel;
bool bsaveprocessimg;
cv::Rect markRoi;
DetConfigResult()
{
nresult = -1;
ncamID = 0;
strChannel = "";
searchroi = cv::Rect(0, 0, 0, 0);
bsaveprocessimg = false;
markRoi = cv::Rect(0, 0, 0, 0);
}
};
public:
AI_Mark_Det(/* args */);
~AI_Mark_Det();
int InitModel_ALL();
int Detect(const cv::Mat &img, DetConfigResult *pDetConfig);
private:
int InitModel();
cv::Rect GetCutRoi(cv::Rect &roi, const cv::Mat &img);
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;
int m_Show_Area;
float m_Show_Len;
cv::Point m_Len_P1;
cv::Point m_Len_P2;
private:
/* data */
};
#endif

@ -0,0 +1,100 @@
/*
//实现对部分缺陷 需要进行 数量 和距离上分析的
*/
#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"
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;
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 InitModel_ALL();
int Detect(const cv::Mat &img, const cv::Mat &mask, DetConfigResult *pDetConfig);
private:
int InitModel_Re_POL();
int InitModel_Re_AD();
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;
int m_Show_Area;
float m_Show_Len;
cv::Point m_Len_P1;
cv::Point m_Len_P2;
private:
/* data */
};
#endif

@ -0,0 +1,196 @@
/*
* @Author: your name
* @Date: 2022-04-20 15:49:50
* @LastEditTime: 2025-07-26 11:23: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 ALLImgCheckAnalysisy_H_
#define ALLImgCheckAnalysisy_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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "BlobBase.h"
#include "AICheck.h"
#include "ImgCheckBase.h"
#include "ImageDetBase.h"
#include "ImgCheckConfig.h"
#include "CheckErrorCodeDefine.hpp"
#include "ConfigBase.h"
#include "CheckSODefine.hpp"
#include "CheckConfigDefine.h"
#include "EdgeDet.h"
#include "ImageDetConfig.h"
#include "Define_Product.hpp"
#include "CameraCheckAnalysisy.hpp"
using namespace std;
using namespace cv;
class ALLImgCheckAnalysisy : public ALLImgCheckBase
{
public:
ALLImgCheckAnalysisy();
~ALLImgCheckAnalysisy();
// 初始化参数 pconfig 参数指针 返回0 成功 其他异常
int RunStart(void *pconfig1);
// 设置检测数据,并开启检测 返回0 成AT_THRESHOLD_TYPE_READY功 其他异常
int SetDataRun_SharePtr(std::shared_ptr<shareImage> p);
// 获取结果信息 返回0 成功 其他异常
int GetCheckReuslt(std::shared_ptr<CheckResult> &pResult);
int CheckImg(std::shared_ptr<shareImage> p, std::shared_ptr<CheckResult> &pResult);
// 获取检测库 状态信息 返回CHECK_THREAD_RUN_STATUS
int GetStatus();
// 更新参数 pconfig 参数指针nConfigType 需要更新的参数类型 返回0 成功 其他异常
int UpdateConfig(void *pconfig, int nConfigType);
std::string GetVersion();
std::string GetErrorInfo();
private:
// 加载运行参数
int LoadRunConfig(void *p);
// 加载分析参数
int LoadCheckConfig(void *p);
/// @brief 初始化并且启动程序
/// @return
int InitRun();
/// @brief 开启检测
/// @return
int StartCheck();
/// @brief 设置空闲
/// @return
int SetIDLE();
private:
// 开启线程
int StartThread();
// 停止线程
int StopThread();
// 退出系统
int ExitSystem();
// 初始化相机检测分析类
int InitCameraCheckAnalysisy();
// 设置相机图片并开始检测分析
int SetCameraImgAndStartDet(std::string strcameraName, std::shared_ptr<Camera_Check_Result> pCamera);
// 初始化
int InitData();
// 处理产品
int Det_Product();
// 联合分析
int AnalysiyAll(int productIdx);
// 暗点联合分析
int AD_AllChannelAnalysisy(int productIdx, std::shared_ptr<PRODUCT_DET_RESULT_> &pProduct);
int AD_AllChannelAnalysisy_New();
int POL_AllChannelAnalysisy_New();
// 设置最终结果
int SetProductResult();
// 设置检测完成
int SetSetComplet(int productIdx, int result, int nerror);
int SetSetComplet_New(int result, int nerror);
// 处理数量
int DetListNum();
// 加载图片 队列
int PushInImg_New(std::shared_ptr<shareImage> p);
// 当前检查环境判断
int CurCheckListStatus();
// 异常返回
int ErrorReturn(std::shared_ptr<shareImage> p);
float CalImgScorl(cv::Mat det_img, cv::Mat up_img);
int AddStrToLog(int productIdx, std::string str);
int AddStrToLog_New(std::string str);
// 设置新的检测参数
int SetNewConfig();
ChannelCheckFunction *GetChannelFuntion(std::string strChannelName); // 获得 通道的检测功能
private:
// 图片处理线程
std::shared_ptr<std::thread> ptr_thread_Run;
int Run(); // 运行;
int set_cpu_id(const std::vector<int> &cpu_set_vec);
private:
RunInfoST m_RunConfig;
// 检测参数模块
ConfigBase *m_pConfig;
ConfigBase *m_pConfig_Cam2;
// 图片处理线程
// 相机处理模块,负责完成对应相机图片的处理功能。
CameraCheckAnalysisy *m_pCameraCheckAnalysisy[MAX_Camera_NUM];
PRINT_LOG_ m_PrintLog;
// 互斥锁定义
private:
// 产品的所有信息
std::shared_ptr<Product_Check_Result> m_ProductImgDetResult_New;
std::vector<std::shared_ptr<PRODUCT_DET_RESULT_>> m_ProductImgDetResultList;
std::mutex mtx_ProductImgDetResultList; // 互斥锁,用于保护数据队列
std::mutex mtx_DetSingle; // 互斥量
std::queue<std::shared_ptr<CheckResult>> m_CheckResultList; // 检测结果
std::mutex mtx_CheckResult; // 互斥锁,用于保护数据队列
std::condition_variable CheckResult_cond; // 条件变量,用于同步生产者和消费者线程
std::vector<std::string> Last_det_LogList; // 上一个产品的检测日志
std::mutex mtx_Last_det_LogList; // 互斥量
private:
int m_nErrorCode; // 错误代码
bool m_bInitSucc; // 初始化状态
bool m_bExit; // 是否退出检测
std::shared_ptr<ImageDetResult> m_OneImg_Result_shareP;
std::shared_ptr<ImageDetconfig> DetImgInfo_shareP;
std::string m_strTest;
// 检测分析参数
AnalysisyConfigST m_AnalysisyConfig;
ALLChannelCheckFunction *m_pChannelFuntion; // 画面检测功能
// 当前检测产品的个数
int m_CurProductIdx;
ReJson_Status m_reJsonStatus_push; // 复测状态;送图
ReJson_Status m_reJsonStatus_Det; // 复测状态;复测
};
#endif

@ -0,0 +1,127 @@
#pragma once
enum ERR_DOT_TYPE_ENUM
{
ERR_TYPE_1,
ERR_TYPE_2,
ERR_TYPE_3,
ERR_TYPE_4,
ERR_TYPE_5,
ERR_TYPE_6,
ERR_TYPE_COUNT,
};
//-----------------------sxg added
#define _MAX_ERROR_SCAN_LINE_PER_ROW 200
#define _MAX_ERROR_DOT_BLOB 1000
#define _MAX_MACRO_COUNT 4
#define _MAX_ERR_CLASS ERR_TYPE_COUNT
// #define _CAM_WIDTH 640
#define _MAX_MIN_VALUE_NUM 10
typedef struct ERROR_DOTS_SCAN_DATA
{
unsigned short x, count;
unsigned short minx, miny;
unsigned short maxx, maxy;
int area, energy;
int xposSum, yposSum;
int macro;
int type;
int ErrClass[_MAX_ERR_CLASS];
} ERROR_DOTS_SCAN_DATA;
typedef struct ERROR_DOTS_SCAN_ROW
{
int scanCount;
ERROR_DOTS_SCAN_DATA errorScanLineTab[_MAX_ERROR_SCAN_LINE_PER_ROW];
int macro[_MAX_MACRO_COUNT];
int ErrClass[_MAX_ERR_CLASS];
int minValue[_MAX_MIN_VALUE_NUM];
} ERROR_DOTS_SCAN_ROW;
typedef struct ERROR_DOTS_BLOB_DATA
{
unsigned short x, y;
unsigned short minx, miny;
unsigned short maxx, maxy;
int area;
int energy;
float JudgArea;
float len;
int macro[_MAX_MACRO_COUNT];
int ErrClass[_MAX_ERR_CLASS];
int ErrDesc;
int ErrType;
int UserErrorType;
int maxValue;
float grayDis;
int AIclasstype;
float density;
unsigned short badd;
} ERROR_DOTS_BLOB_DATA;
typedef struct ERROR_DOTS_BLOBS
{
int blobCount;
int totalArea;
int totalEnergy;
ERROR_DOTS_BLOB_DATA blobTab[_MAX_ERROR_DOT_BLOB];
int ErrClass[_MAX_ERR_CLASS];
int Pass[_MAX_ERROR_DOT_BLOB];
} ERROR_DOTS_BLOBS;
typedef struct ERROR_DOTS_BLOB_PARAM
{
int minArea; // ²ÐµãÇøÓòÃæ»ý×îСֵ£¬µ¥Î»ÎªÏñËØµã£¬Èç¹ûСÓÚ´ËÖµ£¬ÔòºöÂÔ
int minEnergy; // ²ÐµãÇøÓòÄÜÁ¿×îСֵ£¬Èç¹ûСÓÚ´ËÖµ£¬ÔòºöÂÔ
int maxErrorBlobCount; // ×î´óÔÊÐíµÄÂú×ãÉÏÊöÌõ¼þºóµÄ²ÐµãÇøÓòÊýÁ¿£¬Èç¹û´óÓÚ´ËÖµ£¬ Ôò±¨´í
int maxTotalArea; // ×î´óÔÊÐíµÄÂú×ãÉÏÊöÌõ¼þºóµÄ²ÐµãÇøÓò×ÜÃæ»ý£¬Èç¹û´óÓÚ´ËÖµ£¬ Ôò±¨´í
int maxTotalEnergy; // ×î´óÔÊÐíµÄÂú×ãÉÏÊöÌõ¼þºóµÄ²ÐµãÇøÓò×ÜÄÜÁ¿£¬Èç¹û´óÓÚ´ËÖµ£¬ Ôò±¨´í
int maxRegionArea; // ×î´óÔÊÐíµÄµ¥¸ö²ÐµãÇøÓòÃæ»ý£¬Èç¹û´óÓÚ´ËÖµ£¬ Ôò±¨´í
int maxRegionEnergy; // ×î´óÔÊÐíµÄµ¥¸ö²ÐµãÇøÓòÄÜÁ¿£¬Èç¹û´óÓÚ´ËÖµ£¬ Ôò±¨´í
int Hthold[4]; // ѧϰģ°æºóµÄÀ©Õ¹ãÐÖµ
int Lthold[4]; // ѧϰģ°æºóµÄÀ©Õ¹ãÐÖµ
int Level[2]; // ÑÏÖØµÈ¼¶
int mergeDistance; // ²ÐµãºÏ²¢×îС¾àÀë £¬¡¡ÈôÁ½¸ö²Ðµã¾àÀëСÓÚ´ËÖµÔòºÏ²¢ÎªÒ»¸ö
int isUseMacro;
} ERROR_DOTS_BLOB_PARAM;
typedef struct ERROR_BLOBS_PARAM
{
int id;
unsigned char *pb;
unsigned char *pr;
unsigned char *pc;
int width;
int height;
int obj;
ERROR_DOTS_BLOBS *blobs;
} ERROR_BLOBS_PARAM;
#ifdef __cplusplus
extern "C"
{
#endif
void pretest(double x);
extern void AddErrorScan(ERROR_DOTS_SCAN_ROW *curRow, ERROR_DOTS_SCAN_ROW *prevRow, int x, int len, int y, int difSum, int minArea, int minEng, int mdx, int *pErrClass);
extern void LinkScanLineToBlob(ERROR_DOTS_BLOBS *blobs, ERROR_DOTS_SCAN_ROW *prevRow, int sx, int sy, int minArea, int minEnergy, int mergeDistanceX, int mergeDistanceY, int width);
extern void SortBlob(ERROR_DOTS_BLOBS *blobs);
extern void MergeBlob(ERROR_DOTS_BLOBS *blobs, ERROR_DOTS_BLOB_PARAM *param);
extern void AddErrorScan_New(ERROR_DOTS_SCAN_ROW *curRow, ERROR_DOTS_SCAN_ROW *prevRow, int x, int len, int y, int difSum, int minArea, int minEng, int errorType);
extern void LinkScanLineToBlob_New(ERROR_DOTS_BLOBS *blobs, ERROR_DOTS_SCAN_ROW *prevRow, int sx, int sy, int minArea, int minEnergy, int mergeDistanceX, int mergeDistanceY, int width);
extern int GetBlobsFromImg(ERROR_DOTS_BLOBS *blobs_0, ERROR_DOTS_BLOBS *blobs_1, ERROR_DOTS_BLOBS *blobs_2, unsigned char *pb, unsigned char *pr, unsigned char *pc, int width, int height, int obj);
extern int GetBlobsFromIm_1(ERROR_DOTS_BLOBS *blobs, unsigned char *pcropdata, unsigned char *pcropConstructdata, unsigned char *pGrayErrordata, unsigned char *pRGBErrordata, int width, int height);
extern int GetBlobsFromIm_2(ERROR_DOTS_BLOBS *blobs, unsigned char *pcropdata, unsigned char *pcropConstructdata, unsigned char *pGrayErrordata, unsigned char *pRGBErrordata, unsigned char *pGrayMaskdata, int width, int height, int ndiffValueT);
extern int GetBlobsFromIm_All(ERROR_DOTS_BLOBS *blobs, unsigned char *pcropdata, unsigned char *pcropConstructdata, unsigned char *pGrayErrordata, unsigned char *pRGBErrordata, unsigned char *pGrayMaskdata, int width, int height, int ndiffValueT);
extern int GetBlobsFromIm_single(ERROR_DOTS_BLOBS *blobs, unsigned char *pcropdata, unsigned char *pcropConstructdata, unsigned char *pErrordata, int nstartPos, int nstep, int npitch, int nErrorType, unsigned char *pGrayMaskdata, int width, int height, int ndiffValueT);
extern int GetBlobsFromIm_All_onemask(ERROR_DOTS_BLOBS *blobs, unsigned char *pcropdata, unsigned char *pRGBErrordata, unsigned char *pGrayMaskdata, int width, int height, int ndiffValueT);
extern int GetBlobsFromIm_single_onemask(ERROR_DOTS_BLOBS *blobs, unsigned char *pcropdata, unsigned char *pErrordata, int AndValue, int npitch, int nErrorType, unsigned char *pGrayMaskdata, int width, int height, int ndiffValueT);
extern int GetBlobs_V2(ERROR_DOTS_BLOBS *blobs, unsigned char *pImgdata, unsigned char *pErrordata, int width, int height, int basev, int minArea);
#ifdef __cplusplus
}
#endif

@ -0,0 +1,21 @@
/*
* @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 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 wrap_test_print();
void Cuda_ucharToFloat(const unsigned char* input, float* output, int size);
void Cuda_FloatTouchar(const float* input, unsigned char* output, int size);
#endif

@ -0,0 +1,154 @@
/*
* @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 CameraCheckAnalysisy_H_
#define CameraCheckAnalysisy_H_
#include <mutex>
#include <vector>
#include <thread>
#include <string>
#include <stdio.h>
#include <condition_variable>
#include "Define_Base.h"
#include "AICheck.h"
#include "ImgCheckBase.h"
#include "ImageDetBase.h"
#include "ImgCheckConfig.h"
#include "CheckErrorCodeDefine.hpp"
#include "ConfigBase.h"
#include "CheckSODefine.hpp"
#include "CheckConfigDefine.h"
#include "EdgeDet.h"
#include "ImageDetConfig.h"
#include "Define_Product.hpp"
#include "AI_Mark_Det.h"
using namespace std;
using namespace cv;
// 相机处理类
class CameraCheckAnalysisy
{
public:
CameraCheckAnalysisy();
~CameraCheckAnalysisy();
// 相机处理类 初始化
int Init(Camera_IDX camera_ID);
int StartCheck(std::shared_ptr<Camera_Check_Result> pCamera_Check_Result);
private:
// 开启线程
int StartThread();
// 停止线程
int StopThread();
// 初始化检测分析线程类
int InitCheckAnalysisy();
// 初始化其他
int InitRun();
// 设置新的检测参数
int SetNewConfig();
int InitMarkLine();
// 处理每张图片
int CheckImgRun();
int Run(); // 运行;
int set_cpu_id(const std::vector<int> &cpu_set_vec);
// 等待处理图片
int WaitDetImg();
// 增加日志
int AddStrToLog_New(std::string str);
// 预处理图片
int Detect_Pre();
// 处理每张图片
int Detect_Images();
// 边缘处理
int ImgEdge(cv::Mat img, bool bUseDraw, const cv::Mat &paraMaskImg, int thresholdvalue, int AIErodesize, bool bUseAIDet, cv::Mat &detMaskImg, cv::Rect &roi, int productIdx);
// 插入相机日志
int InsertCameraLog();
ChannelCheckFunction *GetChannelFuntion(std::string strChannelName); // 获得 通道的检测功能
// 特征主定位
int Feature_Align(const cv::Mat &detSrcImg, int nproductIdx, cv::Rect Det_CropRoi, ChannelCheckFunction *pFuntion_L255, const cv::Mat &detImg_mask, bool bsave = false, bool bsaveprocessimg = false);
// 预处理 字符检测
int preDet_ZF(std::shared_ptr<ImageDetconfig> p, std::shared_ptr<ImageDetResult> &pResult);
// 检测MarkLine
int Det_MarkLine(const cv::Mat &detSrcImg, cv::Rect Det_CropRoi, Base_Function_MarkLine *pFuntion, cv::Mat &detImg_mask, cv::Rect &markRoi_x, cv::Rect &markRoi_y, bool bsaveprocessimg = false);
// 获取 检测核心库
ImgCheckBase *GetDealResult(int idx = -1);
int GetAndAnalysisyCheckResult(std::shared_ptr<ImageDetResult> &pResult);
public:
// 运行的基本参数
RunInfoST m_RunConfig;
// 检测参数模块
ConfigBase *m_pConfig;
PRINT_LOG_ m_PrintLog;
AI_Edge_Algin::DetConfig AI_detConfig;
Align_Result m_align_Result;
// 图片特征定位
Image_Feature_Algin m_Image_Feature_Algin;
// 检测分析参数
AnalysisyConfigST m_AnalysisyConfig;
ALLChannelCheckFunction *m_pChannelFuntion; // 画面检测功能
BaseCheckFunction *m_pbaseCheckFunction; // 基础检测
std::shared_ptr<ImageDetResult> m_OneImg_Result_shareP;
std::shared_ptr<ImageDetconfig> DetImgInfo_shareP;
std::string m_strCameraName;
private:
// 相机ID
Camera_IDX m_camera_ID;
int m_ncamera_idx;
int m_nErrorCode; // 错误代码
bool m_bInitSucc; // 初始化状态
bool m_bExit; // 是否退出检测
int nLastCheckAnalysisyThreadIdx;
// 图片处理线程
std::shared_ptr<std::thread> ptr_thread_Run;
// 单相机的相关结果信息
std::shared_ptr<Camera_Check_Result> m_pCamera_Check_Result;
bool m_bHaveImgeDet; // 是否有图片需要检查
std::mutex mtx_WaiteImg; // 等待图片的锁
std::condition_variable cond_WaiteImg; // 条件变量,是否有图片需要检查
private:
// 检测核心库
ImgCheckBase *m_pImgCheckAnalysisy[IMGCHECKANALYSISY_NUM];
AI_IMG_deal m_AIDeal;
OtherDet_Config m_OtherDet_Config;
// 边缘检测
EdgeDet_New m_DetEdge;
AI_Mark_Det m_MarkDet; // Mark检测
CHECK_TEM_RESULT m_TemCheck;
private:
private:
};
#endif

@ -0,0 +1,512 @@
#ifndef _CheckErrorDefine_HPP_
#define _CheckErrorDefine_HPP_
#include <string>
#include <opencv2/opencv.hpp>
#include "CheckUtil.hpp"
#include "Base_Define.h"
#include "Define_Base.h"
#include "Define_Error.h"
#define BOOL_TO_STR(bool_expr) (bool_expr) ? "true" : "false"
#define BOOL_TO_STROK(bool_expr) (bool_expr) ? "OK" : "NG"
#define BOOL_TO_ThanLess(bool_expr) (bool_expr) ? ">" : "<"
#define BOOL_TO_LessThan(bool_expr) (bool_expr) ? "<" : ">"
#define BOOL_TO_STR_Error(bool_expr) ((bool_expr) ? "Succ" : "Error")
#define Re_TO_STR_Error(num) ((num) == 0 ? "Succ" : "Error")
#define Re_TO_STR_False(num) ((num) == 0 ? "Succ" : "false")
#define Re_TO_STR_Pass_1(num) ((num) == 1 ? "Pass" : "fail")
#define Re_TO_STR_NG(num) ((num) == 0 ? "OK" : "NG")
#define SRC_IMG_WIDTH 14192
#define SRC_IMG_HEIGHT 10640
// 输入模型图片尺寸
#define SRC_AI_In_IMAGE_WIDTH 1024
#define SRC_AI_In_IMAGE_HEIGHT 1024
// resize 图片的 宽度
#define RESIZE_IMAGE_WIDTH 1280
enum PrintLevel_
{
PrintLevel_0,
PrintLevel_1,
PrintLevel_2,
PrintLevel_3,
PrintLevel_4,
};
enum TEM_IMG_IDX_
{
TEM_IMG_IDX_SrcCrop,
TEM_IMG_IDX_AImask,
TEM_IMG_IDX_DrawSrc,
TEM_IMG_IDX_Result,
TEM_IMG_IDX_Count,
};
static const std::string TEM_IMG_IDX_Names[] =
{
"SrcCrop",
"AImask",
"Drawmask",
"result"};
// 检测过程临结果
struct CHECK_TEM_RESULT
{
cv::Mat temImgList[TEM_IMG_IDX_Count];
std::vector<std::string> timeInfoList;
std::vector<std::string> analysisInfoList;
std::vector<std::string> temlogList;
bool bPrintStr; // 是否打印日志
int addLogLevel;
bool bInTemList;
CHECK_TEM_RESULT()
{
Init();
}
void Init()
{
timeInfoList.clear();
timeInfoList.shrink_to_fit();
analysisInfoList.clear();
analysisInfoList.shrink_to_fit();
temlogList.clear();
temlogList.shrink_to_fit();
for (int i = 0; i < TEM_IMG_IDX_Count; i++)
{
if (!temImgList[i].empty())
{
temImgList[i].release();
}
}
bPrintStr = false;
addLogLevel = 0;
bInTemList = false;
}
void temLogListInit()
{
temlogList.erase(temlogList.begin(), temlogList.end());
temlogList.clear();
}
void AddTimeStr(std::string str, long start, long end)
{
char text[1024] = {0};
double t = end - start;
sprintf(text, "%s : use Time :%.2f", str.c_str(), t);
std::string temstr = text;
printf("%s\n", temstr.c_str());
timeInfoList.push_back(temstr);
}
template <typename... Args>
void AddCheckstr(int 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(format, args...);
if (bPrintStr)
{
printf("%s\n", str.c_str());
}
if (bInTemList)
{
temlogList.push_back(str);
}
else
{
if (LogLevel <= addLogLevel)
{
analysisInfoList.push_back(str);
}
}
}
void AddCheckstr(std::string str)
{
if (str == "")
{
return;
}
printf("%s\n", str.c_str());
analysisInfoList.push_back(str);
}
void AddCheckstr(std::string str, std::string str1)
{
str = str + ":" + str1;
printf("%s\n", str.c_str());
analysisInfoList.push_back(str);
}
void AddCheckstr(std::string str, int value)
{
str = str + ":" + std::to_string(value);
printf("%s\n", str.c_str());
analysisInfoList.push_back(str);
}
void AddCheckstr(std::string str, float value)
{
str = str + ":" + std::to_string(value);
printf("%s\n", str.c_str());
analysisInfoList.push_back(str);
}
void saveImg()
{
for (int i = 0; i < TEM_IMG_IDX_Count; i++)
{
if (!temImgList[i].empty())
{
std::string str = TEM_IMG_IDX_Names[i] + ".png";
cv::imwrite(str, temImgList[i]);
}
}
}
};
enum Print_Level_
{
Print_Level_Info,
Print_Level_Key,
Print_Level_Error,
};
// 大于日志
struct PRINT_LOG_
{
bool bprint;
bool bshow_Info;
bool bshow_Key;
bool bshow_Error;
PRINT_LOG_()
{
Init();
}
void Init()
{
bprint = true;
bshow_Info = true;
bshow_Key = true;
bshow_Error = true;
}
template <typename... Args>
std::string printstr(int LogLevel, std::string stepStr, const std::string &format, Args... args)
{
std::string str = "";
if (!bprint)
{
return str;
}
switch (LogLevel)
{
case Print_Level_Info:
if (!bshow_Info)
{
return str;
}
str = "info-> ";
break;
case Print_Level_Key:
if (!bshow_Key)
{
return str;
}
str = "key-> ";
break;
case Print_Level_Error:
if (!bshow_Error)
{
return str;
}
str = "Error-> ";
break;
default:
return str;
break;
}
str += stepStr + ": ";
str += str_Format(format, args...);
printf("%s\n", str.c_str());
return str;
}
};
#define MAX_THREAD_AIDET_NUM 2
struct SMALLIMGINFO
{
int nDetType;
int nidx;
cv::Mat img;
cv::Mat outimg;
cv::Rect Roi;
int flag;
int start_x;
int start_y;
int nresult;
int x_idx;
int y_idx;
SMALLIMGINFO()
{
Init();
}
~SMALLIMGINFO()
{
release();
}
void Init()
{
if (!img.empty())
{
img.release();
}
if (!outimg.empty())
{
outimg.release();
}
nDetType = 0;
flag = 0;
start_x = 0;
start_y = 0;
nidx = 0;
nresult = 0;
x_idx = 0;
y_idx = 0;
}
void release()
{
if (!img.empty())
{
img.release();
}
if (!outimg.empty())
{
outimg.release();
}
}
};
struct YX_CheckResult_
{
int nresult; // 检测结果
YX_CheckResult_()
{
Init();
}
void Init()
{
nresult = 0;
}
};
// 缺失POl 检测
struct LackPol_CheckResult_
{
int nresult; // 检测结果
LackPol_CheckResult_()
{
Init();
}
void Init()
{
nresult = 0;
}
};
struct WTB_Check_Result_
{
cv::Rect roi_src;
cv::Rect roi_show;
WTB_Check_Result_()
{
Init();
}
void Init()
{
roi_src = cv::Rect(0, 0, 0, 0);
roi_show = cv::Rect(0, 0, 0, 0);
}
};
// 其他检测结果
struct OtherCheckResult
{
YX_CheckResult_ result_YX;
WTB_Check_Result_ WTB_Check_Result;
LackPol_CheckResult_ result_LackPol;
OtherCheckResult()
{
Init();
}
void Init()
{
result_YX.Init();
WTB_Check_Result.Init();
result_LackPol.Init();
}
};
// 检测指令
struct CHECK_INSTRUCT_
{
bool bWhiteAndBlack; // 使用另外一个 检测模型。
CHECK_INSTRUCT_()
{
Init();
}
void Init()
{
bWhiteAndBlack = false;
}
};
// 亮点的判断参数
struct LD_ConfigT_
{
bool buse;
float minArea;
float maxArea;
float hj;
LD_ConfigT_()
{
buse = false;
minArea = 0;
maxArea = 0;
hj = 0;
}
void print(std::string str)
{
printf("%s buse %d minArea %f maxArea %f hj %f\n", str.c_str(), buse, minArea, maxArea, hj);
}
};
// 检测区域参数
struct Detect_ROI_Config
{
bool bdraw; // 是否绘制
std::vector<std::vector<cv::Point>> roiList_Src;
std::vector<std::vector<cv::Point>> roiList_Show;
Detect_ROI_Config()
{
Init();
}
void Init()
{
bdraw = false;
for (auto &innerVec : roiList_Src)
{
innerVec.clear();
}
roiList_Src.clear(); // 清空外层vector
for (auto &innerVec : roiList_Show)
{
innerVec.clear();
}
roiList_Show.clear(); // 清空外层vector
}
void Update(const std::vector<cv::Point> &list, const cv::Rect &roi, float fScale_x, float fScale_y)
{
std::vector<cv::Point> adjustedPolygon;
std::vector<cv::Point> adjustedPolygon_size;
// 遍历多边形中的每个点并根据roi调整位置
for (const auto &point : list)
{
// 调整每个点的位置平移到roi的位置
cv::Point adjustedPoint(point.x - roi.x, point.y - roi.y);
cv::Point sizep;
sizep.x = adjustedPoint.x * fScale_x;
sizep.y = adjustedPoint.y * fScale_y;
adjustedPolygon.push_back(adjustedPoint);
adjustedPolygon_size.push_back(sizep);
}
// 将调整后的多边形添加到roiList_Src
roiList_Src.push_back(adjustedPolygon);
roiList_Show.push_back(adjustedPolygon_size);
}
// 判断点是否在指定idx的ROI内
bool isPointInROI(int idx, const cv::Point &point)
{
// 判断索引是否有效
if (idx < 0 || idx >= roiList_Src.size())
{
printf("Invalid idx: %d\n", idx);
return false;
}
// 获取第 idx 个多边形
const std::vector<cv::Point> &polygon = roiList_Src[idx];
// 使用 pointPolygonTest 来判断点是否在多边形内
double result = cv::pointPolygonTest(polygon, point, false);
// 如果结果大于 0则点在多边形内
if (result > 0)
{
return true;
}
// 如果结果等于 0点在边界上
else if (result == 0)
{
return true; // 你可以根据需求调整边界情况
}
// 如果结果小于 0点在多边形外
return false;
}
void print(std::string str)
{
printf("%s bdraw %d roi num %ld\n", str.c_str(), bdraw, roiList_Src.size());
}
};
// 复测的状态
enum ReJson_Status
{
ReJson_Status_Idel,
ReJson_Status_start,
ReJson_Status_Run,
ReJson_Status_end,
};
struct AD_Channel_Info_
{
cv::Rect roi;
int num;
float fdis;
AD_Channel_Info_()
{
roi = cv::Rect(0, 0, 0, 0);
num = 0;
fdis = 999999999999;
}
};
extern std::string GetErrorCodeInfo(int nErrorCode);
#endif //_CORELOGICFACTORY_HPP_

@ -0,0 +1,76 @@
/*
* @Descripttion:
* @version:
* @Author: sueRimn
* @Date: 2022-04-28 10:41:42
* @LastEditors: sueRimn
* @LastEditTime: 2022-04-28 15:32:49
*/
/*
* 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 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 CalRoi2RoiPre(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 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::Point p1, cv::Point 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);
};
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
// 最大 GPU 个数
#define MAX_GPU_NUM 2
// 单个产品有几个相机拍摄
#define MAX_Camera_NUM 2
// 相机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];
}
};
#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,281 @@
#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_ImgeDet_End, // 图片检测完成
Check_Step_Complete, // 处理完成
Check_Step_COUNT,
};
// 检测结果状态
enum Check_Result_Status
{
Check_Result_Status_NoDet = -1, // 未检测
Check_Result_Status_PreError = -2, // 预处理错误
Check_Result_Status_DetError = -3, // 检测错误
Check_Result_Status_OK = 0, // 检测成功 结果OK
Check_Result_Status_NG = 1, // 检测成功 检测结果NG
};
// 产品检测结果
struct PRODUCT_DET_RESULT_
{
int nresult; // 检测结果
int nError; // 错误情况
std::string strSN; // 产品SN号。
int AddImgStatus; // 检测图片状态
int detImgStatus; // 检测状态 1表检测全部完成
int L255ImgStatus; // l255 图片状态 1 有了
bool bDet_Edge;
bool bDet_Zf;
bool bDet_Up;
int nDet_DP;
bool bhaveDPImg; // 是否有DP的图片
bool bHaveUPImg; // 是否有UP的图片
cv::Rect CutRoi;
std::shared_ptr<std::vector<cv::Rect>> pZF_roiList; // 字符的区域
cv::Mat Edge_maskImg;
cv::Mat Up_MaskImg;
cv::Mat DP_MaskImg;
std::vector<std::shared_ptr<CheckResult>> DetImageList; // 每个通道的检测结果 ,返回的结果。
std::vector<std::shared_ptr<ImageDetResult>> pImageDetResultList; // 检测结果的完整信息
std::vector<std::string> LogList;
int nNotDetCount; // 未检测计数。 当计算超过阈值时,直接不检测,返回结果。
PRODUCT_DET_RESULT_()
{
Init();
}
void Init()
{
nresult = 0;
nError = 0;
strSN = "";
AddImgStatus = 0;
detImgStatus = 0;
L255ImgStatus = 0;
bDet_Edge = false;
bDet_Zf = false;
bDet_Up = false;
bhaveDPImg = false;
bHaveUPImg = false;
nDet_DP = 0;
CutRoi = cv::Rect(0, 0, 0, 0);
if (!Edge_maskImg.empty())
{
Edge_maskImg.release();
}
if (!Up_MaskImg.empty())
{
Up_MaskImg.release();
}
if (!DP_MaskImg.empty())
{
DP_MaskImg.release();
}
LogList.clear();
LogList.shrink_to_fit();
nNotDetCount = 0;
}
};
// 相机检测结果
struct Camera_Check_Result
{
int detMode; // 检测模式
Camera_Info camera_info; // 相机信息
Check_Result_Status checkResultStatus; // 检测结果状态
int nresult; // 检测结果
Check_Step checkStep; // 检测步骤
CameraImage_Status cameraImage_Status; // 图片状态
ErrorInfo errorInfo; // 错误情况
std::string strSN; // 产品SN号。
int AddImgStatus; // 检测图片状态
int detImgStatus; // 检测状态 1表检测全部完成
int L255ImgStatus; // l255 图片状态 1 有了
bool bDet_Edge;
bool bDet_Zf;
bool bDet_Up;
int nDet_DP;
bool bhaveDPImg; // 是否有DP的图片
bool bHaveUPImg; // 是否有UP的图片
cv::Rect CutRoi;
std::shared_ptr<std::vector<cv::Rect>> pZF_roiList; // 字符的区域
cv::Mat sheildImg; // 屏蔽图片
cv::Mat edge_SheildImg; // 边缘屏蔽图片
cv::Mat Edge_maskImg;
cv::Mat Up_MaskImg;
cv::Mat DP_MaskImg;
std::vector<std::shared_ptr<CheckResult>> DetImageList; // 每个通道的检测结果 ,返回的结果。
std::vector<std::shared_ptr<ImageDetResult>> pImageDetResultList; // 检测结果的完整信息
std::vector<std::string> LogList;
int nNotDetCount; // 未检测计数。 当计算超过阈值时,直接不检测,返回结果。
cv::Rect markLine_Roi_X;
cv::Rect markLine_Roi_Y;
std::mutex mtx_Det; // 互斥量
Camera_Check_Result()
{
Init();
}
void Init()
{
camera_info.Init();
checkResultStatus = Check_Result_Status_NoDet;
nresult = 0;
checkStep = Check_Step_NODet;
cameraImage_Status.Init();
errorInfo.Init();
strSN = "";
AddImgStatus = 0;
detImgStatus = 0;
L255ImgStatus = 0;
bDet_Edge = false;
bDet_Zf = false;
bDet_Up = false;
bhaveDPImg = false;
bHaveUPImg = false;
nDet_DP = 0;
detMode = DET_MODE_Det;
CutRoi = cv::Rect(0, 0, 0, 0);
if (!Edge_maskImg.empty())
{
Edge_maskImg.release();
}
if (!Up_MaskImg.empty())
{
Up_MaskImg.release();
}
if (!DP_MaskImg.empty())
{
DP_MaskImg.release();
}
if (!sheildImg.empty())
{
sheildImg.release();
}
if (!edge_SheildImg.empty())
{
edge_SheildImg.release();
}
LogList.clear();
LogList.shrink_to_fit();
markLine_Roi_X = cv::Rect(0, 0, 0, 0);
markLine_Roi_Y = cv::Rect(0, 0, 0, 0);
nNotDetCount = 0;
}
// 设置状态和结果
void Set_Det_Step_Result(Check_Step checkStatus, Check_Result_Status checkResultStatus)
{
this->checkStep = checkStatus;
this->checkResultStatus = checkResultStatus;
}
void AddLog(std::string str)
{
LogList.push_back(str);
}
};
// 产品检测结果
struct Product_Check_Result
{
int nresult; // 检测结果
Check_Step checkStatus; // 检测状态
std::string strSN; // 产品SN号。
ErrorInfo errorInfo; // 错误情况
std::vector<std::shared_ptr<Camera_Check_Result>> cameraCheckResults; // 每个通道的检测结果 ,返回的结果。
std::vector<std::string> LogList;
bool bIsImgComplete; // 图片是否都送完了。
Product_Check_Result()
{
Init();
}
void Init()
{
checkStatus = Check_Step_NODet;
nresult = 0;
strSN = "";
errorInfo.Init();
cameraCheckResults.erase(cameraCheckResults.begin(), cameraCheckResults.end());
cameraCheckResults.clear();
LogList.clear();
LogList.shrink_to_fit();
bIsImgComplete = false;
}
// 创建相应的相机检测结果
std::shared_ptr<Camera_Check_Result> CreateCameraCheckResult(std::string strcameraName)
{
std::shared_ptr<Camera_Check_Result> tem;
tem = GetCameraCheckResult(strcameraName);
if (tem == nullptr)
{
tem = std::make_shared<Camera_Check_Result>();
tem->camera_info.camera_name = strcameraName;
cameraCheckResults.push_back(tem);
}
return tem;
}
std::shared_ptr<Camera_Check_Result> GetCameraCheckResult(std::string strcameraName)
{
if (cameraCheckResults.size() <= 0)
{
return nullptr;
}
for (int i = 0; i < cameraCheckResults.size(); i++)
{
if (cameraCheckResults[i]->camera_info.camera_name == strcameraName)
{
return cameraCheckResults[i];
}
}
return nullptr;
}
void AddLog(std::string str)
{
LogList.push_back(str);
}
};
#endif

@ -0,0 +1,68 @@
/*
//图片基本处理
*/
#ifndef DrawImgl_H_
#define DrawImg_H_
#include <vector>
#include <thread>
#include "ImgCheckConfig.h"
#include "JsonCoversion.h"
#include <stdio.h>
#include "ImageDetConfig.h"
using namespace std;
class DrawImg
{
public:
enum Draw_Type
{
Draw_Type_YS,
Draw_Type_NG,
Draw_Type_Other,
};
public:
DrawImg();
~DrawImg();
int DrawResult(std::shared_ptr<CheckResult> &result);
int DrawInfoImg(cv::Mat &img, cv::Rect roi, int blobidx, int type, float fArea, float fenerge, float fmaxv, float fhj, float flen, Draw_Type drayType, std::string strqx_error, std::string strqx_code, int qx_type, int qx_num, float mindis, bool bqxroi = false);
int DrawInfoImg_Src(cv::Mat &img, cv::Rect roi, int blobidx, int type, float fArea, float fenerge, float fmaxv, float fhj, float flen, Draw_Type drayType, std::string strqx_error, std::string strqx_code, int qx_type, int qx_num, float mindis, bool bqxroi = false);
int preDealImg(cv::Mat &srcimg, cv::Mat &image_resize, bool bfilpSrcImg = true);
int DrawPointList(cv::Mat &image_draw, std::vector<cv::Point> plist);
bool bdraw(cv::Rect roi);
public:
int font_face = cv::FONT_HERSHEY_SIMPLEX;
double font_scale = 0.5;
int thickness = 1;
bool m_bstatus_ReJson;
cv::Scalar Color_Brightness_roi = cv::Scalar(0, 255, 0);
cv::Scalar Color_Brightness_text = cv::Scalar(0, 255, 0);
cv::Scalar DrawBlobErrorCorleList[ERROR_TYPE_COUNT];
std::vector<cv::Rect> m_drawList;
private:
};
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,60 @@
/*
//图片基本处理
*/
#ifndef EdgeDet_H_
#define EdgeDet_H_
#include <opencv2/opencv.hpp>
#include "AI_Edge_Algin.h"
using namespace std;
enum LINE_SEARCH_DIRECTION_CONST
{
DIRECTION_POSITIVE = 1,
DIRECTION_NEGATIVE = -1,
};
class EdgeDet_New
{
public:
EdgeDet_New();
~EdgeDet_New();
int InitRun();
int InitModel();
int GetImgEdge(cv::Mat img, cv::Rect &roi);
int AIEdgeDete(const cv::Mat &img, AI_Edge_Algin::DetConfig *pdetConfig, cv::Mat &detMaskImg, cv::Rect &roi);
cv::Mat showimg;
bool bshowimg;
AI_IMG_deal m_AIDeal;
OtherDet_Config m_OtherDet_Config;
// std::shared_ptr<AI_Edge_Algin> m_pAI_Edge_Algin; // 边缘定位
AI_Edge_Algin m_pAI_Edge_Algin;
cv::Mat detmask;
private:
/// @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,46 @@
#ifndef ImageDetBase_H_
#define ImageDetBase_H_
#include <string>
#include <memory>
#define INTERFACE_Det_VERSION 4
/*******************一般调用流程*************************************************************************************************************************/
/*******************1、初始化 UpdateConfig*************************************************************************************************************************/
/*******************2、初始化 Init 并开启 *************************************************************************************************************************/
/*******************3、GetStatus 获取状态 如果 =CHECK_THREAD_STATUS_IDLE 可以设置检测数据并开启检测 SetDataRun***************************************************/
/*******************4、GetStatus 获取状态 如果 =CHECK_THREAD_STATUS_COMPLETE 检测完成,可以获取检测结果 GetCheckReuslt 拷贝检测结果 自动把状态设为 CHECK_THREAD_STATUS_IDLE*****************************/
struct ImageDetconfig;
struct ImageDetResult;
class ImgCheckBase
{
protected:
ImgCheckBase() {}
public:
// delete camera interface
~ImgCheckBase() {}
static ImgCheckBase *GetInstance();
// 初始化参数 pconfig 参数指针 返回0 成功 其他异常
virtual int RunStart(void *pconfig1 = NULL) = 0;
// 设置检测数据,并开启检测 返回0 成功 其他异常
virtual int SetDataRun_SharePtr(std::shared_ptr<ImageDetconfig> p) = 0;
// 获取结果信息 返回0 成功 其他异常
virtual int GetCheckReuslt(std::shared_ptr<ImageDetResult> &pResult) = 0;
virtual int CheckImg(std::shared_ptr<ImageDetconfig> p, std::shared_ptr<ImageDetResult> &pResult) = 0;
virtual int ReJsonResul(std::shared_ptr<ImageDetconfig> p, std::shared_ptr<ImageDetResult> &pResult) = 0;
// 获取检测库 状态信息 返回CHECK_THREAD_RUN_STATUS
virtual int GetStatus() = 0;
// 更新参数 pconfig 参数指针nConfigType 需要更新的参数类型 返回0 成功 其他异常
virtual int UpdateConfig(void *pconfig, int nConfigType) = 0;
// 返回检测版本信息
virtual std::string GetVersion() = 0;
// 返回错误信息
virtual std::string GetErrorInfo() = 0;
};
#endif

@ -0,0 +1,344 @@
#ifndef _ImageDetConfig_HPP_
#define _ImageDetConfig_HPP_
#include <string>
#include <opencv2/opencv.hpp>
#include "ImgCheckConfig.h"
// 缺陷结果信息
struct QX_ERROR_INFO_
{
int Idx;
int result;
std::string result_name;
cv::Rect roi;
int area;
int energy;
float JudgArea;
float JudgArea_second;
float flen;
int nconfig_qx_type;
std::string qx_name;
int maxValue;
float grayDis;
float fUpIou;
float density; // Blob- 密度
bool bIsStandardLD; // 是否通过LD标准判定跳过UP/DP的IOU检查
std::vector<std::string> detLogList; // 检测日志
QX_ERROR_INFO_()
{
Init();
}
~QX_ERROR_INFO_()
{
}
void Init()
{
Idx = 0;
area = 0;
energy = 0;
JudgArea = 0;
JudgArea_second = 0;
flen = 0;
nconfig_qx_type = 0;
qx_name = "";
maxValue = 0;
grayDis = 0;
fUpIou = 0;
result = 0;
result_name = "OK";
density = 0;
bIsStandardLD = false;
cv::Rect roi = cv::Rect(0, 0, 0, 0);
detLogList.erase(detLogList.begin(), detLogList.end());
detLogList.clear();
}
void print(std::string str = "")
{
std::cout << str << ": "
<< "Idx: " << Idx
<< ", Result: " << result << " " << result_name
<< ", ROI: (" << roi.x << ", " << roi.y << ", " << roi.width << ", " << roi.height << ")"
<< ", Area: " << area
<< ", Energy: " << energy
<< ", JudgArea: " << JudgArea
<< ", JudgArea second: " << JudgArea_second
<< ", density: " << density
<< ", Flen: " << flen
<< ", nconfig_qx_type: " << nconfig_qx_type
<< ", QX Name: " << qx_name
<< ", Max Value: " << maxValue
<< ", Gray Dis: " << grayDis
<< ", fUpIou: " << fUpIou
<< std::endl;
}
};
struct One_Image_CheckResult_
{
cv::Rect CutRoi; // 当前检测图片 对应的裁切区域
cv::Rect Param_CropRoi; // 参数模版 对应的裁切区域
std::shared_ptr<std::vector<QX_ERROR_INFO_>> pQx_ErrorList; // 缺陷错误信息
void print(std::string str = "")
{
std::cout << str << ": "
<< " CutRoi: (" << CutRoi.x << ", " << CutRoi.y << ", " << CutRoi.width << ", " << CutRoi.height << ")"
<< std::endl;
std::cout << str << ": "
<< " Param_CropRoi: (" << Param_CropRoi.x << ", " << Param_CropRoi.y << ", " << Param_CropRoi.width << ", " << Param_CropRoi.height << ")"
<< std::endl;
for (int i = 0; i < pQx_ErrorList->size(); i++)
{
pQx_ErrorList->at(i).print(std::to_string(i));
}
}
};
// 定位结果
struct Align_Result
{
bool bDet; // 检测状态 true 成功false 失败。
bool bUse; // 是否要使用。
bool bDraw; // 是否绘制
cv::Point bestMatch;
int offt_x; // 偏移值
int offt_y; // 偏移值
float fCropROI_Scale_ParmToDet_X; // 裁剪区域的缩放
float fCropROI_Scale_ParmToDet_Y; // 裁剪区域的缩放
std::vector<cv::Point> feature_PointList_DetImg; // 特征区域点 检查图上的特征点
cv::Rect Crop_Roi_DetImg; // 检测图片上的 裁切区域
cv::Rect Crop_Roi_ParmImg; // 参数图片上的 裁切区域
Align_Result()
{
Init();
}
void Init()
{
bDet = false;
bUse = false;
offt_x = 0;
offt_y = 0;
bestMatch = cv::Point(0, 0);
fCropROI_Scale_ParmToDet_X = 1;
fCropROI_Scale_ParmToDet_Y = 1;
feature_PointList_DetImg.clear();
Crop_Roi_DetImg = cv::Rect(0, 0, 0, 0);
Crop_Roi_ParmImg = cv::Rect(0, 0, 0, 0);
bDraw = false;
}
void copy(Align_Result tem)
{
this->bDet = tem.bDet;
this->bUse = tem.bUse;
this->offt_x = tem.offt_x;
this->offt_y = tem.offt_y;
this->fCropROI_Scale_ParmToDet_X = tem.fCropROI_Scale_ParmToDet_X;
this->fCropROI_Scale_ParmToDet_Y = tem.fCropROI_Scale_ParmToDet_Y;
this->bDraw = tem.bDraw;
this->bestMatch = tem.bestMatch;
this->Crop_Roi_DetImg = tem.Crop_Roi_DetImg;
this->Crop_Roi_ParmImg = tem.Crop_Roi_ParmImg;
this->feature_PointList_DetImg.assign(tem.feature_PointList_DetImg.begin(), tem.feature_PointList_DetImg.end());
}
// 从检测图的原始图片 映射到 参数的原始图
cv::Point Det_srcToParm_src_Point(cv::Point &p)
{
cv::Point dst_p;
dst_p.x = (p.x - offt_x) / fCropROI_Scale_ParmToDet_X;
dst_p.y = (p.y - offt_y) / fCropROI_Scale_ParmToDet_Y;
return dst_p;
}
cv::Rect Det_srcToParm_src_Rect(cv::Rect &roi)
{
cv::Rect dst_roi;
cv::Point src_pl = cv::Point(roi.x, roi.y);
cv::Point src_rb = cv::Point(roi.x + roi.width, roi.y + roi.height);
cv::Point p_lt = Det_srcToParm_src_Point(src_pl);
cv::Point p_rb = Det_srcToParm_src_Point(src_rb);
dst_roi.x = p_lt.x;
dst_roi.y = p_lt.y;
dst_roi.width = p_rb.x - p_lt.x;
dst_roi.height = p_rb.y - p_lt.y;
return dst_roi;
}
// 参数的原始图 映射到 检测图的原始图片
cv::Point Parm_srcToDet_src_Point(cv::Point &p)
{
cv::Point dst_p;
dst_p.x = p.x * fCropROI_Scale_ParmToDet_X + offt_x;
dst_p.y = p.y * fCropROI_Scale_ParmToDet_Y + offt_y;
return dst_p;
}
cv::Rect Parm_srcToDet_src_Rect(cv::Rect &roi)
{
cv::Rect dst_roi;
cv::Point src_pl = cv::Point(roi.x, roi.y);
cv::Point src_rb = cv::Point(roi.x + roi.width, roi.y + roi.height);
cv::Point p_lt = Parm_srcToDet_src_Point(src_pl);
cv::Point p_rb = Parm_srcToDet_src_Point(src_rb);
dst_roi.x = p_lt.x;
dst_roi.y = p_lt.y;
dst_roi.width = p_rb.x - p_lt.x;
dst_roi.height = p_rb.y - p_lt.y;
return dst_roi;
}
// 参数图片上的点 对应到 检测裁切后上的点
cv::Point Parm_srcToDet_Crop_Point(cv::Point &p)
{
cv::Point dst_p = Parm_srcToDet_src_Point(p);
dst_p.x -= Crop_Roi_DetImg.x;
dst_p.y -= Crop_Roi_DetImg.y;
return dst_p;
}
// 参数图片上的点 对应到 检测裁切后上的点
cv::Rect Parm_srcToDet_Crop_Rect(cv::Rect &roi)
{
cv::Rect dst_roi;
cv::Point src_pl = cv::Point(roi.x, roi.y);
cv::Point src_rb = cv::Point(roi.x + roi.width, roi.y + roi.height);
cv::Point p_lt = Parm_srcToDet_Crop_Point(src_pl);
cv::Point p_rb = Parm_srcToDet_Crop_Point(src_rb);
dst_roi.x = p_lt.x;
dst_roi.y = p_lt.y;
dst_roi.width = p_rb.x - p_lt.x;
dst_roi.height = p_rb.y - p_lt.y;
return dst_roi;
}
void CalOfftScal()
{
cv::Point src_pl = cv::Point(Crop_Roi_DetImg.x, Crop_Roi_DetImg.y);
cv::Point src_rb = cv::Point(Crop_Roi_DetImg.x + Crop_Roi_DetImg.width, Crop_Roi_DetImg.y + Crop_Roi_DetImg.height);
cv::Point param_pl = cv::Point(Crop_Roi_ParmImg.x, Crop_Roi_ParmImg.y);
cv::Point param_rb = cv::Point(Crop_Roi_ParmImg.x + Crop_Roi_ParmImg.width, Crop_Roi_ParmImg.y + Crop_Roi_ParmImg.height);
int a_x_1 = src_pl.x;
int a_x_2 = src_rb.x;
int b_x_1 = param_pl.x;
int b_x_2 = param_rb.x;
int diff_a_x = a_x_1 - a_x_2;
int diff_b_x = b_x_1 - b_x_2;
float fscale_x = 1;
if (diff_b_x != 0)
{
fscale_x = diff_a_x * 1.0f / diff_b_x;
}
int ofx = a_x_1 - fscale_x * b_x_1;
// printf("a_x_1 %d a_x_2 %d\n", a_x_1, a_x_2);
// printf("b_x_1 %d b_x_2 %d\n", b_x_1, b_x_2);
// printf("fscale_x %f ofx %d \n", fscale_x, ofx);
int a_y_1 = src_pl.y;
int a_y_2 = src_rb.y;
int b_y_1 = param_pl.y;
int b_y_2 = param_rb.y;
int diff_a_y = a_y_1 - a_y_2;
int diff_b_y = b_y_1 - b_y_2;
float fscale_y = 1;
if (diff_b_y != 0)
{
fscale_y = diff_a_y * 1.0f / diff_b_y;
}
int ofy = a_y_1 - fscale_y * b_y_1;
// printf("a_y_1 %d a_y_2 %d\n", a_y_1, a_y_2);
// printf("b_y_1 %d b_y_2 %d\n", b_y_1, b_y_2);
// printf("fscale_y %f ofy %d \n", fscale_y, ofy);
offt_x = ofx;
offt_y = ofy;
fCropROI_Scale_ParmToDet_X = fscale_x;
fCropROI_Scale_ParmToDet_Y = fscale_y;
}
void print()
{
printf("scale x %f y %f ,offt x %d y %d\n", fCropROI_Scale_ParmToDet_X, fCropROI_Scale_ParmToDet_Y, offt_x, offt_y);
}
};
struct ImageDetconfig
{
cv::Mat ShieldMaskImg; // 屏蔽mask
cv::Mat UpMaskImg; // Up 画面 mask图片
cv::Mat DPMaskImg;
cv::Mat edge_maskImg;
bool bUseUpMaskImg;
std::shared_ptr<std::vector<cv::Rect>> pZF_roiList; // 字符的区域
cv::Rect markLine_Roi_X;
cv::Rect markLine_Roi_Y;
std::shared_ptr<shareImage> pBaseImgCheckConfig;
Align_Result alignResult; // 定位结果
ImageDetconfig()
{
Init();
}
~ImageDetconfig()
{
}
void Init()
{
bUseUpMaskImg = false;
if (!ShieldMaskImg.empty())
{
ShieldMaskImg.release();
}
if (!UpMaskImg.empty())
{
UpMaskImg.release();
}
if (!DPMaskImg.empty())
{
DPMaskImg.release();
}
if (!edge_maskImg.empty())
{
edge_maskImg.release();
}
alignResult.Init();
markLine_Roi_X = cv::Rect(0, 0, 0, 0);
markLine_Roi_Y = cv::Rect(0, 0, 0, 0);
}
};
struct ImageDetResult
{
bool bShield_ZF; // 是否要屏蔽字符区域
bool bUseUpImg; // 是否要使用 up img 进行过滤
cv::Mat AI_maskImg;
int Yx_result; // 异显检测状态
float fUP_IOU; // UP 画面 使用的 iou
std::shared_ptr<std::vector<cv::Rect>> pZF_roiList; // 字符的区域
std::shared_ptr<One_Image_CheckResult_> pOneImgDetResult; // 单图检测结果
std::shared_ptr<CheckResult> pBaseImgCheckResult;
ImageDetResult()
{
Init();
}
~ImageDetResult()
{
}
void Init()
{
bShield_ZF = false;
if (!AI_maskImg.empty())
{
AI_maskImg.release();
}
Yx_result = 0;
fUP_IOU = 0;
bUseUpImg = false;
}
};
#endif //_CORELOGICFACTORY_HPP_

@ -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,379 @@
/*
* @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 ImgCheckAnalysisy_H_
#define ImgCheckAnalysisy_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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "BlobBase.h"
#include "AICheck.h"
#include "ImgCheckBase.h"
#include "ImageDetBase.h"
#include "ImgCheckConfig.h"
#include "CheckErrorCodeDefine.hpp"
#include "AIImgDeal.h"
#include "DrawImg.h"
#include "CheckConfigDefine.h"
#include "ConfigBase.h"
#include "ImageDetConfig.h"
#include "QX_Analysis.h"
#include "AIClassify.h"
#include "OtherDetect.h"
#include "AI_Second_Det.h"
#include "Define_Error.h"
using namespace std;
using namespace cv;
enum AT_THRESHOLD_TYPE_
{
AT_THRESHOLD_TYPE_NULL,
AT_THRESHOLD_TYPE_READY,
AT_THRESHOLD_TYPE_BUSY,
AT_THRESHOLD_TYPE_COMPLETE,
};
// 全局静态变量, 记录图像灰度值异常累计数量
static int g_nImgBrightnessErrorCount = 0;
class ImgCheckAnalysisy : public ImgCheckBase
{
public:
ImgCheckAnalysisy();
~ImgCheckAnalysisy();
// 初始化参数 pconfig 参数指针 返回0 成功 其他异常
int RunStart(void *pconfig1);
// 设置检测数据,并开启检测 返回0 成AT_THRESHOLD_TYPE_READY功 其他异常
int SetDataRun_SharePtr(std::shared_ptr<ImageDetconfig> p);
// 获取结果信息 返回0 成功 其他异常
int GetCheckReuslt(std::shared_ptr<ImageDetResult> &pResult);
int CheckImg(std::shared_ptr<ImageDetconfig> p, std::shared_ptr<ImageDetResult> &pResult);
int ReJsonResul(std::shared_ptr<ImageDetconfig> p, std::shared_ptr<ImageDetResult> &pResult);
// 获取检测库 状态信息 返回CHECK_THREAD_RUN_STATUS
int GetStatus();
// 更新参数 pconfig 参数指针nConfigType 需要更新的参数类型 返回0 成功 其他异常
int UpdateConfig(void *pconfig, int nConfigType);
std::string GetVersion();
std::string GetErrorInfo();
private:
// 加载运行参数
int LoadRunConfig(void *p);
// 加载分析参数
int LoadCheckConfig(void *p);
/// @brief 初始化并且启动程序
/// @return
int InitRun(int nId);
/// @brief 开启检测
/// @return
int StartCheck();
/// @brief 设置空闲
/// @return
int SetIDLE();
private:
// 开启线程
int StartThread(int nId);
// 停止线程
int StopThread();
// 退出系统
int ExitSystem();
// 初始化模型
int InitModel();
int InitModel_NF();
int InitModel_YX();
int InitModel_Clas();
int InitModel_ZF();
int InitModel_Up();
int InitModel_127Cell();
// 检测
int CheckRun();
// 设置新的检测参数
int SetNewConfig();
int GetParamidx();
// 增加检测日志
int AddCheckLog(int nlevel, std::string str);
int GetRegionIdx(int x, int y);
ChannelCheckFunction *GetChannelFuntion(std::string strChannelName); // 获得 通道的检测功能
private:
// 图片处理线程
std::shared_ptr<std::thread> ptr_thread_Run;
int Run(int nId); // 运行;
// 图片处理线程
std::shared_ptr<std::thread> ptr_thread_AI;
int set_cpu_id(const std::vector<int> &cpu_set_vec);
int saveAIImg();
int AnalysisResult_New();
int AnalysisResult_Qx();
int AnalysisResult_Param_Judge();
int AnalysisResult_Pre(QX_ERROR_INFO_ *pQX_info, std::string strChannel); // 弱化处理
int AI_Det(cv::Mat inImg, cv::Mat &outimg);
// 利用Up 画面过滤
float UseUpMaskAnalysis(cv::Rect teroi, cv::Mat AIMaskImg);
float CalImgScorl(cv::Mat det_img, cv::Mat up_img);
float CalImgScorl_t(cv::Mat det_img, cv::Mat up_img);
// 分类
int AI_Classify(cv::Mat img, cv::Rect qx_roi, float fjustarea, float *fmaxScore);
// 多区域分类
int AI_Classify_New(const cv::Mat &src_Img, cv::Rect qx_roi, float fjustarea, float *fmaxScore);
// 计算缺陷长度
float Cal_QXLen(cv::Mat qx_maskImg, int qx_type, float fsc_x, float fsc_y);
// 启动AI处理
int StartAIDeal();
// 等待AIdeal完成
int waitImgAIDealEnd();
void waitAIData();
// 二次计算缺陷面积
int ReCalQX_AreaAndLen(AI_SecondDet::DetConfigResult *pdetConfig);
// 检测结果分析
int CheckAnalysisResult();
// BLob分析
int BlobAnalysis_new();
int CalBLobMean_GrayDis();
int CalBLobMean_GrayDis_127Cell();
// 计算blob的密度
int CalBlobDensity();
int CalBlobDensity_QX();
// 轮廓处理
int Contours();
// 轮廓处理
int Contours_New(cv::Mat mask);
cv::Rect GetCutRoi(cv::Rect roi, cv::Mat img);
cv::Rect GetREAIRoi(cv::Rect roi, cv::Mat img);
// 异显检测
int AI_Det_YX(cv::Mat cropImg);
// 检测初始化
int CheckImgInit();
// 参数 核对
int ConfigCheck(cv::Mat img);
// 多线程方式处理
int AI_Detect_Thread(cv::Mat img, cv::Mat &ResultImg);
// 多线程处理,获取小图 序号。
int Multi_Thread_GetSmallImgIdx(int ntype);
// 多线程处理,设置资源状态
int Multi_Thread_SetSmallType(int idx, int ntype);
// AI 后处理
int Multi_Thread_AIResultDet(cv::Mat &resultImg, int idx);
// AI预处理图片
int AI_PreImg(cv::Mat img, cv::Mat &AI_DealImg);
int ThreadAI(int nId); // 运行;
// resize 图片
int ResizeImg();
// 更新 检测区域
int Update_DetRoiList();
// 绘制结果
int DrawResult();
// 对127重复检测
int ReCheck127Cell(const cv::Mat &DetImage);
// 把检查结果转成json
int DetResultToJson();
int DrawOther();
// 创建mask
int CreateMaskImg();
int SetInDetConfig();
// 更新亮点参数
int UPdateLDConfig();
// 添加检测结果
int AddQXResult(cv::Rect qx_roi_src, cv::Rect qx_roi_resize, int qx_type, float fJudgArea, float fenergy, float fgrayDis, cv::Mat YX_AI_InImg, cv::Mat YX_AI_OUTImg);
// 参数缺陷类型转 结果参数类型
int AIClassTypeToConfigType(int nAIQXType, cv::Rect qx_roi);
// 参数缺陷类型转 结果参数类型
int ConfigTypeToResultType(int nconfigType);
int ConfigTypeToQXAnalysis(int nconfigType);
// 判断是否是点状缺陷
bool IsPointQX(int config_qx_tpe);
// 解析 指令
int GetInstruct(int nInstruct);
int GetZfCropMask(cv::Rect roi);
int ZF_Check(cv::Mat img, cv::Mat &inImg, cv::Mat &maskimg);
int YX_Check_L255(cv::Mat cropImg, cv::Mat &inImg, cv::Mat &outmaskimg);
// 使用 DP mask 进行二次判断
int UseDPMask(int L0, int nconfigtype, cv::Rect roi, float JudgeArea, int maxV, int hj);
// 检测有效区域mask图片
int GetDetMaskImg(cv::Mat img, cv::Rect cutroi);
// 亮的判断
int LDJudge(int nconfigtype, cv::Rect roi, float JudgeArea, int maxV, int hj);
// 获取缺陷 对应的AI输入 输出图片,
int GetAIDetImg(cv::Rect Qx_roi, cv::Mat &AI_InImg, cv::Mat &AI_OutImg);
int GetUpMaskImg(cv::Mat inImg, cv::Mat &maskimg);
// 更新成像精度
int UpdateImgageScale(const cv::Mat &srcimg);
// 更新屏蔽区域
int UpdateSheildMask(std::string strChannel, cv::Rect roi);
// 缺陷是否要进行检测分析 缺陷是参数类型的缺陷
bool JudgeQXAnalysis(int nqx_configType);
// 缺陷是否要进行检测分析 缺陷是参数类型的缺陷
bool Judge_MarkLine_QX(int nqx_configType,cv::Rect detqx_Roi);
// AI 检测的缺陷类型,转换成 web 控制 是否要分析检测的缺陷类型
std::string ConfigTypeToWebDetType(int nconfigType);
// 增加到 绘制区域
int addInDrawBlob(int errortype, int blobidx, ERROR_DOTS_BLOB_DATA *blob, float fs_resize_x, float fs_resize_y);
int addInDrawBlob_New(int errortype, int blobidx, QX_ERROR_INFO_ *QX_info, float fs_resize_x, float fs_resize_y);
// 初始化其他检测类
int InitOtherDet();
// 其他类的检测
int OtherDetect();
// 缺失pol检测
int Detect_LackPol(const cv::Mat &DetImage);
// 精确计算缺陷能量(基于像素灰度差)
cv::Scalar calc_blob_info_withstats(cv::Mat &img, const cv::Mat &mask, cv::Rect &stats, cv::Size k_size = cv::Size(5, 5), int expand = 10, double threshold = 0.7);
private:
int m_nErrorCode; // 错误代码
bool m_bInitSucc; // 初始化状态
bool m_bExit; // 是否退出检测
int m_nThreadIdx; // 线程序号 //相机处理的顺序号,该序号 程序运行就已经固定
std::shared_ptr<shareImage> DetImgInfo_shareP;
std::shared_ptr<ImageDetconfig> ImageDet_shareP;
// 检测结果
std::shared_ptr<CheckResult> m_CheckResult_shareP;
std::shared_ptr<ImageDetResult> m_ImageDetResult_shareP;
// 检测参数模块
ConfigBase *m_pConfig;
// 线程运行的一些参数
RunInfoST m_RunConfig;
// 检测结果
// CheckResult m_CheckResult;
// 基本信息和深度学习模型文件参数
CheckConfigST m_CheckConfig;
float m_fImgage_Scale_X;
float m_fImgage_Scale_Y;
// 分析参数
AnalysisyConfigST m_AnalysisyConfig;
ChannelCheckFunction *m_pFuntion;
BaseCheckFunction *m_pbaseCheckFunction; // 基础检测
CommonConfigNodeST *m_pCommonAnalysisyConfig;
BasicConfig *m_pBasicConfig;
RegionConfigST *m_pRegionAnalysisyParam; // 分析参数
int m_QxInParamListIdx[CONFIG_QX_NAME_count];
cv::Mat m_AnalysisyMaskImg; // 分析的mask
cv::Rect m_CutRoi;
cv::Rect m_Crop_Roi_paramImg; // 裁切在参数模板图上的 位置。
bool m_bShield_ZF; // 屏蔽字符检测
// // 检测控制参数
// CheckControlConfigSt *m_pcheckControlConfig;
int m_nRun_Status; // 运行状态:空闲,运行中,异常,。。。。。
int m_nCheckResultErrorCode;
AI_IMG_deal m_AIDeal;
CHECK_TEM_RESULT m_TemCheck;
Detect_ROI_Config m_DetRoiList; // 检测区域roi List
ERROR_DOTS_BLOBS blobs;
ERROR_DOTS_BLOBS blobs_127;
std::mutex mutex_AIDeal; // AI处理互斥锁
std::condition_variable condVar_AI; // 条件变量
int m_nWaite_AIDeal_SmallImg_Num; // 等待AI处理多线程状态 小图数目
int m_nWaite_AIComplete_SmallImg_Num; // AI处理完成 等待 后处理的小图数目
// 小图资源
// SMALLIMGINFO Multi_Thread_DetSmallImgList[MAX_THREAD_AIDET_NUM];
SMALLIMGINFO Multi_Thread_DetSmallImgList[MAX_THREAD_AIDET_NUM];
std::vector<SMALLIMGINFO> AI_DetImgList;
std::mutex mutex_SmallImgList; // 小图资源锁
OtherCheckResult m_OtherResult;
DrawImg m_DrawImg;
CHECK_INSTRUCT_ m_CheckInstruct; // 检测指令
std::vector<cv::Point> m_ZF_centerPoint; // 字符的中心点位置
cv::Rect m_Cut_roi; // 裁剪区域
int m_curLogLevel; // 当前日志等级
cv::Mat m_DetImgMask; // 检测有效区域mask图片
cv::Mat m_ShieldImg_resize;
QX_Analysis m_qx_Analysis;
LD_ConfigT_ m_LDConfig;
LD_ConfigT_ m_LD_WTBConfig;
LD_ConfigT_ m_LD_HSConfig;
AIClassify m_AIClassify; // 缺陷分类
DetResultST m_DetResult; // 检测结果
OtherDet_Config m_OtherDet_Config;
LackPolDet m_LackPolDet; // 缺Pol 检测;
AI_SecondDet m_SecondDet; // 二次分割检测
std::vector<QXImageResult> m_Draw_qxImageResult; // 缺陷小图结果
std::vector<cv::Rect> SmallRoiList;
int det_SmallImgNum;
cv::Mat m_127CellAIMask;
bool m_bstatus_ReJson;
CheckResultJson m_CheckResultJson;
};
#endif

@ -0,0 +1,94 @@
#ifndef ImgCheckBase_H_
#define ImgCheckBase_H_
#include <string>
#include <memory>
#define ALL_INTERFACE_VERSION 4
enum CHECK_THREAD_RUN_STATUS
{
CHECK_THREAD_STATUS_IDLE, // 空闲 0
CHECK_THREAD_STATUS_READY, // 准备好了 1
CHECK_THREAD_STATUS_BUSY, // 运行中 2
CHECK_THREAD_STATUS_COMPLETE, // 检测完成 3
CHECK_THREAD_STATUS_ERROR, // 运行错误 4
};
struct RunInfoST
{
int nThreadIdx; // 线程号id
int nDeviceId; // GPU 设备 号 0 或 1
int nCpu_start_Idx; // 绑定cpu 核号,
int nCpu_num; // 8 至少需要 8个
bool bSaveCheckImg; // 是否存储
bool bRetest; // 是否是复测标志,复测不需要加载模型
int flag1;
int flag2;
std::string str1;
std::string str2;
RunInfoST()
{
nThreadIdx = 0;
nDeviceId = 0;
nCpu_start_Idx = 0;
nCpu_num = 8;
flag1 = 0;
flag2 = 0;
bRetest = false;
str1 = "";
str2 = "";
bSaveCheckImg = false;
}
void copy(RunInfoST tem)
{
this->nDeviceId = tem.nDeviceId;
this->nThreadIdx = tem.nThreadIdx;
this->nCpu_start_Idx = tem.nCpu_start_Idx;
this->nCpu_num = tem.nCpu_num;
this->bSaveCheckImg = tem.bSaveCheckImg;
this->flag1 = tem.flag1;
this->flag2 = tem.flag2;
this->bRetest = tem.bRetest;
this->str1 = tem.str1;
this->str2 = tem.str2;
}
};
/*******************一般调用流程*************************************************************************************************************************/
/*******************1、初始化 UpdateConfig*************************************************************************************************************************/
/*******************2、初始化 Init 并开启 *************************************************************************************************************************/
/*******************3、GetStatus 获取状态 如果 =CHECK_THREAD_STATUS_IDLE 可以设置检测数据并开启检测 SetDataRun***************************************************/
/*******************4、GetStatus 获取状态 如果 =CHECK_THREAD_STATUS_COMPLETE 检测完成,可以获取检测结果 GetCheckReuslt 拷贝检测结果 自动把状态设为 CHECK_THREAD_STATUS_IDLE*****************************/
struct shareImage;
struct CheckResult;
class ALLImgCheckBase
{
protected:
ALLImgCheckBase() {}
public:
// delete camera interface
~ALLImgCheckBase() {}
static ALLImgCheckBase *GetInstance();
// 初始化参数 pconfig 参数指针 返回0 成功 其他异常
virtual int RunStart(void *pconfig1 = NULL) = 0;
// 设置检测数据,并开启检测 返回0 成功 其他异常
virtual int SetDataRun_SharePtr(std::shared_ptr<shareImage> p) = 0;
// 获取结果信息 返回0 成功 其他异常
virtual int GetCheckReuslt(std::shared_ptr<CheckResult> &pResult) = 0;
virtual int CheckImg(std::shared_ptr<shareImage> p, std::shared_ptr<CheckResult> &pResult) = 0;
// 获取检测库 状态信息 返回CHECK_THREAD_RUN_STATUS
virtual int GetStatus() = 0;
// 更新参数 pconfig 参数指针nConfigType 需要更新的参数类型 返回0 成功 其他异常
virtual int UpdateConfig(void *pconfig, int nConfigType) = 0;
// 返回检测版本信息
virtual std::string GetVersion() = 0;
// 返回错误信息
virtual std::string GetErrorInfo() = 0;
static ALLImgCheckBase *instance;
};
#endif

@ -0,0 +1,652 @@
/*
* @Descripttion:
* @version:
* @Author: sueRimn
* @Date: 2022-03-16 17:09:11
* @LastEditors: xiewenji 527774126@qq.com
* @LastEditTime: 2025-07-26 11:21:59
*/
/***********************************************/
/************ ***************/
/************金佰利检测算法参数定义**************/
/************ **************/
/**********************************************/
#ifndef _ImgCheckConfig_HPP_
#define _ImgCheckConfig_HPP_
#include <string>
#include <opencv2/opencv.hpp>
#define RESULT_VERSION 26
#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_CHESS,
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",
"Chess"};
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",
"P8002",
};
// 检测检测参数类型
enum CHECK_CONFIG_TYPE_
{
CHECK_CONFIG_Run, // 运行参数
CHECK_CONFIG_Module, // 参数模块
CHECK_CONFIG_Module_Cam2, // 参数模块 相机2参数
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_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;
int camera_ID; // 相机ID
std::string camera_Name; // 相机名称
int img_id;
cv::Mat img;
cv::Mat other_channel_Result_mask; // 其他通道的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 img_channel; // 图片通道号
int ninstruct; // 运行指令
int nlogLevel; // 日志等级
std::string imgstr;
std::string strImgName;
std::string strImgProductID;
std::string strImgType;
std::string strChannel;
int nImgBigIdx;
int otherValue;
int otherValue_1;
std::string resultJson;
bool bsaveProcessImg; // 保存处理图片
shareImage()
{
Init();
}
~shareImage()
{
}
void Init()
{
if (!img.empty())
{
img.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 = "";
strImgProductID = "";
strChannel = "";
strImgType = "";
nImgBigIdx = 0;
cutRoi = cv::Rect(0, 0, 0, 0);
otherValue = 0;
ninstruct = 0;
img_channel = 0;
resultJson = "";
camera_Name = "";
bsaveProcessImg = 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);
}
}
};
// AI分析结果
struct JudgeInfo
{
int result = 0;
int positive = 0;
int smudgy = 0;
int abnormal = 0;
int black = 0;
int dot = 0;
int other = 0;
std::string RESULT = "OK";
std::string POSITIVE = "OK"; // 正样本 4
std::string SMUDGY = "OK"; // 脏污 3 R通道
std::string ABNORMAL = "OK"; // zhansi 毛发 2 B通道
std::string BLACK = "OK"; // 黑接头 1
std::string DOT = "OK"; // 黑点 1
std::string OTHER = "OK"; // 其他 1
void Init()
{
result = 0;
positive = 0;
smudgy = 0;
abnormal = 0;
black = 0;
dot = 0;
other = 0;
RESULT = "OK";
POSITIVE = "OK";
SMUDGY = "OK";
ABNORMAL = "OK";
BLACK = "OK";
DOT = "OK";
OTHER = "OK";
}
void copy(JudgeInfo tem)
{
this->result = tem.result;
this->positive = tem.positive;
this->smudgy = tem.smudgy;
this->abnormal = tem.abnormal;
this->black = tem.black;
this->dot = tem.dot;
this->RESULT = tem.RESULT;
this->POSITIVE = tem.POSITIVE;
this->SMUDGY = tem.SMUDGY;
this->ABNORMAL = tem.ABNORMAL;
this->BLACK = tem.BLACK;
this->DOT = tem.DOT;
}
};
// 检测结果基本信息
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;
}
};
// 缺陷blob信息
struct BLobST
{
cv::Rect blob;
cv::Rect blob_ResizeImg;
cv::Rect blob_SrcImg;
int energy;
int area;
float JudgArea;
int UserErrorType;
BLobST()
{
Init();
}
void Init()
{
blob = cv::Rect(0, 0, 0, 0);
blob_ResizeImg = cv::Rect(0, 0, 0, 0);
blob_SrcImg = cv::Rect(0, 0, 0, 0);
energy = 0;
area = 0;
JudgArea = 0;
UserErrorType = ERROR_TYPE_OK;
}
void copy(BLobST tem)
{
this->blob = tem.blob;
this->blob_ResizeImg = tem.blob_ResizeImg;
this->blob_SrcImg = tem.blob_SrcImg;
this->energy = tem.energy;
this->area = tem.area;
this->JudgArea = tem.JudgArea;
this->UserErrorType = tem.UserErrorType;
}
};
// 缺陷blob信息
struct BLobListST
{
BLobST bloblist[MAX_BLOB_NUM];
int blobNum;
BLobListST()
{
Init();
}
void Init()
{
blobNum = 0;
for (int i = 0; i < MAX_BLOB_NUM; i++)
{
bloblist[i].Init();
}
}
void copy(BLobListST tem)
{
this->blobNum = tem.blobNum;
for (int i = 0; i < MAX_BLOB_NUM; i++)
{
this->bloblist[i].copy(tem.bloblist[i]);
}
}
};
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;
}
};
#define MAX_SamllImg_xcount 13
#define MAX_SamllImg_ycount 10
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());
}
};
// AI处理后的 结果信息,上传到队列中,做后续风险
struct AI_REUSLTIMG
{
cv::Mat defectImg; // 缺陷检测结果图片
AI_REUSLTIMG()
{
if (!defectImg.empty())
{
defectImg.release();
}
}
~AI_REUSLTIMG()
{
release();
}
void release()
{
if (!defectImg.empty())
{
defectImg.release();
}
}
};
#endif //_CORELOGICFACTORY_HPP_

@ -0,0 +1,39 @@
/*
* @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 OtherDetBaseDefine_H_
#define OtherDetBaseDefine_H_
#include <string>
#include <iostream>
#include "CheckErrorCodeDefine.hpp"
#include "AIImgDeal.h"
#include "BlobBase.h"
using namespace std;
struct OtherDet_Config
{
int nDeviceId; // GPU 号
int nUserValue;
int nShowImg_Width;
int nShowImg_Height;
AI_IMG_deal *pAIDeal;
CHECK_TEM_RESULT *pTemCheck;
OtherDet_Config()
{
pAIDeal = NULL;
pTemCheck = NULL;
nDeviceId = 0;
nUserValue = 0;
nShowImg_Width = 100;
nShowImg_Height = 100;
}
};
#endif

@ -0,0 +1,74 @@
/*
//其他类的检测
*/
#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;
AI_IMG_deal *m_pAIDeal;
CHECK_TEM_RESULT *m_pTemCheck;
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,214 @@
/*
//实现对部分缺陷 需要进行 数量 和距离上分析的
*/
#ifndef QX_Analysis_H_
#define QX_Analysis_H_
#include <opencv2/opencv.hpp>
#include "CheckUtil.hpp"
#include "CheckErrorCodeDefine.hpp"
using namespace std;
enum QX_ANALYSIS_NAME
{
QX_ANALYSIS_POL_CELL, // 异物
QX_ANALYSIS_AD, // 暗点
QX_ANALYSIS_Scratch, // 划伤
QX_ANALYSIS_LINE, // 线类
QX_ANALYSIS_MTX, // MTX
QX_ANALYSIS_ALL, // MTX&异物
QX_ANALYSIS_COUNT,
};
// 缺陷项对应在参数中的名称
static const std::string QX_ANALYSIS_NAME_Names[] =
{
"POL_Cell",
"AD",
"Scratch",
"LINE",
"MTX",
"POL_Cell&MTX"};
// 记录缺陷信息
struct QX_Info
{
float area; // 面积
float energy; // 能量
float hj; // 灰阶
float length; // 长度
float density; // 密度
cv::Point plocatin_mm; // 位置mm
cv::Point plocatin_pixel; // 位置 像素
int blobIdx; // blob idx;
int result;
float fmindis;
int nmindis_BlobIdx;
cv::Point mindis_locatin_pixel; // 位置 像素
int nstatus;
int nqx_type;
QX_Info()
{
Init();
}
void Init()
{
area = 0;
energy = 0;
hj = 0;
length = 0;
plocatin_mm = cv::Point(0, 0);
plocatin_pixel = cv::Point(0, 0);
blobIdx = 0;
result = 0;
fmindis = 0;
mindis_locatin_pixel = cv::Point(0, 0);
nstatus = 0;
nqx_type = 0;
nmindis_BlobIdx = 0;
density = 0;
}
void print(std::string str)
{
printf("%s blobIdx %d,result %d area %f energy %f hj %f length %f md %f x %d y %d x %d y %d \n",
str.c_str(), blobIdx, result, area, energy, hj, length, density, plocatin_mm.x, plocatin_mm.y, plocatin_pixel.x, plocatin_pixel.y);
printf("%s blobIdx %d,fmindis %f mindis_locatin_pixel x %d y %d \n",
str.c_str(), blobIdx, fmindis, mindis_locatin_pixel.x, mindis_locatin_pixel.y);
}
};
struct QX_ALL_List
{
std::vector<QX_Info> qxList;
QX_ALL_List()
{
Init();
}
void Init()
{
qxList.erase(qxList.begin(), qxList.end());
qxList.clear();
// config.Init();
}
};
struct QXAnalysis_Config
{
bool bok;
int num;
float dis;
float len;
int hj;
float density;
float area;
float sum_area;
QXAnalysis_Config()
{
Init();
}
void Init()
{
bok = false;
num = 0;
dis = 0;
len = 0;
area = 0;
hj = 0;
sum_area = 0;
density = 0;
}
void print(std::string str)
{
printf("%s bok %d num %d area %f dis %f len %f hj %d md %f\n", str.c_str(), bok, num, area, dis, len, hj,density);
}
};
struct QX_Config_List
{
std::vector<QXAnalysis_Config> configlsit;
QX_Config_List()
{
Init();
}
void Init()
{
configlsit.erase(configlsit.begin(), configlsit.end());
configlsit.clear();
// config.Init();
}
};
enum QX_ERROR_TYPE_
{
QX_ERROR_TYPE_OK,
QX_ERROR_TYPE_AREA,
QX_ERROR_TYPE_NUM,
QX_ERROR_TYPE_DIS,
QX_ERROR_TYPE_Len,
QX_ERROR_TYPE_NUM_RGB255,
};
struct QX_RESULT
{
int blobIdx; // blob idx;
int error_Type; // 错误原因
int qx_Num; // 缺陷的数量
float mindis;
float flen;
cv::Point qx_MisDis_point_pixel; // 缺陷 间的最小距离
QX_RESULT()
{
Init();
}
void Init()
{
blobIdx = -1;
error_Type = 0;
qx_Num = 0;
flen = 0;
mindis = 0;
qx_MisDis_point_pixel = cv::Point(0, 0);
}
void print(std::string str)
{
printf("%s blobIdx %d error_Type %d qx_Num %d min dis %f flen %f x %d y %d \n",
str.c_str(), blobIdx, error_Type, qx_Num, mindis, flen, qx_MisDis_point_pixel.x, qx_MisDis_point_pixel.y);
}
};
struct QX_Analysis_Result_List
{
std::vector<QX_RESULT> resultList;
QX_Analysis_Result_List()
{
Init();
}
void Init()
{
resultList.erase(resultList.begin(), resultList.end());
resultList.clear();
// config.Init();
}
};
class QX_Analysis
{
private:
QX_ALL_List m_QXList[QX_ANALYSIS_COUNT];
QX_Config_List m_ConfigList[QX_ANALYSIS_COUNT];
QX_Analysis_Result_List m_reultList;
public:
CHECK_TEM_RESULT *m_pTemCheck;
public:
QX_Analysis();
~QX_Analysis();
void SetConfig(int qxidx, QXAnalysis_Config config);
void InitConfig();
bool AddQxInfo(int qxidx, QX_Info qxinfo);
int Init();
int GetReusult(QX_Analysis_Result_List *&presult);
private:
bool Idx(int qxidx);
int Analysis(QX_Config_List *pconfigList, QX_ALL_List *pqxList,int qx_type);
int Analysis_s(QXAnalysis_Config *pconfig, QX_ALL_List *pqxList,int qx_type);
int Analysis_AD_Num(QXAnalysis_Config *pconfig, QX_ALL_List *pqxList,int qx_type);
int Analysis_POL_Num(QXAnalysis_Config *pconfig, QX_ALL_List *pqxList,int qx_type);
};
#endif

@ -0,0 +1,76 @@
/*
* @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 SingleGPU_H_
#define SingleGPU_H_
#include <vector>
#include <thread>
#include <mutex>
#include <string>
#include <iostream>
#include <memory>
#include <opencv2/opencv.hpp>
#include "AICheck.h"
using namespace std;
#define MAX_GPU_NUMBER 4
class AI_SingleGPU
{
public:
AI_SingleGPU(int nGpuIdx);
~AI_SingleGPU();
static AI_SingleGPU *GetInstance(int nGpuIdx);
static AI_SingleGPU *m_pInstance[MAX_GPU_NUMBER];
private:
// 定义一个内部类
class CGarbo
{
public:
CGarbo() {};
~CGarbo()
{
for (int i = 0; i < MAX_GPU_NUMBER; i++)
{
if (nullptr != m_pInstance[i])
{
delete m_pInstance[i];
m_pInstance[i] = nullptr;
}
}
}
};
// 定义一个内部类的静态对象
// 当该对象销毁时顺带就释放myInstance指向的堆区资源
static CGarbo m_garbo;
private:
int m_nGpuIdx;
public:
AI_defect AI_defect_NF; // BOE测试
AI_defect AI_defect_Type2; // 第二个检测模型
AI_defect AI_defect_Cls; // 1023
AI_defect AI_defect_Cls_L0; //
AI_defect AI_defect_YX_1; // L0
AI_defect AI_defect_YX_2; // L127 L255
AI_defect AI_defect_zf; // L127 L255
AI_defect AI_defect_UP; // L127 L255
AI_defect AI_defect_Chess; // L127 L255
AI_defect AI_defect_127Cell; // L127 L255
AI_defect AI_defect_RE_POL; // L127 L255
AI_defect AI_defect_RE_AD; // L127 L255
AI_defect AI_defect_Edge_Big; // L127 L255
AI_defect AI_defect_Edge_Samll; // L127 L255
AI_defect AI_defect_LackPol; // 缺pol检测
AI_defect AI_defect_MarkLine; // MarkLine
};
#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,515 @@
/*
* FileName:CoreLogicFactory.cpp
* Version:V1.0
* Description:
* Created On:Mon Sep 10 11:13:16 UTC 2018
* Modified date:
* Author:Sky
*/
#include "AICheck.h"
#include "CUDA_Det.cuh"
#ifdef USE_TERNSORRT10_BIGMODEL
#include <cassert> // 添加头文件
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <fstream>
#include "CheckUtil.hpp"
#define CHECK(status) \
do \
{ \
auto ret = (status); \
if (ret != 0) \
{ \
std::cerr << "Cuda failure: " << ret << std::endl; \
abort(); \
} \
} while (0)
class Logger : public ILogger
{
void log(Severity severity, const char *msg) noexcept override
{
// suppress info-level messages
if (severity <= Severity::kWARNING)
std::cout << msg << std::endl;
}
} logger;
static Logger gLogger;
#else
#endif
int g_falage = 0;
AI_defect::AI_defect()
{
m_bInitialized = false;
}
AI_defect::~AI_defect()
{
destroy();
}
void AI_defect::destroy()
{
for (int i = 0; i < MAX_AI_BUFFER_SIZE; i++)
{
if (m_config.bufferList[i].ntype == AIBufferType_NULL)
{
break;
}
cudaFree(buffers[i]);
cudaFree(ImgData[i]);
if (floatData)
{
free(floatData);
}
}
// Destroy the engine
#ifdef USE_TERNSORRT10_BIGMODEL
#else
context->destroy();
engine->destroy();
runtime->destroy();
#endif
}
#ifdef USE_TERNSORRT10_BIGMODEL
int AI_defect::model_init(AIInitConfig config)
{
if (m_bInitialized)
{
printf("AI_defect::model_init succ \n");
return 0;
}
if (config.bufferList[0].strName == "")
{
// getchar();
/* code */
}
m_bInitialized = false;
printf("-- AI Init nGpuIdx %d model file %s \n", config.nGpuIdx, config.engine_file_path.c_str());
if (config.nGpuIdx < 0)
{
return 1;
}
if (!config.Checking())
{
printf("Checking error \n");
return 1;
}
m_config.copy(config);
m_config.CalSize(sizeof(float));
cudaSetDevice(m_config.nGpuIdx);
char *trtModelStream{nullptr};
size_t size{0};
std::ifstream file(m_config.engine_file_path, std::ios::binary);
if (!file)
{
std::cerr << "Error opening engine file!" << std::endl;
return 1;
}
if (file.good())
{
std::cout << "load engine success" << std::endl;
file.seekg(0, file.end);
size = file.tellg();
file.seekg(0, file.beg);
trtModelStream = new char[size];
assert(trtModelStream);
file.read(trtModelStream, size);
file.close();
}
else
{
printf("------------Model file open error--********* \n");
return 1;
}
printf("model_init 1 \n");
runtime = createInferRuntime(gLogger);
if (!runtime)
{
std::cerr << "Failed to create runtime!" << std::endl;
return 1;
}
printf("model_init 2 \n");
engine = runtime->deserializeCudaEngine(trtModelStream, size);
if (!engine)
{
std::cerr << "Failed to create engine!" << std::endl;
return 1;
}
printf("model_init 3 \n");
// // Create execution context
context = engine->createExecutionContext();
if (!context)
{
std::cerr << "Failed to create execution context!" << std::endl;
return 1;
}
delete[] trtModelStream;
printf("model_init 4 \n");
// 初始化buffer
for (int i = 0; i < MAX_AI_BUFFER_SIZE; i++)
{
if (m_config.bufferList[i].ntype == AIBufferType_NULL)
{
break;
}
floatData[i] = (float *)malloc(m_config.bufferList[i].ndatalength * sizeof(float));
cudaMalloc(&buffers[i], m_config.bufferList[i].ndataSize);
{
int nsize = m_config.bufferList[i].ndatalength * sizeof(unsigned char);
cudaMalloc(&ImgData[i], nsize);
}
}
m_bInitialized = true;
return 0;
}
int AI_defect::model_Cuda_AI_In_1_Out_1(unsigned char *p_indata_0, unsigned char *p_outdata_1)
{
std::lock_guard<std::mutex> lock(g_mutex);
cudaSetDevice(m_config.nGpuIdx);
cudaStream_t stream;
CHECK(cudaStreamCreate(&stream));
// printf(">>>>>>>>>>>>>>>>>CUDA test m_config.nGpuIdx %d \n", m_config.nGpuIdx);
const ICudaEngine &engine_123 = context->getEngine();
// printf("name %s \n", m_config.bufferList[0].strName.c_str());
// auto s = engine_123.getTensorShape(m_config.bufferList[0].strName.c_str());
// std::cout << "tensor dims: [";
// for (int i = 0; i < s.nbDims; i++)
// {
// std::cout << s.d[i];
// if (i < s.nbDims - 1)
// std::cout << ", ";
// }
// std::cout << "]" << std::endl;
// {
// printf("name %s \n", m_config.bufferList[1].strName.c_str());
// auto s = engine_123.getTensorShape(m_config.bufferList[1].strName.c_str());
// std::cout << "tensor dims: [";
// for (int i = 0; i < s.nbDims; i++)
// {
// std::cout << s.d[i];
// if (i < s.nbDims - 1)
// std::cout << ", ";
// }
// std::cout << "]" << std::endl;
// }
long t1, t2, t3, t4, t5, t6, t7;
// t1 = CheckUtil::getcurTime();
for (int i = 0; i < m_config.bufferList[0].ndatalength; i++)
{
floatData[0][i] = p_indata_0[i];
}
cudaMemcpyAsync(buffers[0], floatData[0], m_config.bufferList[0].ndataSize, cudaMemcpyHostToDevice, stream);
// wrap_test_print();
// 拷贝数据到显卡
// if (kk == 0)
// {
// cudaMemcpyAsync(ImgData[0], p_indata_0, m_config.bufferList[0].nuchardataSize, cudaMemcpyHostToDevice, stream);
// printf("set img************************** m_config.bufferList[0].nuchardataSize %d\n", m_config.bufferList[0].nuchardataSize);
// kk++;
// }
// t2 = CheckUtil::getcurTime();
// // 在显存中 图片数据从 uchar 转到 float
// Cuda_ucharToFloat((unsigned char *)ImgData[0], (float *)buffers[0], m_config.bufferList[0].ndatalength);
// t3 = CheckUtil::getcurTime();
// float *temsssssdata = new float[1024 * 1024];
// cudaMemcpyAsync(temsssssdata, buffers[0], m_config.bufferList[0].ndataSize, cudaMemcpyDeviceToHost, stream);
// for (int i = 0; i < 1024*1024; i = i + 800)
// {
// printf("%d %d %f %d ", i,m_config.bufferList[0].ndatalength, temsssssdata[i],p_indata_0[i]);
// }
// delete [] temsssssdata;
std::string s1 = engine_123.getIOTensorName(0);
std::string s2 = engine_123.getIOTensorName(1);
context->setTensorAddress(s1.c_str(), buffers[0]);
context->setTensorAddress(s2.c_str(), buffers[1]);
context->enqueueV3(stream);
// t4 = CheckUtil::getcurTime();
// Cuda_FloatTouchar((float *)buffers[1], (unsigned char *)ImgData[1], m_config.bufferList[1].ndatalength);
// cudaMemcpyAsync(p_outdata_1, ImgData[1], m_config.bufferList[1].nuchardataSize, cudaMemcpyDeviceToHost, stream);
// float *temdata = new float[m_config.bufferList[1].nuchardataSize];
cudaMemcpyAsync(floatData[1], buffers[1], m_config.bufferList[1].ndataSize, cudaMemcpyDeviceToHost, stream);
// printf("11m_config.bufferList[0].nuchardataSize %d\n", m_config.bufferList[1].nuchardataSize);
for (int i = 0; i < m_config.bufferList[1].nuchardataSize; i++)
{
p_outdata_1[i] = floatData[1][i];
}
// for (int i = 512 * 512 - 1000; i < 512 * 512; i++)
// {
// if (p_outdata_1[i] != 0)
// {
// printf("%d %d %f %d ", i, m_config.bufferList[1].nuchardataSize, temdata[i], p_outdata_1[i]);
// }
// }
// delete temsssssdata;
// delete temdata;
// t5 = CheckUtil::getcurTime();
cudaStreamSynchronize(stream);
cudaStreamDestroy(stream);
// t6 = CheckUtil::getcurTime();
// printf("t2 -t1 %ld t3 -t2 %ld t4 -t3 %ld t5 -t4 %ld t6 -t5 %ld t6 -t1 %ld \n", t2 - t1, t3 - t2, t4 - t3, t5 - t4, t6 - t5, t6 - t1);
// getchar();
return 0;
}
int AI_defect::model_Cuda_AI_In_1_Out_1_float(unsigned char *p_indata_0, float *p_outdata_1)
{
std::lock_guard<std::mutex> lock(g_mutex);
cudaSetDevice(m_config.nGpuIdx);
cudaStream_t stream;
CHECK(cudaStreamCreate(&stream));
// printf(">>>>>>>>>>>>>>>>>CUDA test \n");
const ICudaEngine &engine_123 = context->getEngine();
// auto s = engine_123.getTensorShape(m_config.bufferList[0].strName.c_str());
// std::cout << "tensor dims: [";
// for (int i = 0; i < s.nbDims; i++)
// {
// std::cout << s.d[i];
// if (i < s.nbDims - 1)
// std::cout << ", ";
// }
// std::cout << "]" << std::endl;
// {
// printf("name %s \n", m_config.bufferList[1].strName.c_str());
// auto s = engine_123.getTensorShape(m_config.bufferList[1].strName.c_str());
// std::cout << "tensor dims: [";
// for (int i = 0; i < s.nbDims; i++)
// {
// std::cout << s.d[i];
// if (i < s.nbDims - 1)
// std::cout << ", ";
// }
// std::cout << "]" << std::endl;
// }
// wrap_test_print();
long t1, t2, t3, t4, t5, t6, t7;
// t1 = CheckUtil::getcurTime();
for (int i = 0; i < m_config.bufferList[0].ndatalength; i++)
{
floatData[0][i] = p_indata_0[i];
}
cudaMemcpyAsync(buffers[0], floatData[0], m_config.bufferList[0].ndataSize, cudaMemcpyHostToDevice, stream);
// 拷贝数据到显卡
// cudaMemcpyAsync(ImgData[0], p_indata_0, m_config.bufferList[0].nuchardataSize, cudaMemcpyHostToDevice, stream);
// t2 = CheckUtil::getcurTime();
// 在显存中 图片数据从 uchar 转到 float
// Cuda_ucharToFloat((unsigned char *)ImgData[0], (float *)buffers[0], m_config.bufferList[0].ndatalength);
// t3 = CheckUtil::getcurTime();
std::string s1 = engine_123.getIOTensorName(0);
std::string s2 = engine_123.getIOTensorName(1);
context->setTensorAddress(s1.c_str(), buffers[0]);
context->setTensorAddress(s2.c_str(), buffers[1]);
context->enqueueV3(stream);
// t4 = CheckUtil::getcurTime();
cudaMemcpyAsync(p_outdata_1, buffers[1], m_config.bufferList[1].ndataSize, cudaMemcpyDeviceToHost, stream);
// t5 = CheckUtil::getcurTime();
cudaStreamSynchronize(stream);
cudaStreamDestroy(stream);
// t6 = CheckUtil::getcurTime();
// printf("t2 -t1 %ld t3 -t2 %ld t4 -t3 %ld t5 -t4 %ld t6 -t5 %ld t6 -t1 %ld \n", t2 - t1, t3 - t2, t4 - t3, t5 - t4, t6 - t5, t6 - t1);
return 0;
}
#else
int AI_defect::model_init(AIInitConfig config)
{
if (m_bInitialized)
{
printf("AI_defect::model_init succ \n");
return 0;
}
m_bInitialized = false;
printf("-- AI Init nGpuIdx %d model file %s \n", config.nGpuIdx, config.engine_file_path.c_str());
if (config.nGpuIdx < 0)
{
return 1;
}
if (!config.Checking())
{
return 1;
}
m_config.copy(config);
m_config.CalSize(sizeof(float));
cudaSetDevice(m_config.nGpuIdx);
char *trtModelStream{nullptr};
size_t size{0};
std::ifstream file(m_config.engine_file_path, std::ios::binary);
if (file.good())
{
file.seekg(0, file.end);
size = file.tellg();
file.seekg(0, file.beg);
trtModelStream = new char[size];
assert(trtModelStream);
file.read(trtModelStream, size);
file.close();
}
else
{
printf("------------Model file open error--********* \n");
return 1;
}
sample::Logger m_logger;
runtime = createInferRuntime(m_logger);
assert(runtime != nullptr);
engine = runtime->deserializeCudaEngine(trtModelStream, size, nullptr);
assert(engine != nullptr);
context = engine->createExecutionContext();
assert(context != nullptr);
delete[] trtModelStream;
for (int i = 0; i < MAX_AI_BUFFER_SIZE; i++)
{
if (m_config.bufferList[i].ntype == AIBufferType_NULL)
{
break;
}
floatData[i] = (float *)malloc(m_config.bufferList[i].ndatalength * sizeof(float));
cudaMalloc(&buffers[i], m_config.bufferList[i].ndataSize);
{
int nsize = m_config.bufferList[i].ndatalength * sizeof(unsigned char);
cudaMalloc(&ImgData[i], nsize);
/* code */
}
}
m_bInitialized = true;
return 0;
}
int AI_defect::model_Cuda_AI_In_1_Out_1(unsigned char *p_indata_0, unsigned char *p_outdata_1)
{
std::lock_guard<std::mutex> lock(g_mutex);
cudaSetDevice(m_config.nGpuIdx);
cudaStream_t stream;
cudaStreamCreate(&stream);
for (int i = 0; i < m_config.bufferList[0].ndatalength; i++)
{
floatData[0][i] = p_indata_0[i];
}
cudaMemcpyAsync(buffers[0], floatData[0], m_config.bufferList[0].ndataSize, cudaMemcpyHostToDevice, stream);
// // 拷贝数据到显卡
// cudaMemcpyAsync(ImgData[0], p_indata_0, m_config.bufferList[0].nuchardataSize, cudaMemcpyHostToDevice, stream);
// // t2 = CheckUtil::getcurTime();
// // 在显存中 图片数据从 uchar 转到 float
// Cuda_ucharToFloat((unsigned char *)ImgData[0], (float *)buffers[0], m_config.bufferList[0].ndatalength);
// t3 = CheckUtil::getcurTime();
context->enqueueV2(buffers, stream, nullptr);
// t4 = CheckUtil::getcurTime();
cudaMemcpyAsync(floatData[1], buffers[1], m_config.bufferList[1].ndataSize, cudaMemcpyDeviceToHost, stream);
// printf("11m_config.bufferList[0].nuchardataSize %d\n", m_config.bufferList[1].nuchardataSize);
for (int i = 0; i < m_config.bufferList[1].nuchardataSize; i++)
{
p_outdata_1[i] = floatData[1][i];
}
// Cuda_FloatTouchar((float *)buffers[1], (unsigned char *)ImgData[1], m_config.bufferList[1].ndatalength);
// cudaMemcpyAsync(p_outdata_1, ImgData[1], m_config.bufferList[1].nuchardataSize, cudaMemcpyDeviceToHost, stream);
// t5 = CheckUtil::getcurTime();
cudaStreamSynchronize(stream);
cudaStreamDestroy(stream);
// t6 = CheckUtil::getcurTime();
// printf("t2 -t1 %ld t3 -t2 %ld t4 -t3 %ld t5 -t4 %ld t6 -t5 %ld t6 -t1 %ld \n", t2 - t1, t3 - t2, t4 - t3, t5 - t4, t6 - t5, t6 - t1);
// getchar();
return 0;
}
int AI_defect::model_Cuda_AI_In_1_Out_1_float(unsigned char *p_indata_0, float *p_outdata_1)
{
std::lock_guard<std::mutex> lock(g_mutex);
cudaSetDevice(m_config.nGpuIdx);
cudaStream_t stream;
cudaStreamCreate(&stream);
for (int i = 0; i < m_config.bufferList[0].ndatalength; i++)
{
floatData[0][i] = p_indata_0[i];
}
cudaMemcpyAsync(buffers[0], floatData[0], m_config.bufferList[0].ndataSize, cudaMemcpyHostToDevice, stream);
// // 拷贝数据到显卡
// cudaMemcpyAsync(ImgData[0], p_indata_0, m_config.bufferList[0].nuchardataSize, cudaMemcpyHostToDevice, stream);
// // t2 = CheckUtil::getcurTime();
// // 在显存中 图片数据从 uchar 转到 float
// Cuda_ucharToFloat((unsigned char *)ImgData[0], (float *)buffers[0], m_config.bufferList[0].ndatalength);
// t3 = CheckUtil::getcurTime();
context->enqueueV2(buffers, stream, nullptr);
cudaMemcpyAsync(floatData[1], buffers[1], m_config.bufferList[1].ndataSize, cudaMemcpyDeviceToHost, stream);
// printf("11m_config.bufferList[0].nuchardataSize %d\n", m_config.bufferList[1].nuchardataSize);
for (int i = 0; i < m_config.bufferList[1].nuchardataSize; i++)
{
p_outdata_1[i] = floatData[1][i];
}
// t4 = CheckUtil::getcurTime();
// cudaMemcpyAsync(p_outdata_1, buffers[1], m_config.bufferList[1].ndataSize, cudaMemcpyDeviceToHost, stream);
// t5 = CheckUtil::getcurTime();
cudaStreamSynchronize(stream);
cudaStreamDestroy(stream);
// t6 = CheckUtil::getcurTime();
// printf("t2 -t1 %ld t3 -t2 %ld t4 -t3 %ld t5 -t4 %ld t6 -t5 %ld t6 -t1 %ld \n", t2 - t1, t3 - t2, t4 - t3, t5 - t4, t6 - t5, t6 - t1);
// getchar();
return 0;
}
#endif

@ -0,0 +1,359 @@
#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)
{
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 < QX_SAMLLIMG_WIDTH && roi.height < QX_SAMLLIMG_HEIGHT)
{
cutroi.width = QX_SAMLLIMG_WIDTH;
cutroi.x = pc_x - QX_SAMLLIMG_WIDTH * 0.5;
cutroi.height = QX_SAMLLIMG_HEIGHT;
cutroi.y = pc_y - QX_SAMLLIMG_HEIGHT * 0.5;
}
else
{
// 宽 高
if (roi.width > roi.height)
{
cutroi.width = roi.width + 20;
cutroi.x = roi.x - 10;
float fsx = QX_SAMLLIMG_HEIGHT * 1.0f / QX_SAMLLIMG_WIDTH;
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 = QX_SAMLLIMG_WIDTH * 1.0f / QX_SAMLLIMG_HEIGHT;
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)
{
// 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);
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;
}

@ -0,0 +1,710 @@
/*
* FileName:CoreLogicFactory.cpp
* Version:V1.0
* Description:
* Created On:Mon Sep 10 11:13:16 UTC 2018
* Modified date:
* Author:Sky
*/
#include "AIImgDeal.h"
#include "CheckUtil.hpp"
AI_IMG_deal::AI_IMG_deal()
{
m_pAI_SingleGPU = NULL;
AI_DATA_Cls_OUT_0 = NULL;
AI_DATA_Cls_L0_OUT_0 = NULL;
bInitSucc_re_AD = false;
bInitSucc_re_Pol = false;
bInitSucc_Edge_Samll = false;
bInitSucc_Edge_big = false;
bInitSucc_LackPol = false;
bInitSucc_MarkLine = false;
NewData();
}
AI_IMG_deal::~AI_IMG_deal()
{
// cout << "单例对象销毁!" << endl;
DelteData();
}
// 根据gpu号初始化
int AI_IMG_deal::Init(int nGpuIdx)
{
if (nGpuIdx < 0 || nGpuIdx >= MAX_GPU_NUMBER)
{
return -1;
}
m_nGpuIdx = nGpuIdx;
m_pAI_SingleGPU = AI_SingleGPU::GetInstance(nGpuIdx);
cout << "AI_IMG_deal GPU:" << m_nGpuIdx << " create succ " << m_pAI_SingleGPU << endl;
return 0;
}
int AI_IMG_deal::NewData()
{
if (AI_DATA_Cls_OUT_0 == NULL)
{
AI_DATA_Cls_OUT_0 = new float[AI_Cls_out_0_IMAGE_DATA_LENGTH];
}
if (AI_DATA_Cls_L0_OUT_0 == NULL)
{
AI_DATA_Cls_L0_OUT_0 = new float[AI_Cls_14_out_0_IMAGE_DATA_LENGTH];
}
return 0;
}
int AI_IMG_deal::DelteData()
{
if (AI_DATA_Cls_OUT_0)
{
delete[] AI_DATA_Cls_OUT_0;
AI_DATA_Cls_OUT_0 = NULL;
}
if (AI_DATA_Cls_L0_OUT_0)
{
delete[] AI_DATA_Cls_L0_OUT_0;
AI_DATA_Cls_L0_OUT_0 = NULL;
}
return 0;
}
int AI_IMG_deal::Init_BOE(AIInitConfig config)
{
int re = m_pAI_SingleGPU->AI_defect_NF.model_init(config);
if (0 != re)
{
printf("Init_NF error \n");
}
printf("Init_NF succ----------------------------%d \n", config.nGpuIdx);
return re;
}
int AI_IMG_deal::Init_127Cell(AIInitConfig config)
{
int re = m_pAI_SingleGPU->AI_defect_127Cell.model_init(config);
if (0 != re)
{
printf("Init_127Cell error \n");
bInitSucc_127Cell = false;
}
else
{
bInitSucc_127Cell = true;
}
printf("Init_127Cell succ----------------------------%d bInitSucc_127Cell %d\n", config.nGpuIdx, bInitSucc_127Cell);
return 0;
}
int AI_IMG_deal::Init_BOE_Type2(AIInitConfig config)
{
int re = m_pAI_SingleGPU->AI_defect_Type2.model_init(config);
if (0 != re)
{
printf("Init_BOE_Type2 error \n");
}
printf("Init_BOE_Type2 succ----------------------------%d \n", config.nGpuIdx);
return re;
}
int AI_IMG_deal::Init_BOE_UP(AIInitConfig config)
{
int re = m_pAI_SingleGPU->AI_defect_UP.model_init(config);
if (0 != re)
{
printf("Init_BOE_UP error \n");
}
printf("Init_BOE_UP succ----------------------------%d \n", config.nGpuIdx);
return re;
}
int AI_IMG_deal::Init_BOE_Chess(AIInitConfig config)
{
int re = m_pAI_SingleGPU->AI_defect_Chess.model_init(config);
if (0 != re)
{
printf("Init_BOE_Chess error \n");
}
printf("Init_BOE_Chess succ----------------------------%d \n", config.nGpuIdx);
return re;
}
int AI_IMG_deal::Init_YX_1(AIInitConfig config)
{
int re = m_pAI_SingleGPU->AI_defect_YX_1.model_init(config);
if (0 != re)
{
printf("Init_YX_1 error \n");
}
printf("Init_YX_1 succ----------------------------%d \n", config.nGpuIdx);
return re;
}
int AI_IMG_deal::Init_YX_2(AIInitConfig config)
{
int re = m_pAI_SingleGPU->AI_defect_YX_2.model_init(config);
if (0 != re)
{
printf("Init_YX_2 error \n");
}
printf("Init_YX_2 succ----------------------------%d \n", config.nGpuIdx);
return 0;
}
int AI_IMG_deal::Init_Cls(AIInitConfig config, int ntype)
{
int re = 0;
if (ntype != 1 && ntype != 2)
{
re = m_pAI_SingleGPU->AI_defect_Cls.model_init(config);
if (0 != re)
{
printf("Init_Cls error \n");
}
printf("Init_Cls succ------123---------------ntype%d-------%d \n", config.nGpuIdx, ntype);
}
if (ntype == 1)
{
re = m_pAI_SingleGPU->AI_defect_Cls_L0.model_init(config);
if (0 != re)
{
printf("Init_Cls error \n");
}
printf("Init_Cls succ-----------AI_defect_Cls_L0-----------------%d \n", config.nGpuIdx);
}
return re;
}
int AI_IMG_deal::Init_zf(AIInitConfig config)
{
int re = m_pAI_SingleGPU->AI_defect_zf.model_init(config);
if (0 != re)
{
printf("Init_zf error \n");
}
printf("Init_zf succ----------------------------%d \n", config.nGpuIdx);
return re;
}
int AI_IMG_deal::Init_RE_POL(AIInitConfig config)
{
int re = m_pAI_SingleGPU->AI_defect_RE_POL.model_init(config);
if (0 != re)
{
printf("AI_defect_RE_POL error \n");
bInitSucc_re_Pol = false;
}
else
{
bInitSucc_re_Pol = true;
}
printf("AI_defect_RE_POL succ----------------------------%d AI_defect_RE_POL %d\n", config.nGpuIdx, bInitSucc_re_Pol);
return re;
}
int AI_IMG_deal::Init_RE_AD(AIInitConfig config)
{
int re = m_pAI_SingleGPU->AI_defect_RE_AD.model_init(config);
if (0 != re)
{
printf("AI_defect_RE_AD error \n");
bInitSucc_re_AD = false;
}
else
{
bInitSucc_re_AD = true;
}
printf("AI_defect_RE_AD succ---------------------------%d AI_defect_RE_AD %d\n", config.nGpuIdx, bInitSucc_re_AD);
return re;
}
int AI_IMG_deal::Init_Edge_Big(AIInitConfig config)
{
printf("Init_Edge_Big gpu %d \n", config.nGpuIdx);
int re = m_pAI_SingleGPU->AI_defect_Edge_Big.model_init(config);
if (0 != re)
{
printf("AI_defect_Edge_Big error \n");
bInitSucc_Edge_big = false;
}
else
{
bInitSucc_Edge_big = true;
}
printf("AI_defect_Edge_Big succ-------------------------gpu :%d reuslt : %d\n", config.nGpuIdx, bInitSucc_Edge_big);
return 0;
}
int AI_IMG_deal::Init_Edge_Small(AIInitConfig config)
{
int re = m_pAI_SingleGPU->AI_defect_Edge_Samll.model_init(config);
if (0 != re)
{
printf("AI_defect_Edge_Samll error \n");
bInitSucc_Edge_Samll = false;
}
else
{
bInitSucc_Edge_Samll = true;
}
printf("AI_defect_Edge_Samll succ---------------------------gpu :%d reuslt : %d\n", config.nGpuIdx, bInitSucc_Edge_Samll);
return 0;
}
int AI_IMG_deal::Init_LackPol(AIInitConfig config)
{
int re = m_pAI_SingleGPU->AI_defect_LackPol.model_init(config);
if (0 != re)
{
printf("Init_LackPol error \n");
bInitSucc_LackPol = false;
return re;
}
else
{
bInitSucc_LackPol = true;
}
printf("bInitSucc_LackPol succ---------------------------gpu :%d reuslt: %d\n", config.nGpuIdx, bInitSucc_LackPol);
return 0;
}
int AI_IMG_deal::Init_MarkLine(AIInitConfig config)
{
int re = m_pAI_SingleGPU->AI_defect_MarkLine.model_init(config);
if (0 != re)
{
printf("AI_defect_MarkLine error \n");
bInitSucc_MarkLine = false;
}
else
{
bInitSucc_MarkLine = true;
}
printf("AI_defect_MarkLine succ----------------------------%d AI_defect_RE_POL %d\n", config.nGpuIdx, bInitSucc_MarkLine);
return 0;
}
int AI_IMG_deal::AICheck_BOE(cv::Mat inImg, cv::Mat &outImg_1)
{
if (inImg.empty())
{
return -1;
}
long t1, t2;
t1 = CheckUtil::getcurTime();
uchar *pindata = inImg.ptr<uchar>(0);
outImg_1 = InitMat(AI_NF_out_0_IMAGE_CHANNEL, AI_NF_out_0_IMAGE_WIDTH, AI_NF_out_0_IMAGE_HEIGHT);
uchar *poutImg_1 = outImg_1.ptr<uchar>(0);
m_pAI_SingleGPU->AI_defect_NF.model_Cuda_AI_In_1_Out_1(pindata, poutImg_1);
t2 = CheckUtil::getcurTime();
// printf("AI_defect_NF conver work sum %ld \n", t2 - t1);
return 0;
}
int AI_IMG_deal::AICheck_BOE_Type2(cv::Mat inImg, cv::Mat &outImg_1)
{
if (inImg.empty())
{
return -1;
}
long t1, t2;
t1 = CheckUtil::getcurTime();
uchar *pindata = inImg.ptr<uchar>(0);
outImg_1 = InitMat(AI_NF_out_0_IMAGE_CHANNEL, AI_NF_out_0_IMAGE_WIDTH, AI_NF_out_0_IMAGE_HEIGHT);
uchar *poutImg_1 = outImg_1.ptr<uchar>(0);
m_pAI_SingleGPU->AI_defect_Type2.model_Cuda_AI_In_1_Out_1(pindata, poutImg_1);
t2 = CheckUtil::getcurTime();
// printf("AI_defect_NF conver work sum %ld \n", t2 - t1);
return 0;
}
int AI_IMG_deal::AICheck_BOE_Chess(cv::Mat inImg, cv::Mat &outImg_1)
{
if (inImg.empty())
{
return -1;
}
long t1, t2;
t1 = CheckUtil::getcurTime();
uchar *pindata = inImg.ptr<uchar>(0);
outImg_1 = InitMat(AI_NF_out_0_IMAGE_CHANNEL, AI_NF_out_0_IMAGE_WIDTH, AI_NF_out_0_IMAGE_HEIGHT);
uchar *poutImg_1 = outImg_1.ptr<uchar>(0);
m_pAI_SingleGPU->AI_defect_Chess.model_Cuda_AI_In_1_Out_1(pindata, poutImg_1);
t2 = CheckUtil::getcurTime();
// printf("AI_defect_NF conver work sum %ld \n", t2 - t1);
return 0;
}
int AI_IMG_deal::AICheck_BOE_UP(cv::Mat inImg, cv::Mat &outImg_1)
{
if (inImg.empty())
{
return -1;
}
long t1, t2;
t1 = CheckUtil::getcurTime();
uchar *pindata = inImg.ptr<uchar>(0);
outImg_1 = InitMat(AI_NF_out_0_IMAGE_CHANNEL, AI_NF_out_0_IMAGE_WIDTH, AI_NF_out_0_IMAGE_HEIGHT);
uchar *poutImg_1 = outImg_1.ptr<uchar>(0);
m_pAI_SingleGPU->AI_defect_UP.model_Cuda_AI_In_1_Out_1(pindata, poutImg_1);
t2 = CheckUtil::getcurTime();
// printf("AI_defect_NF conver work sum %ld \n", t2 - t1);
return 0;
}
int AI_IMG_deal::AICheck_YX_1(cv::Mat inImg, cv::Mat &outImg_1)
{
if (inImg.empty())
{
return -1;
}
long t1, t2;
t1 = CheckUtil::getcurTime();
uchar *pindata = inImg.ptr<uchar>(0);
outImg_1 = InitMat(AI_YX_out_0_IMAGE_CHANNEL, AI_YX_out_0_IMAGE_WIDTH, AI_YX_out_0_IMAGE_HEIGHT);
uchar *poutImg_1 = outImg_1.ptr<uchar>(0);
m_pAI_SingleGPU->AI_defect_YX_1.model_Cuda_AI_In_1_Out_1(pindata, poutImg_1);
t2 = CheckUtil::getcurTime();
// printf("AI_defect_NF conver work sum %ld \n", t2 - t1);
return 0;
}
int AI_IMG_deal::AICheck_YX_2(cv::Mat inImg, cv::Mat &outImg_1)
{
if (inImg.empty())
{
return -1;
}
long t1, t2;
t1 = CheckUtil::getcurTime();
uchar *pindata = inImg.ptr<uchar>(0);
outImg_1 = InitMat(AI_YX_out_0_IMAGE_CHANNEL, AI_YX_out_0_IMAGE_WIDTH, AI_YX_out_0_IMAGE_HEIGHT);
uchar *poutImg_1 = outImg_1.ptr<uchar>(0);
m_pAI_SingleGPU->AI_defect_YX_2.model_Cuda_AI_In_1_Out_1(pindata, poutImg_1);
t2 = CheckUtil::getcurTime();
// printf("AI_defect_NF conver work sum %ld \n", t2 - t1);
return 0;
}
int AI_IMG_deal::AICheck_Cls(cv::Mat inImg, int ntype, float *fmaxScore)
{
if (inImg.empty())
{
return -1;
}
uchar *pindata = inImg.ptr<uchar>(0);
int cls_num = AI_Cls_out_0_IMAGE_DATA_LENGTH;
if (ntype == 1)
{
cls_num = AI_Cls_14_out_0_IMAGE_DATA_LENGTH;
}
int max_id = 0;
if (ntype == 1)
{
m_pAI_SingleGPU->AI_defect_Cls_L0.model_Cuda_AI_In_1_Out_1_float(pindata, AI_DATA_Cls_L0_OUT_0);
max_id = F2softmaxId(AI_DATA_Cls_L0_OUT_0, cls_num, fmaxScore);
}
else
{
m_pAI_SingleGPU->AI_defect_Cls.model_Cuda_AI_In_1_Out_1_float(pindata, AI_DATA_Cls_OUT_0);
max_id = F2softmaxId(AI_DATA_Cls_OUT_0, cls_num, fmaxScore);
}
// printf("ccccccccc 2\n");
// getchar();
// std::cout<<"-----------------------------------------max_id="<<max_id<<std::endl;
return max_id;
}
int AI_IMG_deal::AICheck_zf(cv::Mat inImg, cv::Mat &outImg_1)
{
if (inImg.empty())
{
return -1;
}
long t1, t2;
t1 = CheckUtil::getcurTime();
uchar *pindata = inImg.ptr<uchar>(0);
outImg_1 = InitMat(AI_ZF_out_0_IMAGE_CHANNEL, AI_ZF_out_0_IMAGE_WIDTH, AI_ZF_out_0_IMAGE_HEIGHT);
uchar *poutImg_1 = outImg_1.ptr<uchar>(0);
m_pAI_SingleGPU->AI_defect_zf.model_Cuda_AI_In_1_Out_1(pindata, poutImg_1);
t2 = CheckUtil::getcurTime();
// printf("AI_defect_NF conver work sum %ld \n", t2 - t1);
return 0;
}
int AI_IMG_deal::AICheck_127Cell(cv::Mat inImg, cv::Mat &outImg_1)
{
if (inImg.empty())
{
return -1;
}
long t1, t2;
t1 = CheckUtil::getcurTime();
uchar *pindata = inImg.ptr<uchar>(0);
outImg_1 = InitMat(AI_127Cell_out_0_IMAGE_CHANNEL, AI_127Cell_out_0_IMAGE_WIDTH, AI_127Cell_out_0_IMAGE_HEIGHT);
if (!bInitSucc_127Cell)
{
return 1;
}
uchar *poutImg_1 = outImg_1.ptr<uchar>(0);
m_pAI_SingleGPU->AI_defect_127Cell.model_Cuda_AI_In_1_Out_1(pindata, poutImg_1);
t2 = CheckUtil::getcurTime();
return 0;
}
int AI_IMG_deal::AICheck_RE_POL(cv::Mat inImg, cv::Mat &outImg_1)
{
if (inImg.empty())
{
return -1;
}
uchar *pindata = inImg.ptr<uchar>(0);
outImg_1 = InitMat(str_AI_RE_POL_out_0_IMAGE_CHANNEL, str_AI_RE_POL_out_0_IMAGE_WIDTH, str_AI_RE_POL_out_0_IMAGE_HEIGHT);
if (!bInitSucc_re_Pol)
{
return 1;
}
uchar *poutImg_1 = outImg_1.ptr<uchar>(0);
m_pAI_SingleGPU->AI_defect_RE_POL.model_Cuda_AI_In_1_Out_1(pindata, poutImg_1);
return 0;
}
int AI_IMG_deal::AICheck_RE_AD(cv::Mat inImg, cv::Mat &outImg_1)
{
if (inImg.empty())
{
return -1;
}
uchar *pindata = inImg.ptr<uchar>(0);
outImg_1 = InitMat(str_AI_RE_AD_out_0_IMAGE_CHANNEL, str_AI_RE_AD_out_0_IMAGE_WIDTH, str_AI_RE_AD_out_0_IMAGE_HEIGHT);
if (!bInitSucc_re_AD)
{
return 1;
}
uchar *poutImg_1 = outImg_1.ptr<uchar>(0);
m_pAI_SingleGPU->AI_defect_RE_AD.model_Cuda_AI_In_1_Out_1(pindata, poutImg_1);
return 0;
}
int AI_IMG_deal::AICheck_Edge_Big(cv::Mat inImg, cv::Mat &outImg_1)
{
if (inImg.empty())
{
return -1;
}
uchar *pindata = inImg.ptr<uchar>(0);
outImg_1 = InitMat(str_AI_EDGE_Big_out_0_IMAGE_CHANNEL, str_AI_EDGE_Big_out_0_IMAGE_WIDTH, str_AI_EDGE_Big_out_0_IMAGE_HEIGHT);
if (!bInitSucc_Edge_big)
{
return 1;
}
uchar *poutImg_1 = outImg_1.ptr<uchar>(0);
m_pAI_SingleGPU->AI_defect_Edge_Big.model_Cuda_AI_In_1_Out_1(pindata, poutImg_1);
return 0;
}
int AI_IMG_deal::AICheck_Edge_Small(cv::Mat inImg, cv::Mat &outImg_1)
{
if (inImg.empty())
{
return -1;
}
uchar *pindata = inImg.ptr<uchar>(0);
outImg_1 = InitMat(str_AI_EDGE_Small_out_0_IMAGE_CHANNEL, str_AI_EDGE_Small_out_0_IMAGE_WIDTH, str_AI_EDGE_Small_out_0_IMAGE_HEIGHT);
if (!bInitSucc_Edge_Samll)
{
return 1;
}
uchar *poutImg_1 = outImg_1.ptr<uchar>(0);
m_pAI_SingleGPU->AI_defect_Edge_Samll.model_Cuda_AI_In_1_Out_1(pindata, poutImg_1);
return 0;
}
int AI_IMG_deal::AICheck_LackPol(cv::Mat inImg, cv::Mat &outImg_1)
{
if (inImg.empty())
{
return -1;
}
uchar *pindata = inImg.ptr<uchar>(0);
outImg_1 = InitMat(str_AI_LOSSPOL_out_0_IMAGE_CHANNEL, str_AI_LOSSPOL_out_0_IMAGE_WIDTH, str_AI_LOSSPOL_out_0_IMAGE_HEIGHT);
if (!bInitSucc_LackPol)
{
return 1;
}
uchar *poutImg_1 = outImg_1.ptr<uchar>(0);
m_pAI_SingleGPU->AI_defect_LackPol.model_Cuda_AI_In_1_Out_1(pindata, poutImg_1);
return 0;
}
int AI_IMG_deal::AICheck_MarkLine(cv::Mat inImg, cv::Mat &outImg_1)
{
if (inImg.empty())
{
return -1;
}
uchar *pindata = inImg.ptr<uchar>(0);
outImg_1 = InitMat(str_AI_Mark_out_0_IMAGE_CHANNEL, str_AI_Mark_out_0_IMAGE_WIDTH, str_AI_Mark_out_0_IMAGE_HEIGHT);
if (!bInitSucc_MarkLine)
{
return 1;
}
uchar *poutImg_1 = outImg_1.ptr<uchar>(0);
m_pAI_SingleGPU->AI_defect_MarkLine.model_Cuda_AI_In_1_Out_1(pindata, poutImg_1);
return 0;
}
cv::Mat AI_IMG_deal::F2M(float *data, int clannel, int w, int h)
{
cv::Mat dst(h, w, 8 * (clannel - 1));
uint8_t *dstp = (uint8_t *)dst.data;
int length = w * h * clannel;
for (int i = 0; i < length; i++)
{
if (data[i] > 255)
{
dstp[i] = 256 - data[i] / 255;
}
else
{
dstp[i] = uint8_t(data[i]);
}
}
return dst;
}
cv::Mat AI_IMG_deal::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 AI_IMG_deal::F2softmaxId(float *data, int class_num, float *fmaxScore)
{
// std::cout<<"F2softmaxId()-class_num="<<class_num<<std::endl;
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,817 @@
#include "AI_Edge_Algin.h"
#include "CheckErrorCodeDefine.hpp"
#define EDGE_GPU 0
AI_Edge_Algin::AI_Edge_Algin()
{
m_bInitialized = false;
m_bModelSucc = false;
}
AI_Edge_Algin::~AI_Edge_Algin()
{
}
int AI_Edge_Algin::Init(OtherDet_Config *pOtherDet_Config)
{
m_pOtherDet_Config = pOtherDet_Config;
m_pAIDeal = pOtherDet_Config->pAIDeal;
m_bInitialized = true;
return 0;
}
int AI_Edge_Algin::Detect(const cv::Mat &img, DetConfig *pDetConfig, std::shared_ptr<Edge_AI_Result> &pCheckResult_Aling)
{
printf("save type %d \n", pDetConfig->saveProcessImg);
m_pDetConfig = pDetConfig;
static int erridx = 0;
std::string str_error = "";
// 保存过程图片
if (m_pDetConfig->IsSaveProcessImg())
{
erridx++;
if (erridx > 9999999)
{
erridx = 0;
}
str_error = "/home/aidlux/BOE/Edge/Error/" + std::to_string(erridx) + "_src.png";
}
cv::Mat showimg;
// 保存结果图片
if (m_pDetConfig->bSaveResultImg)
{
cv::cvtColor(img, showimg, cv::COLOR_GRAY2BGR);
}
pCheckResult_Aling = std::make_shared<Edge_AI_Result>();
if (img.empty())
{
return 1;
}
// 1、初步定位 找到产品大致区域
int re = 0;
vector<Rect> rois;
cv::Rect Big_roi;
cv::Mat mask;
cv::Mat big_mask;
re = Det_big(img, rois, Big_roi, big_mask);
if (re != 0)
{
printf("AICheck_Edge_Big----error %d \n", re);
if (m_pDetConfig->IsSaveProcessImg())
{
cv::imwrite(str_error, img);
}
return re;
}
if (m_pDetConfig->bSaveResultImg)
{
for (const auto &roi : rois)
{
cv::rectangle(showimg, roi, cv::Scalar(0, 0, 255));
}
cv::rectangle(showimg, Big_roi, cv::Scalar(255, 255, 255), 2);
cv::imwrite(pDetConfig->strCamName + " edge_Small_Det_ROI_0.png", showimg);
}
// 2、对每个小区域进行处理
cv::Mat Src_Mask = cv::Mat(img.rows, img.cols, CV_8U, cv::Scalar(0));
cv::Mat Src_Masksss;
for (const auto &roi : rois)
{
cv::Mat smask;
cv::Rect detROI = roi;
if (detROI.x < 0)
detROI.x = 0;
if (detROI.y < 0)
detROI.y = 0;
if (detROI.x + detROI.width > img.cols)
detROI.x = img.cols - detROI.width;
if (detROI.y + detROI.height > img.rows)
detROI.y = img.rows - detROI.height;
cv::Mat temDet = img(detROI).clone();
re = m_pAIDeal->AICheck_Edge_Small(temDet, smask);
if (re != 0)
{
printf("AICheck_Edge_small----error \n");
return 6;
}
// 保存过程小图
SaveSmallImg(temDet, smask, detROI);
smask.copyTo(Src_Mask(detROI), smask);
}
if (m_pDetConfig->bSaveResultImg)
{
cv::imwrite(pDetConfig->strCamName + " edge_Small_Out_Mask_1.png", Src_Mask);
}
cv::Rect result_roi;
Mat resultMask = Mat::zeros(img.size(), CV_8UC1);
{
vector<vector<Point>> contours;
findContours(Src_Mask, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
// 找到最大轮廓
double max_area = 0;
int max_contour_index = 0;
for (int i = 0; i < contours.size(); i++)
{
double area = contourArea(contours[i]);
if (area > max_area)
{
max_area = area;
max_contour_index = i;
}
}
if (max_contour_index < 0)
{
cerr << "No contours found!" << endl;
return 7;
}
if (max_contour_index >= 0)
{
result_roi = boundingRect(contours[max_contour_index]);
}
drawContours(resultMask, contours, max_contour_index, Scalar(255), FILLED); // -1表示填充所有轮廓
}
// 和原始big模型做比对
{
double widthDiff = std::abs(result_roi.width - Big_roi.width) * 1.0f / std::min(result_roi.width, Big_roi.width);
double heightDiff = std::abs(result_roi.height - Big_roi.height) * 1.0f / std::min(result_roi.height, Big_roi.height);
printf("big roi %s det %swidthDiff %f heightDiff %f\n", CheckUtil::GetRectString(Big_roi).c_str(), CheckUtil::GetRectString(result_roi).c_str(), widthDiff, heightDiff);
// 如果差异超过10%,抛出异常
if (widthDiff > 0.10)
{
return 51;
}
if (heightDiff > 0.10)
{
return 52;
}
}
if (m_pDetConfig->bUseDrawRoi_Check)
{
double widthDiff = std::abs(result_roi.width - m_pDetConfig->drawRoi.width) * 1.0f / std::min(result_roi.width, m_pDetConfig->drawRoi.width);
double heightDiff = std::abs(result_roi.height - m_pDetConfig->drawRoi.height) * 1.0f / std::min(result_roi.height, m_pDetConfig->drawRoi.height);
printf("draw roi %s det %s widthDiff %f heightDiff %f\n", CheckUtil::GetRectString(m_pDetConfig->drawRoi).c_str(), CheckUtil::GetRectString(result_roi).c_str(), widthDiff, heightDiff);
// 如果差异超过10%,抛出异常
if (widthDiff > 0.10)
{
return 53;
}
if (heightDiff > 0.10)
{
return 54;
}
}
// 用big 的来测试
if (false)
{
cv::Size sz_big;
sz_big.width = big_mask.cols;
sz_big.height = big_mask.rows;
cv::Mat size_prodct;
cv::resize(resultMask, size_prodct, sz_big, 0, 0, cv::INTER_AREA);
int va_big = countNonZero(big_mask);
int va_small = countNonZero(size_prodct);
if (va_big > 0)
{
int diff = std::abs(va_big - va_small); // 面积的差异值。
float fs = diff * 1.0f / va_big;
printf("va_big %d va_small %d dff %d diffscale %f \n", va_big, va_small, diff, fs);
if (fs > 0.1)
{
// if (true)
// {
// cv::imwrite("big_mask.png",big_mask);
// cv::imwrite("size_prodct.png",size_prodct);
// getchar();
// }
return 55;
}
}
/* code */
}
if (m_pDetConfig->bUseDrawRoi_Check && !m_pDetConfig->drawMask.empty())
{
cv::Size sz_big;
sz_big.width = big_mask.cols;
sz_big.height = big_mask.rows;
cv::Mat size_prodct;
cv::resize(resultMask, size_prodct, sz_big, 0, 0, cv::INTER_AREA);
cv::Mat size_drawmask;
cv::resize(m_pDetConfig->drawMask, size_drawmask, sz_big, 0, 0, cv::INTER_AREA);
int va_draw = countNonZero(size_drawmask);
int va_small = countNonZero(size_prodct);
if (va_draw > 0)
{
int diff = std::abs(va_draw - va_small); // 面积的差异值。
float fs = diff * 1.0f / va_draw;
printf("va_draw %d va_small %d dff %d diffscale %f \n", va_draw, va_small, diff, fs);
if (fs > 0.1)
{
return 56;
}
}
}
if (m_pDetConfig->bSaveResultImg)
{
cv::imwrite(pDetConfig->strCamName + " edge_product_det_mask.png", resultMask);
if (!m_pDetConfig->drawMask.empty())
{
cv::imwrite(pDetConfig->strCamName + " edge_product_draw_mask.png", m_pDetConfig->drawMask);
}
}
pCheckResult_Aling->DetMask_src = resultMask.clone();
if (m_pDetConfig->bSaveResultImg)
{
cv::imwrite(std::to_string(m_pDetConfig->ncamId) + " edge_Small_mask_Filled_2.png", resultMask);
}
cv::Mat resultMask_erode_small;
// 膨胀腐蚀处理
{
printf("m_pDetConfig->nAIErodesize %d\n", m_pDetConfig->nAIErodesize);
if (m_pDetConfig->nAIErodesize <= 0)
{
resultMask_erode_small = resultMask(result_roi).clone();
}
else
{
// 定义膨胀核
int dilation_size = 7; // 膨胀核的大小
if (m_pDetConfig->nAIErodesize > 0 && m_pDetConfig->nAIErodesize < 101)
{
dilation_size = 2 * m_pDetConfig->nAIErodesize;
}
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(dilation_size, dilation_size));
// 进行膨胀操作
cv::erode(resultMask(result_roi), resultMask_erode_small, kernel);
}
pCheckResult_Aling->mask = ~resultMask_erode_small;
}
if (m_pDetConfig->bSaveResultImg)
{
// cv::imwrite("edge_result_src_roi_thresholdvalue.png", temimg);
cv::imwrite(pDetConfig->strCamName + " edge_result_src_3.png", img(result_roi));
cv::imwrite(pDetConfig->strCamName + " edge_result_mask_4.png", pCheckResult_Aling->mask);
cv::Mat temAdd = img(result_roi).clone();
{
// 查找轮廓
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours(resultMask_erode_small.clone(), contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
// 创建一个空白图像用于绘制轮廓
// 绘制轮廓
cv::drawContours(temAdd, contours, -1, cv::Scalar(255, 255, 0), 2); // 绿色线宽2
}
cv::imwrite(pDetConfig->strCamName + " edge_result_Merge_5.png", temAdd);
}
// 存在中间结果
if (m_pDetConfig->saveProcessImg != Save_Close)
{
static int svidx = 0;
svidx++;
if (svidx > 9999999)
{
svidx = 0;
/* code */
}
std::string str1 = "/home/aidlux/BOE/Edge/Result/" + std::to_string(svidx) + "_mask.png";
std::string str2 = "/home/aidlux/BOE/Edge/Result/" + std::to_string(svidx) + "_show.png";
int newWidth = 1280;
float aspectRatio = static_cast<float>(resultMask_erode_small.rows) / resultMask_erode_small.cols;
int newHeight = static_cast<int>(newWidth * aspectRatio);
// 缩放图像
cv::Mat resizedImage;
cv::resize(resultMask_erode_small, resizedImage, cv::Size(newWidth, newHeight));
cv::Mat temAdd = img(result_roi).clone();
cv::resize(temAdd, temAdd, cv::Size(newWidth, newHeight));
{
// 查找轮廓
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours(resizedImage.clone(), contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
// 创建一个空白图像用于绘制轮廓
// 绘制轮廓
cv::drawContours(temAdd, contours, -1, cv::Scalar(255, 255, 0), 1); // 绿色线宽2
}
cv::imwrite(str1, resizedImage);
cv::imwrite(str2, temAdd);
}
pCheckResult_Aling->roi = result_roi;
return 0;
}
int AI_Edge_Algin::SaveSmallImg(const cv::Mat &img, const cv::Mat &mask, cv::Rect roi)
{
// 是否要保存中间过程的小图
if (m_pDetConfig->IsSaveProcessImg())
{
static int svsmallidx = 0;
svsmallidx++;
if (svsmallidx > 9999999)
{
svsmallidx = 0;
/* code */
}
bool bssss = false;
if (m_pDetConfig->saveProcessImg == Save_Filter)
{
// 4. 查找轮廓
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(mask.clone(), contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
if (contours.size() > 1)
{
bssss = true;
}
else if (contours.size() == 1)
{
int pointNum = 0;
for (int i = 0; i < contours.size(); i++)
{
pointNum += contours[i].size();
}
// printf("pointNum============== %d\n", pointNum);
if (pointNum > 30)
{
bssss = true;
}
}
}
else if (m_pDetConfig->saveProcessImg == Save_ALL)
{
bssss = true;
}
if (bssss)
{
std::string str1 = "/home/aidlux/BOE/Edge/Smasll/" + std::to_string(svsmallidx) + "_in.png";
std::string str2 = "/home/aidlux/BOE/Edge/Smasll/" + std::to_string(svsmallidx) + "_in_mask.png";
// std::string st3 = "/home/aidlux/BOE/Edge/Smasll/" + std::to_string(svsmallidx) + "_in_show.png";
cv::imwrite(str1, img);
cv::imwrite(str2, mask);
// cv::Mat showsss = temDet + smask * 0.4;
// cv::imwrite(st3, showsss);
}
}
return 0;
}
int AI_Edge_Algin::InitModel_ALL()
{
m_bModelSucc = false;
int re = InitModel_Big();
if (re != 0)
{
printf("AI_Edge_Algin InitModel_Big Error \n");
return re;
}
re = InitModel_Small();
if (re != 0)
{
printf("AI_Edge_Algin InitModel_Small Error \n");
return re;
}
m_bModelSucc = true;
return 0;
}
int AI_Edge_Algin::InitModel_Big()
{
AIInitConfig config_nf;
config_nf.nGpuIdx = EDGE_GPU;
config_nf.engine_file_path = str_AI_EDGE_Big_Model_Path;
config_nf.bufferList[0].ntype = AIBufferType_IN;
config_nf.bufferList[0].ndatalength = str_AI_EDGE_Big_IN_0_DATA_LENGTH;
config_nf.bufferList[0].strName = str_AI_EDGE_Big_IN_0_IMAGE_Name;
config_nf.bufferList[1].ntype = AIBufferType_OUT;
config_nf.bufferList[1].ndatalength = str_AI_EDGE_Big_out_0_DATA_LENGTH;
config_nf.bufferList[1].strName = str_AI_EDGE_Big_out_0_IMAGE_Name;
m_pAIDeal->Init_Edge_Big(config_nf);
return 0;
}
int AI_Edge_Algin::InitModel_Small()
{
AIInitConfig config_nf;
config_nf.nGpuIdx = EDGE_GPU;
config_nf.engine_file_path = str_AI_EDGE_Small_Model_Path;
config_nf.bufferList[0].ntype = AIBufferType_IN;
config_nf.bufferList[0].ndatalength = str_AI_EDGE_Small_IN_0_DATA_LENGTH;
config_nf.bufferList[0].strName = str_AI_EDGE_Big_out_0_IMAGE_Name;
config_nf.bufferList[1].ntype = AIBufferType_OUT;
config_nf.bufferList[1].ndatalength = str_AI_EDGE_Small_out_0_DATA_LENGTH;
config_nf.bufferList[1].strName = str_AI_EDGE_Small_out_0_IMAGE_Name;
m_pAIDeal->Init_Edge_Small(config_nf);
return 0;
}
int AI_Edge_Algin::Det_big(const cv::Mat &img, vector<Rect> &smallRoiList, cv::Rect &bigRoi, cv::Mat &big_mask)
{
cv::Size sz;
sz.width = str_AI_EDGE_Big_IN_0_IMAGE_WIDTH;
sz.height = str_AI_EDGE_Big_IN_0_IMAGE_HEIGHT;
cv::Mat detImg;
cv::resize(img, detImg, sz);
int re = 0;
cv::Mat mask;
re = m_pAIDeal->AICheck_Edge_Big(detImg, mask);
big_mask = mask;
if (re != 0)
{
printf("AICheck_Edge_Big----error \n");
int re123 = 100 + re;
return re123;
}
if (m_pDetConfig->bSaveResultImg)
{
cv::imwrite("edge_big_in.png", detImg);
cv::imwrite("edge_big_out_mask.png", mask);
}
if (m_pDetConfig->IsSaveProcessImg())
{
static int bigidx = 0;
bigidx++;
if (bigidx > 9999999)
{
bigidx = 0;
/* code */
}
std::string str1 = "/home/aidlux/BOE/Edge/Big/" + std::to_string(bigidx) + "_in.png";
std::string str2 = "/home/aidlux/BOE/Edge/Big/" + std::to_string(bigidx) + "_in_mask.png";
cv::imwrite(str1, detImg);
cv::imwrite(str2, mask);
}
// 找到最大轮廓
bool found;
cv::Rect boundingBox = CheckUtil::getLargestContourROI(mask, found);
if (!found)
{
cerr << "No contours found!" << endl;
return 4;
}
// 形成 小图分割的检测区域
float fresize_x = img.cols * 1.0f / sz.width;
float fresize_y = img.rows * 1.0f / sz.height;
bigRoi.x = boundingBox.x * fresize_x;
bigRoi.y = boundingBox.y * fresize_y;
bigRoi.width = boundingBox.width * fresize_x;
bigRoi.height = boundingBox.height * fresize_y;
// 使用手动绘制的roi进行校验
if (m_pDetConfig->bUseDrawRoi_Check)
{
double widthDiff = std::abs(bigRoi.width - m_pDetConfig->drawRoi.width) * 1.0f / std::min(bigRoi.width, m_pDetConfig->drawRoi.width);
double heightDiff = std::abs(bigRoi.height - m_pDetConfig->drawRoi.height) * 1.0f / std::min(bigRoi.height, m_pDetConfig->drawRoi.height);
printf("draw roi %s bigRoi %s widthDiff %f heightDiff %f\n", CheckUtil::GetRectString(m_pDetConfig->drawRoi).c_str(), CheckUtil::GetRectString(bigRoi).c_str(), widthDiff, heightDiff);
// 如果差异超过10%,抛出异常
if (widthDiff > 0.10)
{
return 5;
}
if (heightDiff > 0.10)
{
return 5;
}
}
float fresize_x_1 = sz.width * 1.0f / img.cols;
float fresize_y_1 = sz.height * 1.0f / img.rows;
int resize_Small_Roi_width = 320 * fresize_x_1;
int resize_Small_Roi_height = 320 * fresize_y_1;
int haf_w = resize_Small_Roi_width / 2;
int haf_h = resize_Small_Roi_height / 2;
int step_w = resize_Small_Roi_width * 0.85;
int step_h = resize_Small_Roi_height * 0.85;
smallRoiList.clear();
int sizeare = resize_Small_Roi_width * resize_Small_Roi_height;
for (int y = boundingBox.y; y < boundingBox.y + boundingBox.height + haf_h; y += step_h)
{
int roiY = y - haf_h;
for (int x = boundingBox.x; x < boundingBox.x + boundingBox.width + haf_w; x += step_w)
{
int roiX = x - haf_w;
if (roiX < 0)
roiX = 0;
if (roiY < 0)
roiY = 0;
if (roiX + resize_Small_Roi_width >= mask.cols)
roiX = mask.cols - resize_Small_Roi_width;
if (roiY + resize_Small_Roi_height > mask.rows)
roiY = mask.rows - resize_Small_Roi_height;
Rect rect(roiX, roiY, resize_Small_Roi_width, resize_Small_Roi_height);
if (!CheckUtil::RoiInImg(rect, mask))
{
continue;
}
if (roiX >= 0 && roiY >= 0)
{
if (roiX == 0 || roiX + resize_Small_Roi_width == mask.cols)
{
cv::Rect src_Roi;
src_Roi.x = rect.x * fresize_x;
src_Roi.y = rect.y * fresize_y;
src_Roi.width = 320;
src_Roi.height = 320;
smallRoiList.push_back(src_Roi); // 存储ROI的矩形框
// printf("\n\n\n\n\n\n\n=================%d===============\n\n\n\n\n\n\n", smallRoiList.size());
}
else
{
int va = countNonZero(mask(rect));
if (va > 0 && va < sizeare)
{
cv::Rect src_Roi;
src_Roi.x = rect.x * fresize_x;
src_Roi.y = rect.y * fresize_y;
src_Roi.width = 320;
src_Roi.height = 320;
smallRoiList.push_back(src_Roi); // 存储ROI的矩形框
}
}
}
}
}
return 0;
}
Image_Feature_Algin::Image_Feature_Algin()
{
}
Image_Feature_Algin::~Image_Feature_Algin()
{
}
int Image_Feature_Algin::Detect(DetConfig *pDetConfig, Align_Result *pResult, std::vector<std::string> &LogList)
{
// 检测目标:找到 参数模版图到 检测图的 映射关系。包括 缩放和移动。
// 先缩放 在 移动
std::string strlog = "";
if (!pDetConfig)
{
return 1;
}
if (pDetConfig->TemplateImg.empty())
{
strlog = m_PrintLog.printstr(Print_Level_Error, "Image_Align", "TemplateImg is empty ");
LogList.push_back(strlog);
return 1;
}
// 裁切位置;
pResult->Crop_Roi_DetImg = pDetConfig->DetImg_CropROi;
// 1、缩放尺度
float fx = 1;
float fy = 1;
// 裁切尺寸 存在 并合理
if (pDetConfig->param_CropRoi.width > 0 && pDetConfig->param_CropRoi.height > 0 &&
pDetConfig->DetImg_CropROi.width > 0 && pDetConfig->DetImg_CropROi.height > 0)
{
fx = pDetConfig->DetImg_CropROi.width * 1.0f / pDetConfig->param_CropRoi.width;
fy = pDetConfig->DetImg_CropROi.height * 1.0f / pDetConfig->param_CropRoi.height;
if (fx > 0.5 && fx < 2 && fy > 0.5 && fy < 2)
{
pResult->fCropROI_Scale_ParmToDet_X = fx;
pResult->fCropROI_Scale_ParmToDet_Y = fy;
}
else
{
strlog = m_PrintLog.printstr(Print_Level_Error, "Image_Align", "Scale out 0.5--2");
LogList.push_back(strlog);
return 1;
}
}
else
{
strlog = m_PrintLog.printstr(Print_Level_Error, "Image_Align", "crop ROI Error");
LogList.push_back(strlog);
return 1;
}
// strlog = m_PrintLog.printstr(Print_Level_Info, "Image_Align", "Scale x %f y %f\n", fx, fy);
// LogList.push_back(strlog);
// 2、定位
// 1)、模版特征图片的 缩放。
cv::Mat TemplateFeature;
cv::Size sz;
// fx = 1;
// fy = 1;
sz.width = int(pDetConfig->TemplateImg.cols * fx);
sz.height = int(pDetConfig->TemplateImg.rows * fy);
cv::resize(pDetConfig->TemplateImg, TemplateFeature, sz);
if (!CheckUtil::RoiInImg(pDetConfig->Search_Roi, pDetConfig->DetImg))
{
strlog = m_PrintLog.printstr(Print_Level_Error, "Image_Align", "Search_Roi ROI Error Not In img");
LogList.push_back(strlog);
return 1;
}
cv::Mat DetFeature = pDetConfig->DetImg(pDetConfig->Search_Roi).clone();
double confidence = 0;
int kernel_size = 128;
int search_size = 1024;
int det_search_min_size = DetFeature.cols;
if (DetFeature.rows < det_search_min_size)
{
det_search_min_size = DetFeature.rows;
}
int template_kernel_min_size = TemplateFeature.cols;
if (TemplateFeature.rows < template_kernel_min_size)
{
template_kernel_min_size = TemplateFeature.rows;
}
float f_search = search_size * 1.0f / det_search_min_size;
float f_Kernel = kernel_size * 1.0f / template_kernel_min_size;
float falign = f_search;
if (f_Kernel > falign)
{
falign = f_Kernel;
}
cv::Size Search_sz;
Search_sz.width = int(DetFeature.cols * falign);
Search_sz.height = int(DetFeature.rows * falign);
cv::Mat Search_img;
cv::resize(DetFeature, Search_img, Search_sz);
cv::Size Kernel_sz;
Kernel_sz.width = int(TemplateFeature.cols * falign);
Kernel_sz.height = int(TemplateFeature.rows * falign);
cv::Mat Kernel_img;
cv::resize(TemplateFeature, Kernel_img, Kernel_sz);
auto bestMatch = findBestTemplateMatch(Search_img, Kernel_img, confidence);
bestMatch.x /= falign;
bestMatch.y /= falign;
pResult->bestMatch = bestMatch;
if (pDetConfig->bSaveImg)
{
cv::imwrite("Align_template.png", TemplateFeature);
cv::imwrite("Align_Det.png", DetFeature);
}
if (confidence != -1)
{
std::cout << "最佳匹配位置: (" << bestMatch.x << ", " << bestMatch.y
<< "), 得分: " << confidence << std::endl;
if (confidence > pDetConfig->fscore)
{
/* code */
int m_x = pDetConfig->feature_Roi.x * fx - pDetConfig->Search_Roi.x;
int m_y = pDetConfig->feature_Roi.y * fy - pDetConfig->Search_Roi.y;
pResult->offt_x = bestMatch.x - m_x;
pResult->offt_y = bestMatch.y - m_y;
printf("m_x %d bestMatch.x %d offt_x %d\n", m_x, bestMatch.x, pResult->offt_x);
printf("m_y %d bestMatch.y %d offt_y %d\n", m_y, bestMatch.y, pResult->offt_y);
pResult->bDet = true;
pResult->Crop_Roi_ParmImg = pResult->Det_srcToParm_src_Rect(pResult->Crop_Roi_DetImg);
strlog = m_PrintLog.printstr(Print_Level_Info, "Image_Align", " -- Succ :Align score %f > %f offt x %d y %d Scale x %f y %f",
confidence, pDetConfig->fscore, pResult->offt_x, pResult->offt_y, pResult->fCropROI_Scale_ParmToDet_X, pResult->fCropROI_Scale_ParmToDet_Y);
LogList.push_back(strlog);
}
else
{
strlog = m_PrintLog.printstr(Print_Level_Error, "Image_Align", " error :Align score %f< 0.9", confidence);
pResult->fCropROI_Scale_ParmToDet_X = 1;
pResult->fCropROI_Scale_ParmToDet_Y = 1;
LogList.push_back(strlog);
}
}
else
{
pResult->fCropROI_Scale_ParmToDet_X = 1;
pResult->fCropROI_Scale_ParmToDet_Y = 1;
std::cout << "未找到有效匹配" << std::endl;
}
return 0;
}
cv::Point Image_Feature_Algin::findBestTemplateMatch(
const cv::Mat &detectionImage,
const cv::Mat &templateImage,
double &bestScore,
int method)
{
// 输入验证
if (detectionImage.empty() || templateImage.empty())
{
throw std::invalid_argument("输入图像不能为空");
}
if (detectionImage.channels() != 1 || templateImage.channels() != 1)
{
throw std::invalid_argument("必须输入灰度图像");
}
if (templateImage.rows > detectionImage.rows ||
templateImage.cols > detectionImage.cols)
{
throw std::invalid_argument("模板尺寸不能大于被检测图像");
}
// cv::imwrite("detectionImage.png", detectionImage);
// cv::imwrite("templateImage.png", templateImage);
// 执行模板匹配
cv::Mat resultMatrix;
cv::matchTemplate(detectionImage, templateImage, resultMatrix, method);
// 确定极值搜索方式
const bool findMinima = (method == cv::TM_SQDIFF || method == cv::TM_SQDIFF_NORMED);
// 查找极值位置
cv::Point extremaLoc = cv::Point(0, 0);
double extremaVal;
cv::minMaxLoc(resultMatrix,
findMinima ? &extremaVal : nullptr,
findMinima ? nullptr : &extremaVal,
findMinima ? &extremaLoc : nullptr,
findMinima ? nullptr : &extremaLoc);
// 设置有效性检查阈值(可根据方法动态调整)
double threshold = 0.0;
switch (method)
{
case cv::TM_CCOEFF_NORMED:
threshold = 0.6;
break; // [-1, 1]
case cv::TM_CCORR_NORMED:
threshold = 0.7;
break; // [0, 1]
case cv::TM_SQDIFF_NORMED:
threshold = 0.2;
break; // [0, 1]
default:
threshold = 0.0;
}
// 验证匹配有效性
const bool isValid = findMinima ? (extremaVal <= threshold) : (extremaVal >= threshold);
if (isValid)
{
bestScore = extremaVal;
return extremaLoc;
}
bestScore = -1; // 无效时的默认值
return extremaLoc;
}

@ -0,0 +1,476 @@
#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/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_Mark_Det::~AI_Mark_Det()
{
}
int AI_Mark_Det::InitModel_ALL()
{
if (!m_bInitialized)
{
printf("Initialized error \n");
return 1;
}
m_bModelSucc = false;
int re = 0;
re = InitModel();
if (re != 0)
{
printf("InitModel error \n");
m_bModelSucc = false;
}
else
{
m_bModelSucc = true;
}
return 0;
}
int AI_Mark_Det::Detect(const cv::Mat &img, DetConfigResult *pDetConfig)
{
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);
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 = m_pAIDeal->AICheck_MarkLine(temdet, outmask);
// m_pTemCheck->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", "AI Model POL");
// 推理是否成功
if (re != 0)
{
m_pTemCheck->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AI_Mark_Det ", "Error POL AI Model Error");
continue;
}
}
else
{
m_pTemCheck->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AI_Mark_Det ", "Error POL AI Model Error");
continue;
}
if (outmask.empty())
{
m_pTemCheck->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "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->bsaveprocessimg)
{
std::string str12 = "/home/aidlux/BOE/MarkLine/" + std::to_string(pDetConfig->ncamID) + "_" + std::to_string(ki) + "_in.png";
std::string strmask = "/home/aidlux/BOE/MarkLine/" + std::to_string(pDetConfig->ncamID) + "_" + 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->bsaveprocessimg)
{
std::string str12 = "/home/aidlux/BOE/MarkLine/Check_big_" + std::to_string(pDetConfig->ncamID) + "_in.png";
std::string strmask = "/home/aidlux/BOE/MarkLine/Check_big_" + std::to_string(pDetConfig->ncamID) + "_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::InitModel()
{
AIInitConfig config_nf;
config_nf.nGpuIdx = m_pOtherDet_Config->nDeviceId;
config_nf.engine_file_path = str_AI_Mark_Model_Path;
config_nf.bufferList[0].ntype = AIBufferType_IN;
config_nf.bufferList[0].ndatalength = str_AI_Mark_IN_0_DATA_LENGTH;
config_nf.bufferList[0].strName = "0";
config_nf.bufferList[1].ntype = AIBufferType_OUT;
config_nf.bufferList[1].ndatalength = str_AI_Mark_out_0_DATA_LENGTH;
config_nf.bufferList[1].strName = "0";
return m_pAIDeal->Init_MarkLine(config_nf);
}
cv::Rect AI_Mark_Det::GetCutRoi(cv::Rect &roi, const cv::Mat &img)
{
int Dst_Width = str_AI_RE_AD_IN_0_IMAGE_WIDTH;
int Dst_Height = str_AI_RE_AD_IN_0_IMAGE_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_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,649 @@
#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/Second/POL/");
CheckUtil::CreateDir("/home/aidlux/BOE/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_SecondDet::~AI_SecondDet()
{
}
int AI_SecondDet::InitModel_ALL()
{
if (!m_bInitialized)
{
printf("Initialized error \n");
return 1;
}
m_bModelSucc_AD = false;
m_bModelSucc_POL = false;
int re = 0;
re = InitModel_Re_POL();
if (re != 0)
{
printf("InitModel_Re_POL error \n");
m_bModelSucc_POL = false;
}
else
{
m_bModelSucc_POL = true;
}
re = InitModel_Re_AD();
if (re != 0)
{
printf("InitModel_Re_AD error \n");
m_bModelSucc_AD = false;
}
else
{
m_bModelSucc_AD = true;
}
return 0;
}
int AI_SecondDet::Detect(const cv::Mat &img, const cv::Mat &mask, DetConfigResult *pDetConfig)
{
// 二次求面积长度 功能关闭
if (!pDetConfig->pfunction_secondDet->bOpen)
{
m_pTemCheck->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_pTemCheck->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", "Error Size");
return 1;
}
if (!CheckUtil::RoiInImg(AIroi, img))
{
m_pTemCheck->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_pTemCheck->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_pTemCheck->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_pTemCheck->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)
{
detimg123 = mask(AIroi).clone();
}
re12 = Det_Pol(detimg, pDetConfig);
}
if (pDetConfig->qx_type == CONFIG_QX_NAME_AD)
{
if (pDetConfig->pfunction_secondDet->andian_saveProcessImg)
{
detimg123 = mask(AIroi).clone();
}
re12 = Det_AD(detimg, pDetConfig);
}
if (re12 != 0)
{
m_pTemCheck->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE_POL /AD", "Error ");
return 1;
}
return 0;
}
int AI_SecondDet::InitModel_Re_POL()
{
AIInitConfig config_nf;
config_nf.nGpuIdx = m_pOtherDet_Config->nDeviceId;
config_nf.engine_file_path = str_AI_RE_POL_Model_Path;
config_nf.bufferList[0].ntype = AIBufferType_IN;
config_nf.bufferList[0].ndatalength = str_AI_RE_POL_IN_0_DATA_LENGTH;
config_nf.bufferList[0].strName = str_AI_RE_POL_IN_0_IMAGE_Name;
config_nf.bufferList[1].ntype = AIBufferType_OUT;
config_nf.bufferList[1].ndatalength = str_AI_RE_POL_out_0_DATA_LENGTH;
config_nf.bufferList[1].strName = str_AI_RE_POL_out_0_IMAGE_Name;
return m_pAIDeal->Init_RE_POL(config_nf);
}
int AI_SecondDet::InitModel_Re_AD()
{
AIInitConfig config_nf;
config_nf.nGpuIdx = m_pOtherDet_Config->nDeviceId;
config_nf.engine_file_path = str_AI_RE_AD_Model_Path;
config_nf.bufferList[0].ntype = AIBufferType_IN;
config_nf.bufferList[0].ndatalength = str_AI_RE_AD_IN_0_DATA_LENGTH;
config_nf.bufferList[0].strName = str_AI_RE_POL_IN_0_IMAGE_Name;
config_nf.bufferList[1].ntype = AIBufferType_OUT;
config_nf.bufferList[1].ndatalength = str_AI_RE_AD_out_0_DATA_LENGTH;
config_nf.bufferList[1].strName = str_AI_RE_POL_out_0_IMAGE_Name;
return m_pAIDeal->Init_RE_AD(config_nf);
}
cv::Rect AI_SecondDet::GetCutRoi(cv::Rect &roi, const cv::Mat &img)
{
int Dst_Width = str_AI_RE_AD_IN_0_IMAGE_WIDTH;
int Dst_Height = str_AI_RE_AD_IN_0_IMAGE_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)
{
int re = 0;
cv::Mat outimg;
m_pTemCheck->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", " POL start");
// 如果 有面积或长度功能 开启,就进行推理
// if (pDetConfig->pfunction_secondDet->pol_Open_len || pDetConfig->pfunction_secondDet->pol_Open_area)
{
// 模型初始化是否成功
if (m_bModelSucc_POL)
{
re = m_pAIDeal->AICheck_RE_POL(img, outimg);
// m_pTemCheck->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", "AI Model POL");
// 推理是否成功
if (re != 0)
{
m_pTemCheck->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE ", "Error POL AI Model Error");
return 1;
}
}
else
{
m_pTemCheck->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE ", "Error POL AI Model Error");
return 1;
}
}
// else
// {
// m_pTemCheck->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", "POL Param Close ");
// return 1;
// }
if (outimg.empty())
{
m_pTemCheck->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)
{
int re = 0;
cv::Mat outimg;
m_pTemCheck->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", " AD start");
// 如果 有面积或长度功能 开启,就进行推理
// if (pDetConfig->pfunction_secondDet->andian_Open_len || pDetConfig->pfunction_secondDet->andian_Open_area)
{
// 模型初始化是否成功
if (m_bModelSucc_AD)
{
re = m_pAIDeal->AICheck_RE_AD(img, outimg);
// m_pTemCheck->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", "AI Model AD");
// 推理是否成功
if (re != 0)
{
m_pTemCheck->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE ", "Error AD AI Model Error");
return 1;
}
}
else
{
m_pTemCheck->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE ", "Error AD AI Model Error");
return 1;
}
}
// else
// {
// m_pTemCheck->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE Area", "AD Param Close ");
// return 1;
// }
if (outimg.empty())
{
m_pTemCheck->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AICheck_RE ", "Error AD AI Error");
return 1;
}
if (!CheckUtil::RoiInImg(pDetConfig->qx_roi, outimg))
{
m_pTemCheck->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_pTemCheck->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_pTemCheck->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_pTemCheck->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_pTemCheck->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_pTemCheck->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/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;
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,560 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "BlobBase.h"
void pretest(double x)
{
printf("fff %f \n", x);
}
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
//-------------sxg added
void AddErrorScan(ERROR_DOTS_SCAN_ROW *curRow, ERROR_DOTS_SCAN_ROW *prevRow, int x, int len, int y, int difSum, int minArea, int minEng, int mdx, int *pErrClass)
{
if (curRow->scanCount < _MAX_ERROR_SCAN_LINE_PER_ROW)
{
int lastScanLineIndex = curRow->scanCount++;
ERROR_DOTS_SCAN_DATA *scan = curRow->errorScanLineTab + lastScanLineIndex;
scan->x = x;
scan->count = len;
int ex = x + len - 1;
scan->energy = difSum;
scan->area = scan->count;
scan->xposSum = (x + (len >> 1)) * len;
scan->yposSum = y * len;
scan->minx = x;
scan->miny = y;
scan->maxx = ex;
scan->maxy = y;
scan->macro = mdx;
for (int ec = 0; ec < _MAX_ERR_CLASS; ec++)
{
scan->ErrClass[ec] = pErrClass[ec];
}
curRow->macro[scan->macro] = len;
int linkIndexTab[_MAX_ERROR_SCAN_LINE_PER_ROW];
int linkCount = 0;
if (prevRow)
{
for (int t = 0; t < _MAX_MACRO_COUNT; t++)
{
curRow->macro[t] += prevRow->macro[t];
// prevRow->macro[t]=0;
}
int prevLastScanLineIndex = prevRow->scanCount - 1;
ERROR_DOTS_SCAN_DATA *pscan = prevRow->errorScanLineTab + prevLastScanLineIndex;
for (; prevLastScanLineIndex >= 0; --prevLastScanLineIndex, --pscan)
{
int psx = pscan->x - 1;
int pex = psx + pscan->count - 1 + 1;
// sxg modified waitting for valid 9.5
if (x <= pex && ex >= psx)
{
if (pscan->area > 0)
{
int area = scan->area + (pscan->area);
scan->area = area;
if (scan->macro != pscan->macro)
{
if (scan->macro < pscan->macro)
scan->macro = pscan->macro;
}
scan->energy += pscan->energy;
scan->xposSum += pscan->xposSum;
scan->yposSum += pscan->yposSum;
scan->minx = min(scan->minx, pscan->minx);
scan->miny = min(scan->miny, pscan->miny);
scan->maxx = max(scan->maxx, pscan->maxx);
scan->maxy = max(scan->maxy, pscan->maxy);
pscan->area = 0;
pscan->energy = lastScanLineIndex;
for (int ec = 0; ec < _MAX_ERR_CLASS; ec++)
{
scan->ErrClass[ec] = pErrClass[ec] + (pscan->ErrClass[ec]);
}
linkIndexTab[/*0xff & */ (linkCount++)] = prevLastScanLineIndex;
}
// else
//{
// int bindex = 0xff & pscan->energy;
// ERROR_DOTS_SCAN_DATA * hscan = curRow->errorScanLineTab + bindex;
// hscan->count = ex - hscan->x + 1;
// hscan->area += scan->area;
// hscan->energy += scan->energy;
// hscan->xposSum += scan->xposSum;
// hscan->yposSum += scan->yposSum;
// hscan->minx = min(scan->minx , hscan->minx);
// hscan->miny = min(scan->miny , hscan->miny);
// hscan->maxx = max(scan->maxx , hscan->maxx);
// hscan->maxy = max(scan->maxy , hscan->maxy);
// scan->area = 0;
// for(;linkCount > 0 ; --linkCount)
// {
// ERROR_DOTS_SCAN_DATA * p = prevRow->errorScanLineTab + linkIndexTab[0xff & (linkCount - 1)];
// p->energy = bindex;
// }
// curRow->scanCount--;
// break;
// }
}
}
}
}
}
void LinkScanLineToBlob(ERROR_DOTS_BLOBS *blobs, ERROR_DOTS_SCAN_ROW *prevRow, int sx, int sy, int minArea, int minEnergy, int mergeDistanceX, int mergeDistanceY, int width)
{
if (prevRow)
{
int prevLastScanLineIndex = prevRow->scanCount - 1;
ERROR_DOTS_SCAN_DATA *pscan = prevRow->errorScanLineTab + prevLastScanLineIndex;
// int minArea = param->minArea;
// int minEnergy = param->minEnergy;
for (; prevLastScanLineIndex >= 0; --prevLastScanLineIndex, --pscan)
{
if (pscan->area > 0)
{
int x = pscan->xposSum / pscan->area + sx;
int y = pscan->yposSum / pscan->area + sy;
int minx = pscan->minx + sx;
int miny = pscan->miny + sy;
int maxx = pscan->maxx + sx;
int maxy = pscan->maxy + sy;
if (x < width)
{
int blobIndex = blobs->blobCount;
// int mergeDistance = param->mergeDistance;
ERROR_DOTS_BLOB_DATA *pblob = blobs->blobTab + blobIndex - 1;
int left = minx - mergeDistanceX, right = maxx + mergeDistanceX;
int top = miny - mergeDistanceY, bottom = maxy + mergeDistanceY;
for (int i = blobIndex - 1; i >= 0; --i, --pblob)
{
if (1)
{
if (pblob->maxy > top && pblob->miny < bottom)
{
if (pblob->maxx > left && pblob->minx < right)
{
int area = pblob->area + pscan->area;
pblob->x = (pblob->x * pblob->area + x * pscan->area) / area;
pblob->y = (pblob->y * pblob->area + y * pscan->area) / area;
pblob->area = area;
for (int ec = 0; ec < _MAX_ERR_CLASS; ec++)
{
pblob->ErrClass[ec] += pscan->ErrClass[ec];
}
pblob->energy += pscan->energy;
pblob->minx = min(pblob->minx, minx);
pblob->miny = min(pblob->miny, miny);
pblob->maxx = max(pblob->maxx, maxx);
pblob->maxy = max(pblob->maxy, maxy);
pblob->macro[pscan->macro] += prevRow->macro[pscan->macro];
prevRow->macro[pscan->macro] -= pscan->area;
blobIndex = _MAX_ERROR_DOT_BLOB;
break;
}
}
}
}
if (pscan->area > minArea /*|| pscan->energy > minEnergy*/)
{
if (blobIndex < _MAX_ERROR_DOT_BLOB)
{
pblob = blobs->blobTab + blobIndex;
pblob->x = x;
pblob->y = y;
pblob->area = pscan->area;
pblob->energy = pscan->energy;
pblob->minx = minx;
pblob->miny = miny;
pblob->maxx = maxx;
pblob->maxy = maxy;
blobs->blobCount++;
for (int t = 0; t < _MAX_MACRO_COUNT; t++)
{
pblob->macro[t] = 0;
}
pblob->macro[pscan->macro] = pscan->area;
prevRow->macro[pscan->macro] -= pscan->area;
// prevRow->macro[pscan->macro]=0;
for (int ec = 0; ec < _MAX_ERR_CLASS; ec++)
{
pblob->ErrClass[ec] = pscan->ErrClass[ec];
}
}
}
}
}
pscan->area = 0;
for (int ec = 0; ec < _MAX_ERR_CLASS; ec++)
{
pscan->ErrClass[ec] = 0;
}
}
// for (int t=0;t<MAX_MACRO_COUNT;t++)
//{
// //curRow->macro[t]+=prevRow->macro[t];
// prevRow->macro[t]=0;
// }
}
}
void MergeBlob(ERROR_DOTS_BLOBS *blobs, ERROR_DOTS_BLOB_PARAM *param)
{
int count = blobs->blobCount;
ERROR_DOTS_BLOB_DATA *blob = blobs->blobTab + count - 1;
int pace = param->mergeDistance;
for (int i = count - 1; i > 0; --i, --blob)
{
int minx = blob->minx;
int miny = blob->miny;
int maxx = blob->maxx;
int maxy = blob->maxy;
int energy = blob->energy;
int left = minx - pace, right = maxx + pace;
int top = miny - 1, bottom = maxy + 1;
ERROR_DOTS_BLOB_DATA *pblob = blob - 1;
for (int j = i - 1; j >= 0; --j, --pblob)
{
if (1)
{
if (pblob->maxy > top && pblob->miny < bottom)
{
if (pblob->maxx > left && pblob->minx < right)
{
int areaSum = pblob->area + blob->area;
int x = blob->x, y = blob->y;
pblob->x = (pblob->x * pblob->area + x * blob->area) / areaSum;
pblob->y = (pblob->y * pblob->area + y * blob->area) / areaSum;
pblob->area = areaSum;
for (int ec = 0; ec < _MAX_ERR_CLASS; ec++)
{
pblob->ErrClass[ec] += blob->ErrClass[ec];
}
pblob->energy += energy;
pblob->minx = min(pblob->minx, minx);
pblob->miny = min(pblob->miny, miny);
pblob->maxx = max(pblob->maxx, maxx);
pblob->maxy = max(pblob->maxy, maxy);
for (int t = 0; t < _MAX_MACRO_COUNT; t++)
{
pblob->macro[t] += blob->macro[t];
blob->macro[t] = 0;
}
count--;
memmove(blob, blob + 1, (count - i) * sizeof(blob[0]));
break;
}
}
}
}
}
blobs->blobCount = count;
}
// static int __cdecl compareBlob(const void * p1, const void * p2)
static int compareBlob(const void *p1, const void *p2)
{
ERROR_DOTS_BLOB_DATA *b1 = (ERROR_DOTS_BLOB_DATA *)p1;
ERROR_DOTS_BLOB_DATA *b2 = (ERROR_DOTS_BLOB_DATA *)p2;
return (b2->area) - (b1->area);
}
void SortBlob(ERROR_DOTS_BLOBS *blobs)
{
int count = blobs->blobCount;
ERROR_DOTS_BLOB_DATA *blob = blobs->blobTab;
qsort(blob, count, sizeof(blob[0]), compareBlob);
}
int GetBlobsFromImg(ERROR_DOTS_BLOBS *blobs_0, ERROR_DOTS_BLOBS *blobs_1, ERROR_DOTS_BLOBS *blobs_2, unsigned char *pB, unsigned char *pr, unsigned char *pc, int width, int height, int obj)
{
return 0;
}
int GetBlobsFromIm_1(ERROR_DOTS_BLOBS *blobs, unsigned char *pcropdata, unsigned char *pcropConstructdata, unsigned char *pGrayErrordata, unsigned char *pRGBErrordata, int width, int height)
{
return 0;
}
int GetBlobsFromIm_2(ERROR_DOTS_BLOBS *blobs, unsigned char *pcropdata, unsigned char *pcropConstructdata, unsigned char *pGrayErrordata, unsigned char *pRGBErrordata, unsigned char *pGrayMaskdata, int width, int height, int ndiffValueT)
{
return 0;
}
int GetBlobsFromIm_All(ERROR_DOTS_BLOBS *blobs, unsigned char *pcropdata, unsigned char *pcropConstructdata, unsigned char *pGrayErrordata, unsigned char *pRGBErrordata, unsigned char *pGrayMaskdata, int width, int height, int ndiffValueT)
{
return 0;
}
int GetBlobsFromIm_single(ERROR_DOTS_BLOBS *blobs, unsigned char *pcropdata, unsigned char *pcropConstructdata, unsigned char *pErrordata, int nstartPos, int nstep, int npitch, int nErrorType, unsigned char *pGrayMaskdata, int width, int height, int ndiffValueT)
{
return 0;
}
int GetBlobsFromIm_All_onemask(ERROR_DOTS_BLOBS *blobs, unsigned char *pcropdata, unsigned char *pRGBErrordata, unsigned char *pGrayMaskdata, int width, int height, int ndiffValueT)
{
return 0;
}
int GetBlobsFromIm_single_onemask(ERROR_DOTS_BLOBS *blobs, unsigned char *pcropdata, unsigned char *pErrordata, int AndValue, int npitch, int nErrorType, unsigned char *pGrayMaskdata, int width, int height, int ndiffValueT)
{
return 0;
}
// 当前行和前面行合并
void AddErrorScan_New(ERROR_DOTS_SCAN_ROW *curRow, ERROR_DOTS_SCAN_ROW *prevRow, int x, int len, int y, int difSum, int minArea, int minEng, int errorType)
{
if (curRow->scanCount < _MAX_ERROR_SCAN_LINE_PER_ROW)
{
int lastScanLineIndex = curRow->scanCount++;
ERROR_DOTS_SCAN_DATA *scan = curRow->errorScanLineTab + lastScanLineIndex;
scan->x = x;
scan->count = len;
int ex = x + len - 1;
scan->energy = difSum;
scan->area = scan->count;
scan->xposSum = (x + (len >> 1)) * len;
scan->yposSum = y * len;
scan->minx = x;
scan->miny = y;
scan->maxx = ex;
scan->maxy = y;
scan->type = errorType;
if (prevRow)
{
int prevLastScanLineIndex = prevRow->scanCount - 1;
ERROR_DOTS_SCAN_DATA *pscan = prevRow->errorScanLineTab + prevLastScanLineIndex;
for (; prevLastScanLineIndex >= 0; --prevLastScanLineIndex, --pscan)
{
int psx = pscan->x - 1;
int pex = psx + pscan->count - 1 + 1;
if (x <= pex && ex >= psx && pscan->type == scan->type)
{
if (pscan->area > 0)
{
int area = scan->area + (pscan->area);
scan->area = area;
scan->energy += pscan->energy;
scan->xposSum += pscan->xposSum;
scan->yposSum += pscan->yposSum;
scan->minx = min(scan->minx, pscan->minx);
scan->miny = min(scan->miny, pscan->miny);
scan->maxx = max(scan->maxx, pscan->maxx);
scan->maxy = max(scan->maxy, pscan->maxy);
pscan->area = 0;
pscan->energy = lastScanLineIndex;
}
}
}
}
}
}
void LinkScanLineToBlob_New(ERROR_DOTS_BLOBS *blobs, ERROR_DOTS_SCAN_ROW *prevRow, int sx, int sy, int minArea, int minEnergy, int mergeDistanceX, int mergeDistanceY, int width)
{
if (prevRow)
{
int prevLastScanLineIndex = prevRow->scanCount - 1;
ERROR_DOTS_SCAN_DATA *pscan = prevRow->errorScanLineTab + prevLastScanLineIndex;
// int minArea = param->minArea;
// int minEnergy = param->minEnergy;
for (; prevLastScanLineIndex >= 0; --prevLastScanLineIndex, --pscan)
{
if (pscan->area > 0)
{
int x = pscan->xposSum / pscan->area + sx;
int y = pscan->yposSum / pscan->area + sy;
int minx = pscan->minx + sx;
int miny = pscan->miny + sy;
int maxx = pscan->maxx + sx;
int maxy = pscan->maxy + sy;
if (x < width)
{
int blobIndex = blobs->blobCount;
// int mergeDistance = param->mergeDistance;
ERROR_DOTS_BLOB_DATA *pblob = blobs->blobTab + blobIndex - 1;
int left = minx - mergeDistanceX, right = maxx + mergeDistanceX;
int top = miny - mergeDistanceY, bottom = maxy + mergeDistanceY;
for (int i = blobIndex - 1; i >= 0; --i, --pblob)
{
if (pblob->ErrType == pscan->type)
{
if (pblob->maxy > top && pblob->miny < bottom)
{
if (pblob->maxx > left && pblob->minx < right)
{
int area = pblob->area + pscan->area;
pblob->x = (pblob->x * pblob->area + x * pscan->area) / area;
pblob->y = (pblob->y * pblob->area + y * pscan->area) / area;
pblob->area = area;
// for (int ec = 0; ec < _MAX_ERR_CLASS; ec++)
// {
// pblob->ErrClass[ec] += pscan->ErrClass[ec];
// }
pblob->energy += pscan->energy;
pblob->minx = min(pblob->minx, minx);
pblob->miny = min(pblob->miny, miny);
pblob->maxx = max(pblob->maxx, maxx);
pblob->maxy = max(pblob->maxy, maxy);
// pblob->macro[pscan->macro] += prevRow->macro[pscan->macro];
// prevRow->macro[pscan->macro] -= pscan->area;
blobIndex = _MAX_ERROR_DOT_BLOB;
break;
}
}
}
}
if (pscan->area > minArea /*|| pscan->energy > minEnergy*/)
{
if (blobIndex < _MAX_ERROR_DOT_BLOB)
{
pblob = blobs->blobTab + blobIndex;
pblob->x = x;
pblob->y = y;
pblob->area = pscan->area;
pblob->energy = pscan->energy;
pblob->ErrType = pscan->type;
pblob->minx = minx;
pblob->miny = miny;
pblob->maxx = maxx;
pblob->maxy = maxy;
blobs->blobCount++;
// for (int t = 0; t < _MAX_MACRO_COUNT; t++)
// {
// pblob->macro[t] = 0;
// }
// pblob->macro[pscan->macro] = pscan->area;
// prevRow->macro[pscan->macro] -= pscan->area;
// prevRow->macro[pscan->macro]=0;
// for (int ec = 0; ec < _MAX_ERR_CLASS; ec++)
// {
// pblob->ErrClass[ec] = pscan->ErrClass[ec];
// }
}
}
}
}
pscan->area = 0;
for (int ec = 0; ec < _MAX_ERR_CLASS; ec++)
{
pscan->ErrClass[ec] = 0;
}
}
// for (int t=0;t<MAX_MACRO_COUNT;t++)
//{
// //curRow->macro[t]+=prevRow->macro[t];
// prevRow->macro[t]=0;
// }
}
}
int GetBlobs_V2(ERROR_DOTS_BLOBS *blobs, unsigned char *pImgdata, unsigned char *pErrordata, int width, int height, int basev, int minArea)
{
if (blobs == NULL || pErrordata == NULL)
{
return 1;
}
int pitch = width;
int offset;
int point_is_err = 0;
int wLineErrsList = 0;
int errPos_xList = 0;
int difSumList = 0;
int point_is_errList = 0;
// memset(blobs, 0x00, sizeof(ERROR_DOTS_BLOBS));
ERROR_DOTS_SCAN_ROW rowDataTab[2];
ERROR_DOTS_SCAN_ROW *curRow = 0;
ERROR_DOTS_SCAN_ROW *prevRow = 0;
int MIN_AREA = minArea;
if (minArea <= 0)
{
MIN_AREA = 10;
}
int minEnergy = 2;
int mergeDistanceX = 1;
int mergeDistanceY = 1;
offset = 0;
int nErrorType = 0;
int lasttype = -1;
for (int y = 0; y < height; y++)
{
wLineErrsList = 0;
difSumList = 0;
curRow = rowDataTab + (y & 1);
curRow->scanCount = 0;
offset = y * pitch - 1;
nErrorType = -1;
lasttype = -1;
int kh = 0;
for (int x = 0; x < width; x++)
{
offset++;
point_is_err = 0;
if (pErrordata[offset] != 0 && pImgdata[offset] > basev)
{
point_is_err = 1;
difSumList += 1;
wLineErrsList++;
errPos_xList = x;
kh = 1;
}
else // 没有残点 所有缺陷都需要判断是否截止
{
// 当前点 该缺陷类型 为FALSE 并且 改缺陷类型 有过残点
if (wLineErrsList > 0)
{
AddErrorScan_New(curRow, prevRow, errPos_xList - wLineErrsList + 1, wLineErrsList, y, difSumList, 0, 0, ERR_TYPE_1);
wLineErrsList = 0;
difSumList = 0;
}
kh = 0;
}
if (x == width - 1)
{
if (wLineErrsList > 0)
{
AddErrorScan_New(curRow, prevRow, errPos_xList - wLineErrsList + 1, wLineErrsList, y, difSumList, 0, 0, ERR_TYPE_1);
}
}
}
LinkScanLineToBlob_New(blobs, prevRow, 0, 0, MIN_AREA, minEnergy, mergeDistanceX, mergeDistanceY, width);
prevRow = curRow;
}
LinkScanLineToBlob_New(blobs, prevRow, 0, 0, MIN_AREA, minEnergy, mergeDistanceX, mergeDistanceY, width);
ERROR_DOTS_BLOB_PARAM blobParam;
memset(&blobParam, 0x00, sizeof(ERROR_DOTS_BLOB_PARAM));
blobParam.mergeDistance = 1;
MergeBlob(blobs, &blobParam);
SortBlob(blobs);
return 0;
}

@ -0,0 +1,56 @@
#include "CUDA_Det.cuh"
__global__ void test_print()
{
printf("Hello World!\n");
int index = threadIdx.z * blockDim.x * blockDim.y +
threadIdx.y * blockDim.x +
threadIdx.x;
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
printf("blockIdx.x %d blockDim.x %d, threadIdx.x %d\n", blockIdx.x, blockDim.x, threadIdx.x);
printf("block idx: (%3d, %3d, %3d), thread idx: %3d, cord: (%3d, %3d)\n",
blockIdx.z, blockIdx.y, blockIdx.x,
index, x, y);
}
__global__ void ucharToFloat(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(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 wrap_test_print()
{
test_print<<<5, 6>>>();
cudaDeviceSynchronize();
return;
}
void Cuda_ucharToFloat(const unsigned char *input, float *output, int size)
{
cudaDeviceSynchronize();
int blockSize = 1024;
int numBlocks = (size + blockSize - 1) / blockSize;
ucharToFloat<<<numBlocks, blockSize>>>(input, output, size);
}
void Cuda_FloatTouchar(const float *input, unsigned char *output, int size)
{
cudaDeviceSynchronize();
int blockSize = 1024;
int numBlocks = (size + blockSize - 1) / blockSize;
floatToUchar<<<numBlocks, blockSize>>>(input, output, size);
}

File diff suppressed because it is too large Load Diff

@ -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,566 @@
/*
* FileName:CoreLogicFactory.cpp
* Version:V1.0
* Description:
* Created On:Mon Sep 10 11:13:16 UTC 2018
* Modified date:
* Author:Sky
*/
#include "CheckUtil.hpp"
#include <sys/time.h>
#include <stdio.h>
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string>
#include <sstream>
#include <sys/statfs.h>
#include <stdlib.h>
#include <fstream>
#include <thread>
#include "snowflake.hpp"
int _sysmkdir_2(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_2(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;
}
long CheckUtil::getcurTime()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return ((long)tv.tv_sec) * 1000 + ((long)tv.tv_usec) / 1000;
}
std::string CheckUtil::Op_float2String(float nvalue)
{
char buffer[20];
sprintf(buffer, "%.1f", nvalue);
std::string st1 = buffer;
return st1;
}
int64_t CheckUtil::getSnowId()
{
using snowflake_t = snowflake<1534832906275L, std::mutex>;
static snowflake_t uuid;
static bool bInit = false;
if (!bInit)
{
uuid.init(1, 1);
bInit = true;
}
return uuid.nextid();
return 0;
}
bool CheckUtil::JudgRect(cv::Rect roi, int img_w, int img_h)
{
if (img_w <= 0 || img_h <= 0)
{
return false;
}
if (roi.x < 0 || roi.x >= img_w)
{
return false;
}
if (roi.width <= 0 || roi.width >= img_w)
{
return false;
}
if (roi.y < 0 || roi.y >= img_h)
{
return false;
}
if (roi.height <= 0 || roi.height >= img_h)
{
return false;
}
if (roi.x + roi.width >= img_w)
{
return false;
}
if (roi.y + roi.height >= img_h)
{
return false;
}
return true;
}
bool CheckUtil::JudgRect_SZ(cv::Rect roi, int w, int h)
{
if (roi.x < 0 || roi.x >= w)
{
return false;
}
if (roi.width <= 0 || roi.width != w)
{
return false;
}
if (roi.y < 0 || roi.y >= h)
{
return false;
}
if (roi.height <= 0 || roi.height != h)
{
return false;
}
return true;
}
bool CheckUtil::compareIgnoreCase(const std::string &str1, const std::string &str2)
{
// 将 str1 和 str2 转换为小写后进行比较
std::string lower_str1 = str1;
std::string lower_str2 = str2;
// 使用 std::transform 将字符串转换为小写
std::transform(lower_str1.begin(), lower_str1.end(), lower_str1.begin(), ::tolower);
std::transform(lower_str2.begin(), lower_str2.end(), lower_str2.begin(), ::tolower);
// 比较两个转换后的字符串
return lower_str1 == lower_str2;
}
bool CheckUtil::RoiInImg(cv::Rect roi, cv::Mat img)
{
if (roi.width <= 0 || roi.height <= 0)
{
return false;
}
if ((roi & cv::Rect(0, 0, img.cols, img.rows)) == roi)
{
return true;
}
return false;
}
int CheckUtil::printROI(cv::Rect roi, std::string str)
{
printf("%s x %d y %d w %d h %d\n", str.c_str(), roi.x, roi.y, roi.width, roi.height);
return 0;
}
float CheckUtil::CalIoU(cv::Rect rect1, cv::Rect rect2)
{
// 计算交集区域
cv::Rect intersection = rect1 & rect2;
// 计算并集区域
cv::Rect union_rect = rect1 | rect2;
// 计算交集区域和并集区域的面积
double intersection_area = intersection.area();
double union_area = union_rect.area();
// 计算IoU值
double iou = intersection_area / union_area;
return iou;
}
float CheckUtil::CalRoi2RoiPre(cv::Rect rect1, cv::Rect rect2)
{
// 计算交集区域
cv::Rect intersection = rect1 & rect2;
// 计算并集区域
cv::Rect union_rect = rect1;
// 计算交集区域和并集区域的面积
double intersection_area = intersection.area();
double union_area = union_rect.area();
double iou = 0;
if (union_area != 0)
{
iou = intersection_area / union_area;
}
// 计算IoU值
return iou;
}
float CheckUtil::CalIoU_t(cv::Rect rect1, cv::Rect rect2)
{
// 计算交集区域
cv::Rect intersection = rect1 & rect2;
// 计算并集区域
cv::Rect union_rect = rect1;
// 计算交集区域和并集区域的面积
double intersection_area = intersection.area();
double union_area = union_rect.area();
// 计算IoU值
double iou = intersection_area / union_area;
return iou;
}
int CheckUtil::CheckRect(cv::Rect &roi, int img_w, int img_h)
{
if (roi.x < 0 || roi.x >= img_w)
{
roi.x = 0;
}
if (roi.y < 0 || roi.y >= img_h)
{
roi.y = 0;
}
if (roi.width <= 0 || roi.width > img_w)
{
roi.width = 1;
}
if (roi.height <= 0 || roi.height > img_h)
{
roi.height = 1;
}
if (roi.x + roi.width > img_w)
{
roi.x = img_w - roi.width;
if (roi.x < 0)
{
roi.x = 0;
roi.width = img_w;
}
}
if (roi.y + roi.height > img_h)
{
roi.y = img_h - roi.height;
if (roi.y < 0)
{
roi.y = 0;
roi.height = img_h;
}
}
return 0;
}
int CheckUtil::SizeRect(cv::Rect &roi, int img_w, int img_h, int addw, int addh)
{
if (roi.width + 2 * addw > img_w)
{
return 1;
}
if (roi.height + 2 * addh > img_h)
{
return 1;
}
int sx = roi.x - addw;
int ex = roi.x + roi.width + addw;
if (sx < 0)
{
sx = 0;
}
if (ex > img_w)
{
ex = img_w;
}
int sy = roi.y - addh;
int ey = roi.y + roi.height + addh;
if (sy < 0)
{
sy = 0;
}
if (ey > img_h)
{
ey = img_h;
}
roi.x = sx;
roi.width = ex - sx;
roi.y = sy;
roi.height = ey - sy;
return 0;
}
float CheckUtil::CalImgBrightness(cv::Mat imgRoi)
{
if (imgRoi.empty())
{
return 0.0f;
}
cv::Mat mat_mean, mat_stddev;
cv::meanStdDev(imgRoi, mat_mean, mat_stddev); // 求灰度图像的均值、均方差
float m = mat_mean.at<double>(0, 0);
return m;
}
float CheckUtil::Cal2PointAngle(cv::Point p_left, cv::Point p_right)
{
double angle = std::atan2(p_left.y - p_right.y, p_right.x - p_left.x);
return angle * 180 / 3.1415926;
}
cv::Rect CheckUtil::getLargestContourROI(const cv::Mat &binaryImg, bool &found)
{
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
// 查找轮廓
cv::findContours(binaryImg.clone(), contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
found = false;
if (contours.empty())
{
return cv::Rect(); // 返回空Rect
}
// 找到面积最大的轮廓
double maxArea = 0;
int maxAreaIdx = -1;
for (size_t i = 0; i < contours.size(); i++)
{
double area = cv::contourArea(contours[i]);
if (area > maxArea)
{
maxArea = area;
maxAreaIdx = i;
}
}
// 如果没有找到有效轮廓比如所有轮廓面积都为0
if (maxAreaIdx == -1 || maxArea <= 0)
{
return cv::Rect();
}
found = true;
// 返回最大轮廓的边界矩形
return cv::boundingRect(contours[maxAreaIdx]);
}
std::string CheckUtil::GetRectString(cv::Rect rect)
{
std::string str = "[" + std::to_string(rect.x) + "," + std::to_string(rect.y) + "," + std::to_string(rect.width) + "," + std::to_string(rect.height) + "]";
return str;
}
int CheckUtil::CreateDir(const std::string &dir)
{
int ret = 0;
if (dir.empty())
return -1;
std::string pdir;
if ((ret = _sysmkdir_2(dir)) == -1)
{
pdir = __getParentDir_2(dir);
if ((ret = CreateDir(pdir)) == 0)
{
ret = CreateDir(dir);
}
}
return ret;
}
bool CheckUtil::bcalDis(cv::Point p1, cv::Point p2, int disT)
{
double dis = std::sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
if (dis < disT)
return true;
return false;
}
double CheckUtil::calDis(cv::Point p1, cv::Point p2)
{
double dis = std::sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
return dis;
}
void CheckUtil::PrintRect(cv::Rect roi, std::string str)
{
printf("%s x %d y %d w %d h %d \n", str.c_str(), roi.x, roi.y, roi.width, roi.height);
}
int CheckUtil::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)
{
if (img.empty())
{
printf("error >>>> img.empty \n");
return 1;
/* code */
}
if (!RoiInImg(config_roi, img))
{
printf("error >>>> roi != img size \n");
return 2;
}
if (config_SmallImg_Width <= 0 ||
config_SmallImg_Height <= 0 ||
config_SmallImg_Width > img.cols ||
config_SmallImg_Height > img.rows)
{
printf("error >>>>config_SmallImg_Width %d config_SmallImg_Height %d \n ", config_SmallImg_Width, config_SmallImg_Height);
return 3;
}
if (config_MinOverlap_Width < 0 ||
config_MinOverlap_Height < 0 ||
config_MinOverlap_Width > img.cols ||
config_MinOverlap_Height > img.rows ||
config_MinOverlap_Width >= config_SmallImg_Width ||
config_MinOverlap_Height >= config_SmallImg_Height)
{
printf("error >>>>config_MinOverlap_Width %d config_MinOverlap_Height %d \n ", config_MinOverlap_Width, config_MinOverlap_Height);
return 4;
}
int AI_Img_width = config_SmallImg_Width;
int AI_Img_height = config_SmallImg_Height;
int start_x = config_roi.x;
int start_y = config_roi.y;
int end_x = config_roi.width + config_roi.x;
int end_y = config_roi.height + config_roi.y;
// 有效图片 宽 高
int det_width = config_roi.width;
int det_height = config_roi.height;
if (AI_Img_width > det_width || AI_Img_height > det_height)
{
printf("error >>>>config_SmallImg_Width %d != roi width %d \n ", config_SmallImg_Width, det_width);
printf("error >>>>config_SmallImg_Height %d != roi height %d \n ", config_SmallImg_Height, det_height);
return 5;
}
// printf("config_SmallImg_Width %d config_SmallImg_Height %d \n ", config_SmallImg_Width, config_SmallImg_Height);
// printf("config_MinOverlap_Width %d config_MinOverlap_Height %d \n ", config_MinOverlap_Width, config_MinOverlap_Height);
/////////////////、计算宽度方向 块的个数 和 重叠 ///////////////////////
// 可分为多少块 宽度度方向
float fBlocknum_x = det_width * 1.0f / AI_Img_width;
// 块的个数
int nBlocknum_x = std::ceil(fBlocknum_x);
// 如果 有重叠要求
if (config_MinOverlap_Width >= 0)
{
float fconfig_BlocknuNum_x = (det_width - AI_Img_width) * 1.0f / (config_SmallImg_Width - config_MinOverlap_Width) + 1;
int nconfig_BlocknuNum_x = std::ceil(fconfig_BlocknuNum_x);
if (nBlocknum_x < nconfig_BlocknuNum_x)
{
nBlocknum_x = nconfig_BlocknuNum_x;
}
}
int use_MinOverlap_Width = 0;
// 计算重叠率
if (nBlocknum_x > 1)
{
// 有多个块,要判断 块的重叠是否满足要求
int nSumLen_x = nBlocknum_x * AI_Img_width; //
float fOverlap_x = (nSumLen_x - det_width) * 1.0f / (nBlocknum_x - 1);
use_MinOverlap_Width = int(fOverlap_x);
}
// printf("nBlocknum_x %d use_MinOverlap_Width %d \n", nBlocknum_x, use_MinOverlap_Width);
/////////////////、计算高度方向 块的个数 和 重叠 ///////////////////////
// 可分为多少块 高度方向
float fBlocknum_y = det_height * 1.0f / AI_Img_height;
// 块的个数
int nBlocknum_y = std::ceil(fBlocknum_y);
// 如果 有重叠要求
if (config_MinOverlap_Height >= 0)
{
float fconfig_BlocknuNum_y = (det_height - AI_Img_height) * 1.0f / (config_SmallImg_Height - config_MinOverlap_Height) + 1;
int nconfig_BlocknuNum_y = std::ceil(fconfig_BlocknuNum_y);
if (nBlocknum_y < nconfig_BlocknuNum_y)
{
nBlocknum_y = nconfig_BlocknuNum_y;
}
}
int use_MinOverlap_Height = 0;
// 计算重叠率
if (nBlocknum_y > 1)
{
// 有多个块,要判断 块的重叠是否满足要求
int nSumLen_y = nBlocknum_y * AI_Img_height; //
float fOverlap_y = (nSumLen_y - det_height) * 1.0f / (nBlocknum_y - 1);
use_MinOverlap_Height = int(fOverlap_y);
}
// printf("nBlocknum_y %d use_MinOverlap_Height %d \n", nBlocknum_y, use_MinOverlap_Height);
int cut_sy = start_y;
int cut_ey = start_y + 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;
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;
}
}
return 0;
}

@ -0,0 +1,685 @@
/*
* @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 "DrawImg.h"
#include "QX_Analysis.h"
DrawImg::DrawImg()
{
m_bstatus_ReJson = false;
}
DrawImg::~DrawImg()
{
}
int DrawImg::DrawResult(std::shared_ptr<CheckResult> &result)
{
if (result->resultimg.channels() == 1)
{
cv::cvtColor(result->resultimg, result->resultimg, cv::COLOR_GRAY2RGB); // 彩色 可选项
}
cv::Mat image_draw = result->resultimg;
m_drawList.erase(m_drawList.begin(), m_drawList.end());
m_drawList.clear();
for (int i = 0; i < result->qxImageResult.size(); i++)
{
DrawInfoImg_Src(image_draw, result->qxImageResult.at(i).resizeImgroi,
result->qxImageResult.at(i).idx,
result->qxImageResult.at(i).type,
result->qxImageResult.at(i).area,
result->qxImageResult.at(i).energy,
result->qxImageResult.at(i).max_v,
result->qxImageResult.at(i).hj,
result->qxImageResult.at(i).len,
Draw_Type_NG, result->qxImageResult.at(i).strTypeName, result->qxImageResult.at(i).qx_Code,
result->qxImageResult.at(i).qx_type,
result->qxImageResult.at(i).qx_num,
result->qxImageResult.at(i).density, m_bstatus_ReJson);
// DrawInfoImg(src_draw, result->qxImageResult.at(i).srcImgroi, result->qxImageResult.at(i).type, result->qxImageResult.at(i).area);
if (result->qxImageResult.at(i).srcImg.channels() == 1)
{
cv::cvtColor(result->qxImageResult.at(i).srcImg, result->qxImageResult.at(i).srcImg, cv::COLOR_GRAY2RGB); // 彩色 可选项
}
DrawInfoImg(result->qxImageResult.at(i).srcImg,
result->qxImageResult.at(i).CutImgroi,
result->qxImageResult.at(i).idx,
result->qxImageResult.at(i).type,
result->qxImageResult.at(i).area,
result->qxImageResult.at(i).energy,
result->qxImageResult.at(i).max_v,
result->qxImageResult.at(i).hj,
result->qxImageResult.at(i).len,
Draw_Type_NG, result->qxImageResult.at(i).strTypeName,
result->qxImageResult.at(i).qx_Code,
result->qxImageResult.at(i).qx_type,
result->qxImageResult.at(i).qx_num,
result->qxImageResult.at(i).density, m_bstatus_ReJson);
}
for (int i = 0; i < result->YS_ImageResult.size(); i++)
{
DrawInfoImg_Src(image_draw, result->YS_ImageResult.at(i).resizeImgroi, result->YS_ImageResult.at(i).idx,
result->YS_ImageResult.at(i).type,
result->YS_ImageResult.at(i).area,
result->YS_ImageResult.at(i).energy,
result->YS_ImageResult.at(i).max_v,
result->YS_ImageResult.at(i).hj,
result->YS_ImageResult.at(i).len,
Draw_Type_YS, result->YS_ImageResult.at(i).strTypeName,
result->YS_ImageResult.at(i).qx_Code,
result->YS_ImageResult.at(i).qx_type,
result->YS_ImageResult.at(i).qx_num,
result->YS_ImageResult.at(i).density, m_bstatus_ReJson);
// DrawInfoImg(src_draw, result->qxImageResult.at(i).srcImgroi, result->qxImageResult.at(i).type, result->qxImageResult.at(i).area);
if (result->YS_ImageResult.at(i).srcImg.channels() == 1)
{
cv::cvtColor(result->YS_ImageResult.at(i).srcImg, result->YS_ImageResult.at(i).srcImg, cv::COLOR_GRAY2RGB); // 彩色 可选项
}
DrawInfoImg(result->YS_ImageResult.at(i).srcImg,
result->YS_ImageResult.at(i).CutImgroi,
result->YS_ImageResult.at(i).idx,
result->YS_ImageResult.at(i).type,
result->YS_ImageResult.at(i).area,
result->YS_ImageResult.at(i).energy,
result->YS_ImageResult.at(i).max_v,
result->YS_ImageResult.at(i).hj,
result->YS_ImageResult.at(i).len,
Draw_Type_YS, result->YS_ImageResult.at(i).strTypeName,
result->YS_ImageResult.at(i).qx_Code,
result->YS_ImageResult.at(i).qx_type,
result->YS_ImageResult.at(i).qx_num,
result->YS_ImageResult.at(i).density, m_bstatus_ReJson);
}
return 0;
}
int DrawImg::DrawInfoImg(cv::Mat &img, cv::Rect roi, int blobidx, int type, float fArea, float fenerge, float fmaxv, float fhj, float flen, Draw_Type drayType, std::string strqx_error, std::string strqx_code, int qx_type, int qx_num, float mindis, bool bqxroi)
{
cv::Point pc;
pc.x = roi.x;
pc.y = roi.y;
cv::Rect src_Roi = roi;
roi.x -= 5;
roi.y -= 5;
roi.width += 10;
roi.height += 10;
if (roi.x < 0)
{
roi.x = 0;
}
if (roi.y < 0)
{
roi.y = 0;
}
// printf("roi %s \n", CheckUtil::GetRectString(roi).c_str());
if (roi.x + roi.width > img.cols)
{
roi.width = img.cols - roi.x;
if (roi.width <= 0)
{
roi.width = 1;
}
}
if (roi.y + roi.height > img.rows)
{
roi.height = img.rows - roi.y;
if (roi.height <= 0)
{
roi.height = 1;
}
}
if (bqxroi)
{
cv::Scalar roicolor = cv::Scalar(0, 0, 255);
switch (drayType)
{
case Draw_Type_NG:
roicolor = cv::Scalar(0, 0, 255);
break;
case Draw_Type_YS:
roicolor = cv::Scalar(128, 0, 0);
break;
case Draw_Type_Other:
roicolor = cv::Scalar(0, 120, 120);
break;
default:
break;
}
cv::rectangle(img, roi, roicolor);
}
char buffer[128];
// sprintf(buffer, " A:%.1f E:%.1f", result->qxiImageResult.at(i).area, result->qxiImageResult.at(i).energy);
// sprintf(buffer, " A:%.1f E:%.1f HJ:%.1f", result->qxiImageResult.at(i).area, result->qxiImageResult.at(i).energy, result->qxiImageResult.at(i).hj);
sprintf(buffer, "%d T:%d %s %s qx %d %d m:%.1f\nA:%.2f E:%.1f Mv:%.1f hj:%.1f len %.1f", blobidx, type, strqx_error.c_str(), strqx_code.c_str(), qx_type, qx_num, mindis, fArea, fenerge, fmaxv, fhj, flen);
std::string st1 = buffer;
std::string text = st1;
// 按行分割文本
std::vector<std::string> lines;
size_t pos = 0;
while ((pos = text.find("\n")) != std::string::npos)
{
lines.push_back(text.substr(0, pos));
text.erase(0, pos + 1);
}
lines.push_back(text);
int baseline;
// 获取文本框的长宽
cv::Size text_size = cv::getTextSize(text, font_face, font_scale, thickness, &baseline);
cv::Rect droi;
droi.width = text_size.width;
droi.height = text_size.height;
// 输出每一行文本
int lineHeight = text_size.height + baseline;
droi.height = lineHeight;
int line_one_y = 0;
int linenum = lines.size() - 1;
bool bdrawroi = true;
if (lines.size() <= 0)
{
return 0;
}
cv::Rect drawRoi;
drawRoi.x = pc.x;
drawRoi.y = pc.y;
drawRoi.width = text_size.width;
drawRoi.height = text_size.height * lines.size();
{
for (size_t i = 0; i < lines.size(); ++i)
{
// 将文本框居中绘制
cv::Point origin = cv::Point(drawRoi.x, drawRoi.y + (i + 1) * (text_size.height));
double temfont_scale = font_scale * 0.6;
if (drayType == Draw_Type_NG)
{
if (qx_type == QX_ERROR_TYPE_NUM_RGB255)
{
cv::putText(img, lines[i], origin, font_face, temfont_scale, cv::Scalar(80, 128, 100), thickness, 1, 0);
}
else
{
cv::putText(img, lines[i], origin, font_face, temfont_scale, cv::Scalar(0, 255, 0), thickness, 1, 0);
}
}
else
{
if (drayType == Draw_Type_Other)
{
cv::putText(img, lines[i], origin, font_face, temfont_scale, cv::Scalar(0, 182, 185), thickness, 1, 0);
}
else
{
cv::putText(img, lines[i], origin, font_face, temfont_scale, cv::Scalar(128, 125, 0), thickness, 1, 0);
}
}
}
}
return 0;
}
int DrawImg::DrawInfoImg_Src(cv::Mat &img, cv::Rect roi, int blobidx, int type, float fArea, float fenerge, float fmaxv, float fhj, float flen, Draw_Type drayType, std::string strqx_error, std::string strqx_code, int qx_type, int qx_num, float mindis, bool bqxroi)
{
cv::Point pc;
pc.x = roi.x;
pc.y = roi.y;
cv::Rect src_Roi = roi;
roi.x -= 5;
roi.y -= 5;
roi.width += 10;
roi.height += 10;
if (roi.x < 0)
{
roi.x = 0;
}
if (roi.y < 0)
{
roi.y = 0;
}
// printf("roi %s \n", CheckUtil::GetRectString(roi).c_str());
if (roi.x + roi.width > img.cols)
{
roi.width = img.cols - roi.x;
if (roi.width <= 0)
{
roi.width = 1;
}
}
if (roi.y + roi.height > img.rows)
{
roi.height = img.rows - roi.y;
if (roi.height <= 0)
{
roi.height = 1;
}
}
if (bqxroi)
{
cv::Scalar roicolor = cv::Scalar(0, 0, 255);
switch (drayType)
{
case Draw_Type_NG:
roicolor = cv::Scalar(0, 0, 255);
break;
case Draw_Type_YS:
roicolor = cv::Scalar(128, 0, 0);
break;
case Draw_Type_Other:
roicolor = cv::Scalar(0, 120, 120);
break;
default:
break;
}
cv::rectangle(img, roi, roicolor);
}
char buffer[128];
if (drayType == Draw_Type_NG)
{
sprintf(buffer, "%d T:%d %s %s qx %d %d m:%.1f\nA:%.2f E:%.1f Mv:%.1f hj:%.1f len %.1f", blobidx, type, strqx_error.c_str(), strqx_code.c_str(), qx_type, qx_num, mindis, fArea, fenerge, fmaxv, fhj, flen);
}
else
{
sprintf(buffer, "%d %s ", blobidx, strqx_error.c_str());
}
std::string st1 = buffer;
std::string text = st1;
// 按行分割文本
std::vector<std::string> lines;
size_t pos = 0;
while ((pos = text.find("\n")) != std::string::npos)
{
lines.push_back(text.substr(0, pos));
text.erase(0, pos + 1);
}
lines.push_back(text);
int baseline;
// 获取文本框的长宽
cv::Size text_size = cv::getTextSize(text, font_face, font_scale, thickness, &baseline);
cv::Rect droi;
droi.width = text_size.width;
droi.height = text_size.height;
// 输出每一行文本
int lineHeight = text_size.height + baseline;
droi.height = lineHeight;
int line_one_y = 0;
int linenum = lines.size() - 1;
bool bdrawroi = true;
if (lines.size() <= 0)
{
return 0;
}
cv::Rect drawRoi;
drawRoi.x = pc.x;
drawRoi.y = pc.y;
drawRoi.width = text_size.width;
drawRoi.height = text_size.height * lines.size();
// //寻找绘制区域
cv::Point pSearchStart;
pSearchStart.x = pc.x;
pSearchStart.y = pc.y - drawRoi.height;
int search_Y = 300;
int search_X = 500;
int step_x = 30;
int step_y = 20;
if (drayType != Draw_Type_NG)
{
search_Y = 30;
search_X = 30;
step_x = 10;
step_y = 10;
}
bool bSucc = false;
cv::Rect temRoi;
temRoi.width = drawRoi.width;
temRoi.height = drawRoi.height;
cv::Point line_p_qx = pc;
cv::Point line_p_dr = pc;
for (int addX = 0; addX < search_X; addX = addX + step_x)
{
int ix = pSearchStart.x + addX;
for (int xcount = 0; xcount < 2; xcount++)
{
if (xcount == 0)
{
ix = pSearchStart.x + addX;
line_p_qx.x = src_Roi.x + src_Roi.width;
line_p_dr.x = ix;
}
else
{
ix = pSearchStart.x - addX;
line_p_qx.x = src_Roi.x;
line_p_dr.x = ix;
}
if (ix < 0)
{
ix = 0;
// continue;
}
if (ix + drawRoi.width > img.cols)
{
ix = img.cols - drawRoi.width;
// continue;
}
temRoi.x = ix;
for (int addY = 0; addY < search_Y; addY = addY + step_y)
{
int iy = addY + pSearchStart.y;
for (int ycount = 0; ycount < 2; ycount++)
{
if (ycount == 0)
{
iy = pSearchStart.y + addY;
line_p_qx.y = src_Roi.y;
line_p_dr.y = iy + temRoi.height;
}
else
{
iy = pSearchStart.y - addY;
line_p_qx.y = src_Roi.y + src_Roi.height;
line_p_dr.y = iy + temRoi.height;
}
if (iy < 0)
{
iy = 0;
// continue;
}
if (iy + drawRoi.height > img.rows)
{
iy = img.rows - drawRoi.height;
// continue;
}
temRoi.y = iy;
if (bdraw(temRoi))
{
bSucc = true;
break;
}
}
if (bSucc)
{
break;
}
}
if (bSucc)
{
break;
}
}
if (bSucc)
{
break;
}
}
// 如果是NG则强制绘制
if (!bSucc && drayType == Draw_Type_NG)
{
temRoi = drawRoi;
bSucc = true;
}
if (bSucc)
{
drawRoi = temRoi;
// cv::rectangle(img, drawRoi, cv::Scalar(255, 255, 255));
// cv::Point p1 = cv::Point(drawRoi.x, drawRoi.y);
cv::line(img, line_p_qx, line_p_dr, cv::Scalar(255, 255, 0));
m_drawList.push_back(drawRoi);
for (size_t i = 0; i < lines.size(); ++i)
{
// 将文本框居中绘制
cv::Point origin = cv::Point(drawRoi.x, drawRoi.y + (i + 1) * (text_size.height));
double temfont_scale = font_scale;
if (drayType == Draw_Type_NG)
{
if (qx_type == QX_ERROR_TYPE_NUM_RGB255)
{
cv::putText(img, lines[i], origin, font_face, temfont_scale, cv::Scalar(80, 128, 100), thickness, 1, 0);
}
else
{
cv::putText(img, lines[i], origin, font_face, temfont_scale, cv::Scalar(0, 255, 0), thickness, 1, 0);
}
}
else
{
if (drayType == Draw_Type_Other)
{
cv::putText(img, lines[i], origin, font_face, temfont_scale, cv::Scalar(0, 182, 185), thickness, 1, 0);
}
else
{
cv::putText(img, lines[i], origin, font_face, temfont_scale, cv::Scalar(128, 125, 0), thickness, 1, 0);
}
}
}
}
return 0;
}
int DrawImg::preDealImg(cv::Mat &srcimg, cv::Mat &image_resize, bool bfilpSrcImg)
{
return 0;
}
int DrawImg::DrawPointList(cv::Mat &image_draw, std::vector<cv::Point> plist)
{
return 0;
}
bool DrawImg::bdraw(cv::Rect roi)
{
for (auto &r : m_drawList)
{
if (CheckUtil::CalIoU(r, roi) > 0)
{
return false;
}
}
return true;
}
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;
}
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();
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;
Json::Value root = toJsonValue();
Json::StreamWriterBuilder writerBuilder;
std::string jsonString = Json::writeString(writerBuilder, root);
return jsonString;
}

@ -0,0 +1,784 @@
#include "EdgeDet.h"
#include <numeric>
// 计算平均值
double computeAverage(const std::vector<double> &data)
{
return std::accumulate(data.begin(), data.end(), 0.0) / data.size();
}
// 剔除异常数据,这里以平均值加减两倍标准差为界限
std::vector<double> removeOutliers(const std::vector<double> &data)
{
double mean = computeAverage(data);
double sq_sum = std::inner_product(data.begin(), data.end(), data.begin(), 0.0);
double stdev = std::sqrt(sq_sum / data.size() - mean * mean);
std::vector<double> filteredData;
for (double value : data)
{
if (std::abs(value - mean) <= 2 * stdev)
{ // 可以根据需要调整异常值判断的标准
filteredData.push_back(value);
}
}
return filteredData;
}
EdgeDet_New::EdgeDet_New()
{
bshowimg = false;
// m_pAI_Edge_Algin = NULL;
}
EdgeDet_New::~EdgeDet_New()
{
}
int EdgeDet_New::InitRun()
{
m_OtherDet_Config.pAIDeal = &m_AIDeal;
// m_pAI_Edge_Algin = std::make_shared<AI_Edge_Algin>();
m_pAI_Edge_Algin.Init(&m_OtherDet_Config);
InitModel();
return 0;
}
int EdgeDet_New::InitModel()
{
printf("EdgeDet_New::InitModel =============\n");
// 获取当前gpu号确定的 AI处理线程
m_AIDeal.Init(0);
// 边缘搜索模型
//if (m_pAI_Edge_Algin.get() != nullptr)
{
int re = m_pAI_Edge_Algin.InitModel_ALL();
if (re != 0)
{
printf("m_pAI_Edge_Algin InitModel_ALL error \n");
}
}
return 0;
}
int EdgeDet_New::GetImgEdge(cv::Mat img, cv::Rect &roi)
{
bool bdetSucc = false;
if (bshowimg)
{
cv::cvtColor(img, showimg, cv::COLOR_GRAY2BGR);
}
int exp = 0;
cv::Rect detroi;
detroi.x = 0;
detroi.y = 0;
detroi.width = img.cols;
detroi.height = img.rows * 0.8;
int re = UDNoiseEdgeDetect(img, 3, 40, 1, detroi, 30, 60);
if (re < 0)
{
printf("edge error 1 %d \n", re);
return re;
}
roi.y = re + exp;
if (bshowimg && !showimg.empty())
{
cv::Point p1 = cv::Point(0, re);
cv::Point p2 = cv::Point(img.cols, re);
cv::line(showimg, p1, p2, cv::Scalar(255, 0, 255), 5);
printf(">>>>>1>>000000>\n");
}
// cv::Point p1 = cv::Point(0, re);
// cv::Point p2 = cv::Point(img.cols, re);
// cv::line(img, p1, p2, cv::Scalar(255));
detroi.x = 0;
detroi.y = img.rows * 0.2;
detroi.width = img.cols;
detroi.height = img.rows * 0.8 - 1;
re = UDNoiseEdgeDetect(img, -3, 40, 10, detroi, 30, 60);
if (re < 0)
{
printf("edge error 2 %d \n", re);
return re;
}
roi.height = re - exp - roi.y;
if (bshowimg && !showimg.empty())
{
cv::Point p1 = cv::Point(0, re);
cv::Point p2 = cv::Point(img.cols, re);
cv::line(showimg, p1, p2, cv::Scalar(255, 0, 255), 5);
}
// p1 = cv::Point(0, re);
// p2 = cv::Point(img.cols, re);
// cv::line(img, p1, p2, cv::Scalar(255));
// cv::imwrite("showimg.png", img);
// printf(">>>>>>>>\n");
// getchar();
detroi.x = 0;
detroi.y = 0;
detroi.width = img.cols / 2;
detroi.height = img.rows;
re = LRNoiseEdgeDetect(img, 3, 40, 1, detroi, 30, 60);
if (re < 0)
{
printf("edge error 333 v %d \n", re);
return re;
}
roi.x = re + exp;
if (bshowimg && !showimg.empty())
{
cv::Point p1 = cv::Point(re, 0);
cv::Point p2 = cv::Point(re, img.rows);
cv::line(showimg, p1, p2, cv::Scalar(255, 0, 255), 5);
}
// p1 = cv::Point(re, 0);
// p2 = cv::Point(re, img.rows);
// cv::line(img, p1, p2, cv::Scalar(255));
// cv::imwrite("showimg.png", img);
// printf(">>>>>>>>\n");
// getchar();
// cv::imwrite("showimg.png", showimg);
// printf(">>>>>1>>>re %d\n", re);
// getchar();
detroi.x = img.cols / 2;
detroi.y = 0;
detroi.width = img.cols / 2 - 1;
detroi.height = img.rows;
re = LRNoiseEdgeDetect(img, -3, 40, 1, detroi, 30, 60);
if (re < 0)
{
printf(">>>>>>>>\n");
printf("edge error 4 %d \n", re);
return re;
}
roi.width = re - exp - roi.x;
// int len = roi.width / 4 * 4;
// roi.width = len;
if (bshowimg && !showimg.empty())
{
cv::Point p1 = cv::Point(re, 0);
cv::Point p2 = cv::Point(re, img.rows);
cv::line(showimg, p1, p2, cv::Scalar(255, 0, 255), 5);
cv::rectangle(showimg, roi, cv::Scalar(0, 255, 0));
}
// cv::Mat temimg = showimg(real_roi).clone();
// if (real_roi.width > real_roi.height)
// {
// sz.width = 2048;
// fx = sz.width * 1.0f / real_roi.width;
// sz.height = real_roi.height * fx;
// }
// else
// {
// sz.height = 2048;
// fx = sz.height * 1.0f / real_roi.height;
// sz.width = real_roi.width * fx;
// }
// cv::resize(temimg, showimg, sz);
if (bshowimg && !showimg.empty() && true)
{
printf(">>>>>>>>\n");
static int ssss = 0;
cv::Size sz;
if (img.cols > img.rows)
{
sz.width = 2732;
sz.height = 2048;
}
else
{
sz.width = 2048;
sz.height = 2732;
}
// cv::Mat detsizeimg;
cv::resize(showimg, showimg, sz);
// std::string strpath22 = "./img/edge/" + std::to_string(ssss++) + "_det.png";
// printf(">>>>>>>>strpath22 %s\n", strpath22.c_str());
// cv::imwrite(strpath22, detsizeimg);
// std::string strpath22222 = "./img/edge/" + std::to_string(ssss++) + "_src.png";
// printf(">>>>>>>>strpath22 %s\n", strpath22.c_str());
// cv::imwrite(strpath22222, img);
// cv::imwrite("showimg.png", showimg);
// printf(">>>>>>>>\n");
}
// p1 = cv::Point(re, 0);
// p2 = cv::Point(re, img.rows);
// cv::line(img, p1, p2, cv::Scalar(255));
// cv::imwrite("showimg.png", img);
// printf(">>>>>>>>\n");
// getchar();
// cv::rectangle(img, roi, cv::Scalar(255));
// cv::imwrite("showimg.png", img);
// printf(">>>>>>>>\n");
// getchar();
return 0;
}
int EdgeDet_New::AIEdgeDete(const cv::Mat &img, AI_Edge_Algin::DetConfig *pdetConfig, cv::Mat &detMaskImg, cv::Rect &roi)
{
std::shared_ptr<Edge_AI_Result> CheckResult_Aling;
//if (m_pAI_Edge_Algin.get() != nullptr)
{
if (!detmask.empty())
{
detmask.release();
}
int re = m_pAI_Edge_Algin.Detect(img, pdetConfig, CheckResult_Aling);
if (re != 0)
{
printf("AIEdgeDete error \n");
return re;
}
detMaskImg = CheckResult_Aling->mask.clone();
roi = CheckResult_Aling->roi;
detmask = CheckResult_Aling->DetMask_src.clone();
}
// else
// {
// return 1;
// }
return 0;
}
int EdgeDet_New::UDNoiseEdgeDetect(cv::Mat img, int DirectSign, int Gate, int BorW, cv::Rect roi, int StepCount, int Limit)
{
if (img.empty())
{
return -11;
}
if (img.channels() != 1)
{
printf("*****************************channels\n");
return -12;
}
if (StepCount < 0 || StepCount >= roi.width)
{
printf("*****************************StepCount\n");
return -22;
}
std::vector<double> data;
// cv::Mat showimg;
// cv::cvtColor(img, showimg, cv::COLOR_GRAY2BGR);
uchar *pdata = (uchar *)img.data;
int sx = roi.x;
int ex = roi.x + roi.width;
int sy = roi.y;
int ey = roi.y + roi.height;
// 表示 反向搜索
if (DirectSign < 0)
{
sy = roi.y + roi.height;
ey = roi.y;
}
int step = roi.width / StepCount;
int offt = 0;
int sumsite = 0;
int sumcount = 0;
// 表示搜索黑点
if (BorW == 0)
{
}
else // 表示搜索白点
{
for (int x = roi.x; x < ex; x = x + step)
{
int ncount = 0;
int start = 0;
for (int y = sy;; y = y + DirectSign)
{
if (DirectSign > 0 && y > ey)
{
break;
}
if (DirectSign < 0 && y < ey)
{
break;
}
int maxv = 0;
// 1、计算当前值是否 满足基本要求
offt = y * img.cols + x;
maxv = pdata[offt];
if (maxv < 40)
{
for (int ix = -4; ix < 5; ix++)
{
int newx = x + ix;
if (newx < 0)
{
newx = 0;
}
if (newx > img.cols)
{
newx = img.cols;
}
offt = y * img.cols + newx;
if (pdata[offt] > maxv)
{
maxv = pdata[offt];
}
}
}
if (maxv > 40)
{
// 2、计算区域最大值
for (int k = -4; k < 5; k++)
{
int newy = y + k;
if (newy < 0)
{
newy = 0;
}
if (newy >= img.rows)
{
newy = img.rows - 1;
}
for (int ix = -4; ix < 5; ix++)
{
int newx = x + ix;
if (newx < 0)
{
newx = 0;
}
if (newx > img.cols)
{
newx = img.cols;
}
offt = newy * img.cols + newx;
if (pdata[offt] > maxv)
{
maxv = pdata[offt];
}
}
/* code */
}
if (bshowimg)
{
cv::Rect roi;
roi.x = x - 2;
roi.width = 5;
if (roi.x < 0)
{
roi.x = 0;
}
int rdp = roi.x + roi.width;
if (rdp > showimg.cols)
{
rdp = showimg.cols;
}
roi.width = rdp - roi.x;
roi.y = y - 2;
roi.height = 5;
if (roi.y < 0)
{
roi.y = 0;
}
rdp = roi.y + roi.height;
if (rdp > showimg.rows)
{
rdp = showimg.rows;
}
roi.height = rdp - roi.y;
cv::rectangle(showimg, roi, cv::Scalar(0, 0, 255));
/* code */
}
}
else
{
// if (start > 0)
// {
// printf("error p %d %d %d \n", x, y, maxv);
// /* code */
// }
}
// 3、满足要求 记录
if (maxv >= Gate)
{
ncount += 2;
if (start == 0)
{
start = y;
}
if (ncount > Limit)
{
break;
}
}
else
{
// if (maxv < 15)
// {
// ncount = 0;
// }
ncount--;
if (ncount < 0)
{
ncount = 0;
start = 0;
}
}
}
// 4、满足退出要求就退出
if (ncount > Limit)
{
sumcount++;
sumsite += start;
data.push_back(start);
if (bshowimg && !showimg.empty())
{
cv::Point p(x, start);
cv::circle(showimg, p, 13, cv::Scalar(0, 255, 0), 5);
// cv::imwrite("showimg.png", showimg);
// printf(">>>>>>>> %d %d \n",x,start);
// getchar();
}
}
}
}
if (sumcount <= 0)
{
return -3;
}
else
{
// 先剔除异常数据
std::vector<double> filteredData = removeOutliers(data);
if (bshowimg && !showimg.empty())
{
// for (int i = 0; i < data.size(); i++)
// {
// printf("%d %f \n ", i, data.at(i));
// }
// for (int i = 0; i < filteredData.size(); i++)
// {
// printf("%d %f \n ", i, filteredData.at(i));
// }
}
sumsite = 0;
sumcount = 0;
int mean = 0;
for (int i = 0; i < filteredData.size(); i++)
{
sumsite += filteredData.at(i);
sumcount++;
}
if (sumcount > 0)
{
mean = sumsite / sumcount;
}
mean = sumsite / sumcount;
return mean;
}
return -5;
}
int EdgeDet_New::LRNoiseEdgeDetect(cv::Mat img, int DirectSign, int Gate, int BorW, cv::Rect roi, int StepCount, int Limit)
{
if (img.empty())
{
return -1;
}
if (img.channels() != 1)
{
printf("*****************************channels\n");
return -1;
}
if (StepCount < 0 || StepCount >= roi.width)
{
printf("*****************************StepCount\n");
return -2;
}
std::vector<double> data;
// cv::Mat showimg;
// cv::cvtColor(img, showimg, cv::COLOR_GRAY2BGR);
uchar *pdata = (uchar *)img.data;
int sx = roi.x;
int ex = roi.x + roi.width;
int sy = roi.y;
int ey = roi.y + roi.height;
// 表示 反向搜索
if (DirectSign < 0)
{
sx = roi.x + roi.width;
ex = roi.x;
}
int step = roi.height / StepCount;
int offt = 0;
int sumsite = 0;
int sumcount = 0;
// 表示搜索黑点
if (BorW == 0)
{
}
else // 表示搜索白点
{
// printf("---- y sy %d ey %d sx %d ex %d\n", sy, ey, sx, ex);
for (int y = sy; y < ey; y = y + step)
{
int ncount = 0;
int start = 0;
for (int x = sx;; x = x + DirectSign)
{
if (DirectSign > 0 && x > ex)
{
break;
}
if (DirectSign < 0 && x < ex)
{
break;
}
int maxv = 0;
// 1、计算当前值是否 满足基本要求
offt = y * img.cols + x;
maxv = pdata[offt];
if (maxv < 40)
{
for (int k = -4; k < 5; k++)
{
int newy = y + k;
if (newy < 0)
{
newy = 0;
}
if (newy >= img.rows)
{
newy = img.rows - 1;
}
offt = newy * img.cols + x;
maxv = pdata[offt];
if (pdata[offt] > maxv)
{
maxv = pdata[offt];
}
}
}
if (maxv > 40)
{
// 2、计算区域最大值
for (int k = -4; k < 5; k++)
{
int newy = y + k;
if (newy < 0)
{
newy = 0;
}
if (newy >= img.rows)
{
newy = img.rows - 1;
}
for (int ix = -4; ix < 5; ix++)
{
int newx = x + ix;
if (newx < 0)
{
newx = 0;
}
if (newx > img.cols)
{
newx = img.cols;
}
offt = newy * img.cols + newx;
if (pdata[offt] > maxv)
{
maxv = pdata[offt];
}
}
/* code */
}
if (bshowimg)
{
cv::Rect roi;
roi.x = x - 2;
roi.width = 5;
if (roi.x < 0)
{
roi.x = 0;
}
int rdp = roi.x + roi.width;
if (rdp > showimg.cols)
{
rdp = showimg.cols;
}
roi.width = rdp - roi.x;
roi.y = y - 2;
roi.height = 5;
if (roi.y < 0)
{
roi.y = 0;
}
rdp = roi.y + roi.height;
if (rdp > showimg.rows)
{
rdp = showimg.rows;
}
roi.height = rdp - roi.y;
cv::rectangle(showimg, roi, cv::Scalar(0, 0, 255));
/* code */
}
}
else
{
// if (start > 0)
// {
// //printf("error p %d %d %d \n", x, y, maxv);
// /* code */
// }
}
// 3、满足要求 记录
if (maxv >= Gate)
{
ncount += 2;
if (start == 0)
{
start = x;
// printf("---- %d %d y %d\n", pdata[offt], start, y);
}
if (ncount > Limit)
{
break;
}
}
else
{
// if (maxv < 15)
// {
// ncount = 0;
// }
ncount--;
if (ncount < 0)
{
start = 0;
ncount = 0;
}
}
}
if (ncount > Limit)
{
sumcount++;
sumsite += start;
data.push_back(start);
if (bshowimg && !showimg.empty())
{
cv::Point p(start, y);
cv::circle(showimg, p, 13, cv::Scalar(255, 255, 125), 5);
// cv::imwrite("showimg.png", showimg);
// printf(">>>>>>>>\n");
// getchar();
}
}
}
}
// if (bshowimg && !showimg.empty())
// {
// cv::imwrite("showimg.png", showimg);
// printf(">>>>>>123>> DirectSign %d \n",DirectSign);
// getchar();
// }
// if (DirectSign < 0)
// {
// cv::imwrite("showimg.png", img);
// printf(">>>>>>>>\n");
// getchar();
// }
if (sumcount <= 0)
{
return -3;
}
else
{
// 先剔除异常数据
std::vector<double> filteredData = removeOutliers(data);
if (bshowimg && !showimg.empty())
{
// for (int i = 0; i < data.size(); i++)
// {
// printf("%d %f \n ", i, data.at(i));
// }
// for (int i = 0; i < filteredData.size(); i++)
// {
// printf("%d %f \n ", i, filteredData.at(i));
// }
}
sumsite = 0;
sumcount = 0;
int mean = 0;
for (int i = 0; i < filteredData.size(); i++)
{
sumsite += filteredData.at(i);
sumcount++;
}
if (sumcount > 0)
{
mean = sumsite / sumcount;
}
mean = sumsite / sumcount;
return mean;
}
return -5;
}

@ -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,77 @@
#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() > 20 && !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,103 @@
#include "OtherDetect.h"
#include "CheckErrorCodeDefine.hpp"
AIDetectBase ::AIDetectBase(/* args */)
{
m_pOtherDet_Config = NULL;
m_pAIDeal = NULL;
m_bInitialized = false;
m_bModelSucc = false;
}
AIDetectBase ::~AIDetectBase()
{
}
int AIDetectBase ::Init(OtherDet_Config *pOtherDet_Config)
{
m_pOtherDet_Config = pOtherDet_Config;
m_pAIDeal = pOtherDet_Config->pAIDeal;
m_pTemCheck = pOtherDet_Config->pTemCheck;
m_bInitialized = true;
return 0;
}
LackPolDet::LackPolDet(/* args */)
{
}
LackPolDet::~LackPolDet()
{
}
int LackPolDet::Init_LackPol()
{
AIInitConfig config_nf;
config_nf.nGpuIdx = m_pOtherDet_Config->nDeviceId;
config_nf.engine_file_path = str_AI_LOSSPOL_Model_Path;
config_nf.bufferList[0].ntype = AIBufferType_IN;
config_nf.bufferList[0].ndatalength = str_AI_LOSSPOL_IN_0_DATA_LENGTH;
config_nf.bufferList[1].ntype = AIBufferType_OUT;
config_nf.bufferList[1].ndatalength = str_AI_LOSSPOL_out_0_DATA_LENGTH;
int re = m_pAIDeal->Init_LackPol(config_nf);
return re;
}
int LackPolDet::InitModel_ALL()
{
m_bModelSucc = false;
int re = Init_LackPol();
if (re != 0)
{
printf("AI_Edge_Algin Init_LackPol Error \n");
return re;
}
m_bModelSucc = true;
return 0;
}
int LackPolDet::Detect(const cv::Mat &img, DetConfig *pDetConfig, cv::Mat &outMask)
{
cv::Mat inImg;
cv::Size sz;
cv::Mat detmask_size;
if (pDetConfig == NULL)
{
return 1;
}
if (img.empty())
{
return 2;
}
if (pDetConfig->detMaskImg.empty())
{
return 3;
}
if (!m_bModelSucc)
{
return 4;
}
sz.width = str_AI_LOSSPOL_IN_0_IMAGE_WIDTH;
sz.height = str_AI_LOSSPOL_IN_0_IMAGE_HEIGHT;
cv::resize(img, inImg, sz, 0, 0, cv::INTER_AREA);
cv::resize(pDetConfig->detMaskImg, detmask_size, sz, 0, 0, cv::INTER_AREA);
m_pAIDeal->AICheck_LackPol(inImg, outMask);
if (pDetConfig->bSaveResultImg)
{
if (!inImg.empty())
{
cv::imwrite(pDetConfig->strChannel + "_LackPol_In.png", inImg);
}
if (!outMask.empty())
{
cv::imwrite(pDetConfig->strChannel + "_LackPol_out.png", outMask);
}
}
outMask.setTo(0, detmask_size);
return 0;
}

@ -0,0 +1,534 @@
#include "QX_Analysis.h"
#include "CheckErrorCodeDefine.hpp"
QX_Analysis::QX_Analysis(/* args */)
{
}
QX_Analysis::~QX_Analysis()
{
}
void QX_Analysis::SetConfig(int qxidx, QXAnalysis_Config config)
{
if (!Idx(qxidx))
{
return;
}
// printf("SetConfig type %d %s add \n", qxidx, QX_ANALYSIS_NAME_Names[qxidx].c_str());
config.print(QX_ANALYSIS_NAME_Names[qxidx]);
m_ConfigList[qxidx].configlsit.push_back(config);
}
void QX_Analysis::InitConfig()
{
for (int i = 0; i < QX_ANALYSIS_COUNT; i++)
{
m_ConfigList[i].Init();
}
}
bool QX_Analysis::AddQxInfo(int qxidx, QX_Info qxinfo)
{
if (!Idx(qxidx))
{
return false;
}
// printf("AddQxInfo type %d %s add \n", qxidx, QX_ANALYSIS_NAME_Names[qxidx].c_str());
// qxinfo.print(QX_ANALYSIS_NAME_Names[qxidx]);
// 初步筛选一次
bool badd = false;
for (int i = 0; i < (int)m_ConfigList[qxidx].configlsit.size(); i++)
{
QXAnalysis_Config *pconfig = &m_ConfigList[qxidx].configlsit.at(i);
// 面积 灰阶满足要求
if (qxinfo.area >= pconfig->area &&
qxinfo.hj >= pconfig->hj &&
qxinfo.length >= pconfig->len &&
qxinfo.density >= pconfig->density)
{
badd = true;
}
m_pTemCheck->AddCheckstr(PrintLevel_3, 3, "preA", "add = %s congfig idx %d / %d ", BOOL_TO_STR(badd), i, (int)m_ConfigList[qxidx].configlsit.size());
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "Area", "%s -> %f %s %f ",
BOOL_TO_STR(qxinfo.area >= pconfig->area), qxinfo.area, BOOL_TO_ThanLess(qxinfo.area >= pconfig->area), pconfig->area);
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "HJ", "%s -> %f %s %d ",
BOOL_TO_STR(qxinfo.hj >= pconfig->hj), qxinfo.hj, BOOL_TO_ThanLess(qxinfo.hj >= pconfig->hj), pconfig->hj);
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "Len", "%s -> %f %s %f ",
BOOL_TO_STR(qxinfo.length >= pconfig->len), qxinfo.length, BOOL_TO_ThanLess(qxinfo.length >= pconfig->len), pconfig->len);
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "md", "%s -> %f %s %f ",
BOOL_TO_STR(qxinfo.density >= pconfig->density), qxinfo.density, BOOL_TO_ThanLess(qxinfo.density >= pconfig->density), pconfig->density);
if (badd)
{
break;
/* code */
}
}
if (badd)
{
m_QXList[qxidx].qxList.push_back(qxinfo);
}
return badd;
}
int QX_Analysis::Init()
{
for (int i = 0; i < QX_ANALYSIS_COUNT; i++)
{
m_QXList[i].Init();
}
m_reultList.Init();
return 0;
}
int QX_Analysis::GetReusult(QX_Analysis_Result_List *&presult)
{
m_pTemCheck->AddCheckstr(PrintLevel_0, 3, "Num And Dis Judge", "==========Start========");
// 分析每一个缺陷类型
for (int i = 0; i < QX_ANALYSIS_COUNT; i++)
{
if (QX_ANALYSIS_POL_CELL != i && QX_ANALYSIS_AD != i && QX_ANALYSIS_MTX != i && QX_ANALYSIS_Scratch != i && QX_ANALYSIS_LINE != i)
{
continue;
}
if (m_QXList[i].qxList.size() <= 0 || m_ConfigList[i].configlsit.size() <= 0)
{
continue;
}
m_pTemCheck->AddCheckstr(PrintLevel_0, 3, "Num And Dis Judge", "%s start", QX_ANALYSIS_NAME_Names[i].c_str());
Analysis(&m_ConfigList[i], &m_QXList[i], i);
m_pTemCheck->AddCheckstr(PrintLevel_0, 3, "Num And Dis Judge", "%s end", QX_ANALYSIS_NAME_Names[i].c_str());
}
presult = &m_reultList;
m_pTemCheck->AddCheckstr(PrintLevel_0, 3, "Num And Dis Judge", "==========End ======== Add New QX Num = %d", m_reultList.resultList.size());
return 0;
}
bool QX_Analysis::Idx(int qxidx)
{
if (qxidx < 0 || qxidx >= QX_ANALYSIS_COUNT)
{
return false;
}
return true;
}
int QX_Analysis::Analysis(QX_Config_List *pconfigList, QX_ALL_List *pqxList, int qx_type)
{
for (int i = 0; i < (int)pconfigList->configlsit.size(); i++)
{
m_pTemCheck->AddCheckstr(PrintLevel_1, 3, "Num And Dis Judge", "param %d / %d Analysis start ", i, (int)pconfigList->configlsit.size());
Analysis_s(&pconfigList->configlsit.at(i), pqxList, qx_type);
// m_pTemCheck->AddCheckstr(PrintLevel_1, 3, "Num And Dis Judge", "param %d / %d Analysis end ", i, (int)pconfigList->configlsit.size());
}
if (qx_type == QX_ANALYSIS_AD)
{
m_pTemCheck->AddCheckstr(PrintLevel_1, 3, "Num And Dis Judge", " AD Num Deal");
for (int i = 0; i < (int)pconfigList->configlsit.size(); i++)
{
m_pTemCheck->AddCheckstr(PrintLevel_1, 3, "Num And Dis Judge", "param %d / %d AD Num start ", i, (int)pconfigList->configlsit.size());
Analysis_AD_Num(&pconfigList->configlsit.at(i), pqxList, qx_type);
// m_pTemCheck->AddCheckstr(PrintLevel_1, 3, "Num And Dis Judge", "param %d / %d AD Num end ", i, (int)pconfigList->configlsit.size());
}
}
if (qx_type == QX_ANALYSIS_POL_CELL)
{
m_pTemCheck->AddCheckstr(PrintLevel_1, 3, "Num And Dis Judge", " POL_CELL Num Deal");
for (int i = 0; i < (int)pconfigList->configlsit.size(); i++)
{
m_pTemCheck->AddCheckstr(PrintLevel_1, 3, "Num And Dis Judge", "param %d / %d POL_CELL Num %d start ", i, (int)pconfigList->configlsit.size(),(int)pqxList->qxList.size());
Analysis_POL_Num(&pconfigList->configlsit.at(i), pqxList, qx_type);
// m_pTemCheck->AddCheckstr(PrintLevel_1, 3, "Num And Dis Judge", "param %d / %d AD Num end ", i, (int)pconfigList->configlsit.size());
}
}
return 0;
}
int QX_Analysis::Analysis_s(QXAnalysis_Config *pconfig, QX_ALL_List *pqxList, int qx_type)
{
int num = 0;
m_pTemCheck->AddCheckstr(PrintLevel_2, 3, "param", " okparam = %d area %f max_area %f hj %d num %d dis %f len %f md %f", pconfig->bok, pconfig->area, pconfig->sum_area, pconfig->hj, pconfig->num, pconfig->dis, pconfig->len, pconfig->density);
float sumarea = 0;
float fmaxarea = 0;
for (int i = 0; i < (int)pqxList->qxList.size(); i++)
{
// 面积 灰阶满足要求
if (pqxList->qxList.at(i).area >= pconfig->area &&
pqxList->qxList.at(i).hj >= pconfig->hj &&
pqxList->qxList.at(i).density >= pconfig->density &&
pqxList->qxList.at(i).length >= pconfig->len)
{
num++;
pqxList->qxList.at(i).nstatus = 1;
sumarea += pqxList->qxList.at(i).area;
if (pqxList->qxList.at(i).area > fmaxarea)
{
fmaxarea = pqxList->qxList.at(i).area;
}
}
m_pTemCheck->AddCheckstr(PrintLevel_3, 3, "preA", "qx_idx %d : %s num = %d ", i, Re_TO_STR_Pass_1(pqxList->qxList.at(i).nstatus), num);
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "Area", "%s -> %f %s %f ",
BOOL_TO_STR(pqxList->qxList.at(i).area >= pconfig->area), pqxList->qxList.at(i).area, BOOL_TO_ThanLess(pqxList->qxList.at(i).area >= pconfig->area), pconfig->area);
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "HJ", "%s -> %f %s %d ",
BOOL_TO_STR(pqxList->qxList.at(i).hj >= pconfig->hj), pqxList->qxList.at(i).hj, BOOL_TO_ThanLess(pqxList->qxList.at(i).hj >= pconfig->hj), pconfig->hj);
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "Len", "%s -> %f %s %f ",
BOOL_TO_STR(pqxList->qxList.at(i).length >= pconfig->len), pqxList->qxList.at(i).length, BOOL_TO_ThanLess(pqxList->qxList.at(i).length >= pconfig->len), pconfig->len);
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "md", "%s -> %f %s %f ",
BOOL_TO_STR(pqxList->qxList.at(i).density >= pconfig->density), pqxList->qxList.at(i).density, BOOL_TO_ThanLess(pqxList->qxList.at(i).density >= pconfig->density), pconfig->density);
}
if (pconfig->bok == 1)
{
m_pTemCheck->AddCheckstr(PrintLevel_2, 3, "OK Param Judge", "Num %d ", num);
// 只要有一个条件大于阈值参数就NG;
if (num > 0)
{
int are = QX_ERROR_TYPE_OK;
// 数量超过阈值
if (num > pconfig->num)
{
are = QX_ERROR_TYPE_NUM;
for (int i = 0; i < (int)pqxList->qxList.size(); i++)
{
// 面积 灰阶满足要求
if (pqxList->qxList.at(i).nstatus == 1)
{
pqxList->qxList.at(i).nqx_type = QX_ERROR_TYPE_NUM;
}
}
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "result NG", "num %d > config num %d nqx_type %d ", num, pconfig->num, are);
}
else
{
m_pTemCheck->AddCheckstr(PrintLevel_3, 3, "Num", " %s -> num %d %s %d ", BOOL_TO_STR(num < pconfig->num), num, BOOL_TO_LessThan(num < pconfig->num), pconfig->num);
for (int i = 0; i < (int)pqxList->qxList.size(); i++)
{
m_pTemCheck->AddCheckstr(PrintLevel_3, 3, "Num And Dis Judge", "Blob info %d / %d idx %d: area %f e %f len %f hj %f", i, (int)pqxList->qxList.size(),
pqxList->qxList.at(i).blobIdx, pqxList->qxList.at(i).area, pqxList->qxList.at(i).energy, pqxList->qxList.at(i).length, pqxList->qxList.at(i).hj);
if (pqxList->qxList.at(i).nstatus == 1)
{
// 长度超过阈值
if (pqxList->qxList.at(i).length > pconfig->len)
{
pqxList->qxList.at(i).nqx_type = QX_ERROR_TYPE_Len;
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "result NG", "length %f > config len %f nqx_type %d ", pqxList->qxList.at(i).length, pconfig->len, pconfig->dis, pqxList->qxList.at(i).nqx_type);
}
int minidx = -1;
// 对距离有要求
if (pconfig->dis > 0)
{
double mindis = 99999999999;
for (int j = 0; j < (int)pqxList->qxList.size(); j++)
{
if (i == j)
{
continue;
}
// 面积 灰阶满足要求
if (pqxList->qxList.at(j).nstatus == 1)
{
double dis = CheckUtil::calDis(pqxList->qxList.at(i).plocatin_mm, pqxList->qxList.at(j).plocatin_mm);
if (dis < mindis)
{
mindis = dis;
minidx = j;
}
}
}
// 最小距离 大于 阈值
if (mindis <= pconfig->dis)
{
pqxList->qxList.at(i).nqx_type = QX_ERROR_TYPE_DIS;
pqxList->qxList.at(i).fmindis = mindis;
pqxList->qxList.at(i).nmindis_BlobIdx = minidx;
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "result NG", "mindis %f < config dis %f nqx_type %d ", mindis, pconfig->dis, pqxList->qxList.at(i).nqx_type);
}
// m_pTemCheck->AddCheckstr(PrintLevel_3, 3, "QX_Analysis", "mindis %f minidx %d config dis %f nqx_type %d ", mindis, minidx, pconfig->dis,pqxList->qxList.at(i).nqx_type);
}
}
}
}
for (int i = 0; i < (int)pqxList->qxList.size(); i++)
{
if (pqxList->qxList.at(i).nqx_type > QX_ERROR_TYPE_OK)
{
if (pqxList->qxList.at(i).result == 0)
{
pqxList->qxList.at(i).result = 1;
QX_RESULT tem;
tem.blobIdx = pqxList->qxList.at(i).blobIdx;
tem.qx_Num = num;
tem.mindis = pqxList->qxList.at(i).fmindis;
tem.flen = pqxList->qxList.at(i).length;
tem.error_Type = pqxList->qxList.at(i).nqx_type;
if (pqxList->qxList.at(i).nmindis_BlobIdx >= 0)
{
tem.qx_MisDis_point_pixel = pqxList->qxList.at(pqxList->qxList.at(i).nmindis_BlobIdx).plocatin_pixel;
}
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "result = NG", "Add New qx,Blob idx %d type %d num %d dis %f len %f ", tem.blobIdx, tem.error_Type, tem.qx_Num, tem.mindis, tem.flen);
m_reultList.resultList.push_back(tem);
}
}
}
}
}
else
{
// 数量满足要求
if (num >= pconfig->num && num > 0 && fmaxarea >= pconfig->sum_area)
{
m_pTemCheck->AddCheckstr(PrintLevel_2, 3, "Num And Dis Judge", "Num = true:Num %d >= %d max_area = true: %f > %f ", num, pconfig->num, fmaxarea, pconfig->sum_area);
for (int i = 0; i < (int)pqxList->qxList.size(); i++)
{
// 面积 灰阶满足要求
if (pqxList->qxList.at(i).area >= pconfig->area &&
pqxList->qxList.at(i).hj >= pconfig->hj &&
pqxList->qxList.at(i).density >= pconfig->density &&
pqxList->qxList.at(i).length >= pconfig->len)
{
m_pTemCheck->AddCheckstr(PrintLevel_3, 3, "qx Info", "qx_idx %d / %d idx %d: area %f e %f len %f hj %f", i, (int)pqxList->qxList.size(),
pqxList->qxList.at(i).blobIdx, pqxList->qxList.at(i).area, pqxList->qxList.at(i).energy, pqxList->qxList.at(i).length, pqxList->qxList.at(i).hj);
int minidx = -1;
bool bdis = true;
double remindis = 0;
// 对距离有要求
if (pconfig->dis > 0)
{
double mindis = 99999999999;
for (int j = 0; j < (int)pqxList->qxList.size(); j++)
{
if (i == j)
{
continue;
}
// 面积 灰阶满足要求
if (pqxList->qxList.at(j).area >= pconfig->area &&
pqxList->qxList.at(j).hj >= pconfig->hj)
{
double dis = CheckUtil::calDis(pqxList->qxList.at(i).plocatin_mm, pqxList->qxList.at(j).plocatin_mm);
if (dis < mindis)
{
mindis = dis;
minidx = j;
}
}
}
// 最小距离 大于 阈值
if (mindis > pconfig->dis)
{
bdis = false;
}
// m_pTemCheck->AddCheckstr(PrintLevel_3, 3, "QX_Analysis", "mindis %f minidx %d config dis %f ", mindis, minidx, pconfig->dis);
// m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "dis", "dis Is %s -> %f %s %f ",
// BOOL_TO_STR(bdis), mindis, BOOL_TO_ThanLess(bdis), pconfig->dis);
remindis = mindis;
}
else
{
// m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "QX_Analysis", "dis Is true; param :dis == 0;");
}
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "dis", "dis Is %s -> %f %s %f ",
BOOL_TO_STR(bdis), remindis, BOOL_TO_LessThan(bdis), pconfig->dis);
// printf("bdis %d pqxList->qxList.at(i).result %d ",bdis, pqxList->qxList.at(i).result);
// 距离满足要求
if (bdis && pqxList->qxList.at(i).result == 0)
{
pqxList->qxList.at(i).result = 1;
QX_RESULT tem;
tem.blobIdx = pqxList->qxList.at(i).blobIdx;
tem.qx_Num = num;
tem.mindis = remindis;
if (pconfig->num <= 0 && pconfig->dis <= 0)
{
tem.error_Type = QX_ERROR_TYPE_AREA;
}
else if (pconfig->dis <= 0)
{
tem.error_Type = QX_ERROR_TYPE_NUM;
}
else
{
tem.error_Type = QX_ERROR_TYPE_DIS;
if (minidx >= 0)
{
tem.qx_MisDis_point_pixel = pqxList->qxList.at(minidx).plocatin_pixel;
}
}
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "Add New QX",
"result = NG, Add New qx,Blob idx %d -> num %d >= %d is true; dis %f <= %f is true; max_area %f >= %f is true ",
tem.blobIdx, num, pconfig->num, remindis, pconfig->dis, fmaxarea, pconfig->sum_area);
m_reultList.resultList.push_back(tem);
}
else
{
if (pqxList->qxList.at(i).result != 0)
{
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "Num And Dis Judge", "result = NG, old result = %d ", pqxList->qxList.at(i).result);
}
// if (!bdis)
// {
// m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "Num And Dis Judge", "Fail,dis %s ", BOOL_TO_STR(bdis));
// }
}
}
else
{
// m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "preA", "fail");
}
}
}
else
{
m_pTemCheck->AddCheckstr(PrintLevel_3, 3, "result", "fail ");
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "num", "%s -> %d %s %d ",
BOOL_TO_STR(num >= pconfig->num), num, BOOL_TO_ThanLess(num >= pconfig->num), pconfig->num);
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "num", "%s -> %d %s 0 ",
BOOL_TO_STR(num > 0), num, BOOL_TO_ThanLess(num > 0));
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "max_area", "%s -> %f %s %f ",
BOOL_TO_STR(fmaxarea >= pconfig->sum_area), fmaxarea, BOOL_TO_ThanLess(fmaxarea >= pconfig->sum_area), pconfig->sum_area);
}
}
return 0;
}
int QX_Analysis::Analysis_AD_Num(QXAnalysis_Config *pconfig, QX_ALL_List *pqxList, int qx_type)
{
// 如果缺陷是暗点,
// 并且 对数量有2个以上要的。因为只有1个要求的话本身不能满足那么其他通道也暗点总和一起分析也没意义。
// 同时对 距离没有要求的。
if (qx_type == QX_ANALYSIS_AD && !pconfig->bok && (pconfig->num > 1 || pconfig->dis > 1))
{
// 如果是暗点,那么先忽略暗点对数量的要求,暗点的数量 = RGB 255 多个通道不同位置的暗点数量总和,所以需要 统一放到外面分析。
// 解决措施对暗点缺陷有数量要求的先忽略先NG 在在外面进行分析。
// 对数量有要求。
m_pTemCheck->AddCheckstr(PrintLevel_2, 3, "Num And Dis Judge", "AD_Num config okparam = %d area %f max_area %f hj %d num %d dis %f len %f", pconfig->bok, pconfig->area, pconfig->sum_area, pconfig->hj, pconfig->num, pconfig->dis, pconfig->len);
for (int i = 0; i < (int)pqxList->qxList.size(); i++)
{
// 当前还是好品的。
if (pqxList->qxList.at(i).result == 0)
{
bool bsucc = false;
// 面积 灰阶满足要求
if (pqxList->qxList.at(i).area >= pconfig->area &&
pqxList->qxList.at(i).hj >= pconfig->hj &&
pqxList->qxList.at(i).density >= pconfig->density &&
pqxList->qxList.at(i).length >= pconfig->len)
{
bsucc = true;
}
m_pTemCheck->AddCheckstr(PrintLevel_3, 3, "Num deal ", "%d :%s", i, BOOL_TO_STROK(bsucc));
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "Area", "%s -> %f %s %f ",
BOOL_TO_STR(pqxList->qxList.at(i).area >= pconfig->area), pqxList->qxList.at(i).area, BOOL_TO_ThanLess(pqxList->qxList.at(i).area >= pconfig->area), pconfig->area);
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "HJ", "%s -> %f %s %d ",
BOOL_TO_STR(pqxList->qxList.at(i).hj >= pconfig->hj), pqxList->qxList.at(i).hj, BOOL_TO_ThanLess(pqxList->qxList.at(i).hj >= pconfig->hj), pconfig->hj);
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "Len", "%s -> %f %s %f ",
BOOL_TO_STR(pqxList->qxList.at(i).length >= pconfig->len), pqxList->qxList.at(i).length, BOOL_TO_ThanLess(pqxList->qxList.at(i).length >= pconfig->len), pconfig->len);
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "md", "%s -> %f %s %f ",
BOOL_TO_STR(pqxList->qxList.at(i).density >= pconfig->density), pqxList->qxList.at(i).density, BOOL_TO_ThanLess(pqxList->qxList.at(i).density >= pconfig->density), pconfig->density);
if (bsucc)
{
pqxList->qxList.at(i).result = 1;
QX_RESULT tem;
tem.blobIdx = pqxList->qxList.at(i).blobIdx;
tem.qx_Num = -pconfig->num;
tem.mindis = 0;
tem.error_Type = QX_ERROR_TYPE_NUM_RGB255;
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "Num And Dis Judge",
"result = NG Num RGB255, Add New qx,Blob idx %d ", tem.blobIdx);
m_reultList.resultList.push_back(tem);
}
}
}
}
return 0;
}
int QX_Analysis::Analysis_POL_Num(QXAnalysis_Config *pconfig, QX_ALL_List *pqxList, int qx_type)
{
// 如果缺陷是暗点,
// 并且 对数量有2个以上要的。因为只有1个要求的话本身不能满足那么其他通道也暗点总和一起分析也没意义。
// 同时对 距离没有要求的。
if (qx_type == QX_ANALYSIS_POL_CELL && !pconfig->bok && (pconfig->num > 1 || pconfig->dis > 1))
{
// 如果是暗点,那么先忽略暗点对数量的要求,暗点的数量 = RGB 255 多个通道不同位置的暗点数量总和,所以需要 统一放到外面分析。
// 解决措施对暗点缺陷有数量要求的先忽略先NG 在在外面进行分析。
// 对数量有要求。
m_pTemCheck->AddCheckstr(PrintLevel_2, 3, "Num And Dis Judge", "POL_Num config okparam = %d area %f max_area %f hj %d num %d dis %f len %f", pconfig->bok, pconfig->area, pconfig->sum_area, pconfig->hj, pconfig->num, pconfig->dis, pconfig->len);
for (int i = 0; i < (int)pqxList->qxList.size(); i++)
{
// 当前还是好品的。
if (pqxList->qxList.at(i).result == 0)
{
bool bsucc = false;
// 面积 灰阶满足要求
if (pqxList->qxList.at(i).area >= pconfig->area &&
pqxList->qxList.at(i).hj >= pconfig->hj &&
pqxList->qxList.at(i).density >= pconfig->density &&
pqxList->qxList.at(i).length >= pconfig->len)
{
bsucc = true;
}
m_pTemCheck->AddCheckstr(PrintLevel_3, 3, "Num deal ", "%d :%s", i, BOOL_TO_STROK(bsucc));
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "Area", "%s -> %f %s %f ",
BOOL_TO_STR(pqxList->qxList.at(i).area >= pconfig->area), pqxList->qxList.at(i).area, BOOL_TO_ThanLess(pqxList->qxList.at(i).area >= pconfig->area), pconfig->area);
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "HJ", "%s -> %f %s %d ",
BOOL_TO_STR(pqxList->qxList.at(i).hj >= pconfig->hj), pqxList->qxList.at(i).hj, BOOL_TO_ThanLess(pqxList->qxList.at(i).hj >= pconfig->hj), pconfig->hj);
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "Len", "%s -> %f %s %f ",
BOOL_TO_STR(pqxList->qxList.at(i).length >= pconfig->len), pqxList->qxList.at(i).length, BOOL_TO_ThanLess(pqxList->qxList.at(i).length >= pconfig->len), pconfig->len);
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "md", "%s -> %f %s %f ",
BOOL_TO_STR(pqxList->qxList.at(i).density >= pconfig->density), pqxList->qxList.at(i).density, BOOL_TO_ThanLess(pqxList->qxList.at(i).density >= pconfig->density), pconfig->density);
if (bsucc)
{
pqxList->qxList.at(i).result = 1;
QX_RESULT tem;
tem.blobIdx = pqxList->qxList.at(i).blobIdx;
tem.qx_Num = -pconfig->num;
tem.mindis = 0;
tem.error_Type = QX_ERROR_TYPE_NUM_RGB255;
m_pTemCheck->AddCheckstr(PrintLevel_4, 3, "Num And Dis Judge",
"result = NG Num RGB255, Add New qx,Blob idx %d ", tem.blobIdx);
m_reultList.resultList.push_back(tem);
}
}
}
}
return 0;
}

@ -0,0 +1,43 @@
/*
* FileName:CoreLogicFactory.cpp
* Version:V1.0
* Description:
* Created On:Mon Sep 10 11:13:16 UTC 2018
* Modified date:
* Author:Sky
*/
#include "SingleGPU.h"
AI_SingleGPU *AI_SingleGPU::m_pInstance[MAX_GPU_NUMBER] = {nullptr};
AI_SingleGPU::CGarbo AI_SingleGPU::m_garbo;
AI_SingleGPU::AI_SingleGPU(int nGpuIdx)
{
m_nGpuIdx = nGpuIdx;
cout << "AI_SingleGPU GPU:" << m_nGpuIdx << " create succ" << endl;
}
AI_SingleGPU::~AI_SingleGPU()
{
// cout << "单例对象销毁!" << endl;
}
AI_SingleGPU *AI_SingleGPU::GetInstance(int nGpuIdx)
{
if (nGpuIdx < 0 || nGpuIdx >= MAX_GPU_NUMBER)
{
return NULL;
}
if (nullptr == m_pInstance[nGpuIdx])
{
std::mutex mutex_;
mutex_.lock(); // 需要自己采用适当的互斥方式
if (nullptr == m_pInstance[nGpuIdx])
{
m_pInstance[nGpuIdx] = new AI_SingleGPU(nGpuIdx);
}
mutex_.unlock();
}
return m_pInstance[nGpuIdx];
}

@ -0,0 +1,68 @@
#CMake
cmake_minimum_required (VERSION 3.5)
project(rootproject)
set(CHECK_WORK_Value "POL_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(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("")
# CommonUtil
add_subdirectory(AlgorithmModule)
MESSAGE("")

@ -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/polet 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,63 @@
#ifndef ConfigBase_H_
#define ConfigBase_H_
#include <string>
#define CONFIGBASE_VERSION 4
enum CONFIG_TYPE_
{
ConfigType_Analysisy_Common_XL,
ConfigType_Check_XL,
ConfigType_Image_In,
ConfigType_Image_out,
ConfigType_BloB,
ConfigType_Count,
};
struct ImageInfo
{
int width;
int height;
int channels;
ImageInfo()
{
width = 0;
height = 0;
channels = 0;
}
void copy(ImageInfo tem)
{
this->width = tem.width;
this->height = tem.height;
this->channels = tem.channels;
}
void print(std::string str)
{
printf("%s width=%d height=%d channels=%d\n", str.c_str(), width, height, channels);
}
};
class ConfigBase
{
protected:
ConfigBase() {}
public:
// delete camera interface
~ConfigBase() {}
static ConfigBase *GetInstance();
// 获取参数更新状态 true 有更新
virtual bool GetConfigUpdataStatus(int nConfigType, int nidx) = 0;
// 复制想使用的参数
virtual int GetConfig(int nConfigType, void *pconfig) = 0;
// 更新参数 pconfig 参数指针nConfigType 需要更新的参数类型 返回0 成功 其他异常
virtual int UpdateConfig(void *pconfig, int nConfigType) = 0;
virtual int UpdateJSONConfig(void *pconfig, int nConfigType) = 0;
// 返回检测版本信息
virtual std::string GetVersion() = 0;
// 返回错误信息
virtual std::string GetErrorInfo() = 0;
};
#endif

@ -0,0 +1,46 @@
#ifndef ConfigInstance_H_
#define ConfigInstance_H_
#include "JsonCoversion.h"
#include <stdio.h>
#include <string.h>
#include <thread>
#include "ConfigBase.h"
#include "Define.h"
#include "JsonConfig.h"
#include "CheckConfigDefine.h"
class ConfigInstance : public ConfigBase
{
public:
ConfigInstance();
~ConfigInstance();
bool GetConfigUpdataStatus(int nConfigType,int nidx);
// 获取想使用的参数
int GetConfig(int nConfigType,void *pconfig) ;
// 更新参数 pconfig 参数指针nConfigType 需要更新的参数类型 返回0 成功 其他异常
int UpdateConfig(void *pconfig, int nConfigType);
int UpdateJSONConfig(void *pconfig, int nConfigType);
// 返回检测版本信息
std::string GetVersion();
// 返回错误信息
std::string GetErrorInfo();
private:
// updata analysis cofnig
int Updata_analysis(Json::Value json_value);
int Updata_Check(Json::Value json_value);
//设置 参数更新状态
int SetStatus( int nConfigType);
// 成员变量
private:
int m_ErrorValue; //错误代码
std::mutex mutex_status;
bool m_USER_ConfigUpdataStatusList[ConfigType_Count][MAX_USER_COUNT];
AnalysisyConfigST m_AnalysisyConfig;
CheckConfigST m_CheckConfig;
};
#endif

@ -0,0 +1,46 @@
#ifndef Define_H_
#define Define_H_
#include <string>
// 参数使用最大的用户数 用以更新 参数使用
#define MAX_USER_COUNT 10
enum ERROR_TYPE_Config_
{
ERROR_Type_Ok,
ERROR_Type_JsonNull,
ERROR_Type_ConfigType,
ERROR_Type_Count,
};
static const std::string ERROR_TYPE_Names[] =
{
"OK",
"Json Is Null",
"Config Type Error"};
struct CommonParamST
{
std::string image;
std::string skuName;
std::string value;
CommonParamST()
{
image = "";
value = "";
skuName = "";
}
void copy(CommonParamST tem)
{
this->image = tem.image;
this->value = tem.value;
this->skuName = tem.skuName;
}
};
enum CHECK_INSTUCT_
{
CHECK_INSTUCT_NULL = 1, // 空
CHECK_INSTUCT_WhiteAndBlack = CHECK_INSTUCT_NULL * 2, // WTB,BTW,HB3,HB4 使用单独检查方法
};
#endif

@ -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,19 @@
/*
* @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 "ConfigBase.h"
#include "ConfigInstance.h"
ConfigBase* ConfigBase::GetInstance()
{
return (ConfigBase*)new ConfigInstance();
}
bool compareBylay(const RegionConfigST &a, const RegionConfigST &b)
{
return a.basicInfo.lay < b.basicInfo.lay;
}

@ -0,0 +1,213 @@
/*
* @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 "ConfigInstance.h"
ConfigInstance::ConfigInstance()
{
m_ErrorValue = ERROR_Type_Ok;
}
ConfigInstance::~ConfigInstance()
{
}
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);
}
}
// for (int i = 0; i < m_AnalysisyConfig.commonCheckConfig.nodeConfigArr.size(); i++)
// {
// m_AnalysisyConfig.commonCheckConfig.nodeConfigArr.at(i).ToSheildMaskImg();
// // 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 @@
#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,23 @@
# 阿加犀工业检测算法调用通用库
## 介绍
京东方 检测算法so
## 环境
1、opencv
2、tensorRT
## 使用
1、把本地的TensorRT 头文件拷贝到 include文件下中。/home/aidlux/drivers/tensorrt/TensorRT-8.2.1.8/samples/common/
2、修改模型输入、输出尺寸。ImgCheckConfig.h AI_IN_IMAGE_WIDTH AI_IN_IMAGE_HEIGHT AI_OUT_IMAGE_WIDTH AI_OUT_IMAGE_HEIGHT
3、修改模型输入参数宏定义 作为变量初始化参数
### 最近更新 Update
### Notes
+ 1、如果不能正确显示中文有可能系统没有安装中文字符 sudo apt-get install language-pack-zh-hans
### Author
- [谢文吉]

@ -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}")

@ -0,0 +1,15 @@
if(NOT DEFINED ModuleName OR ModuleName EQUAL "")
set(ModuleName "DefaultModule")
endif()
# BUILD_ARCH:x86_64 aarch64 gcc -v Target
if(NOT DEFINED BUILD_ARCH)
set(BUILD_ARCH x86_64 CACHE STRING "Arch of this project")
endif()
if(NOT "${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}" STREQUAL "${CMAKE_BINARY_DIR}/../lib/${BUILD_ARCH}/")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/${BUILD_ARCH}/)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/${BUILD_ARCH}/)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/)
endif()
link_directories(${CMAKE_ARCHIVE_OUTPUT_DIRECTORY})

@ -0,0 +1,2 @@
message(STATUS "build <${ModuleName}>")
message(STATUS " ARCH type:${BUILD_ARCH} Mode:${CMAKE_BUILD_TYPE}")
Loading…
Cancel
Save