tmp backup

This commit is contained in:
rci
2024-10-20 16:49:57 +08:00
parent cfe1ef0419
commit da29e77880
27 changed files with 1471 additions and 1563 deletions
@@ -3,7 +3,7 @@ get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME)
string(TIMESTAMP RUN_TIME)
message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME})
set(DLL_NAMES "opencv" "halcon" "Myalgo" "myTools" )
set(DLL_NAMES "opencv" "halcon" "halconAlgo" "myTools" "handdleAI")
foreach(child ${DLL_NAMES})
LIST(APPEND ENV_INCLUDE ${${child}_include})
LIST(APPEND ENV_LIB ${${child}_lib})
@@ -39,7 +39,7 @@ FILE(GLOB UI_FILES "./*.ui")
#find_package(Qt5 COMPONENTS Core REQUIRED)
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS network REQUIRED)
add_library(${CURRENT_FOLDER} SHARED
${HEAD_FILES}
${SRC_FILES}
@@ -58,6 +58,7 @@ set_target_properties(${CURRENT_FOLDER} PROPERTIES LINKER_LANGUAGE C
target_link_libraries(${CURRENT_FOLDER} PRIVATE
${ENV_TARGET}
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Network
)
@@ -1,94 +1,151 @@
#include "Hd_AI_algo_jixing1.h"
#include "Hd_AI_algo_hanHou.h"
#include <QDateTime>
#include <codecvt>
#include <QtConcurrent/QtConcurrent>
#include <qfuture.h>
#include <QTextCodec>
#include "Myalgo.h"
#include <corecrt_wstring.h>
#include <myTools.h>
#include <filesystem>
#include <myTools.h>
#include <algo.h>
using namespace cv;
//原图保存文件夹
QString oriImgSaveDir = "D:/601线/超声波预焊01机/极性检测CCD/原图/";
QByteArray silieResultText = "0";
QByteArray fanzheResultText = "0";
QByteArray jiErWidth = "0";
QByteArray jiErHeight = "0";
QByteArray hanYin1 = "0";
QByteArray hanYin2 = "0";
//原图保存文件夹s
QString oriImgSaveDir = "D:/601线/预焊CCD/焊后检测CCD/原图/";
//原图class图保存文件夹
QString classImgSaveDir = "D:/601线/超声波预焊01机/极性检测CCD/class图/";
QString classImgSaveDir = "D:/601线/预焊CCD/焊后检测CCD/class图/";
//结果保存文件夹
QString resImgSaveDir = "D:\\601线\\超声波超声波预焊01机\\极性检测CCD\\结果图\\";
QString resImgSaveDir = "D:/601线/预焊CCD/焊后检测CCD/结果图/";
//切图的class的width,根据项目实际设置!
int sizeW = 150;
int sizeW = 150;
//切图的class的height,根据项目实际设置!
int sizeH = 150;
int sizeH = 150;
//切图的class的width,根据项目实际设置!0为黑,255为白;
int fillColour = 0;
int algoResult;
int fillColour = 0;
//检测线程锁
QMutex* detect_mutex;
QMutex* detect_mutex;
//保存线程锁
QMutex* saveStruct_mutex;
QMutex* saveStruct_mutex;
//检测线程运行标志
bool ifdetectThread = false;
bool ifdetectThread = false;
QString cameraKey_index = "";
QString cameraKey_index = "";
//初始化参数列表
QByteArrayList initValueList;
static void createDirectoryIfNotExists(const QString& path) {
QDir dir;
dir.mkpath(path);
}
static std::string getCurrentTime() {
//初始化参数列表
QByteArrayList initValueList;
static void createDirectoryIfNotExists(const QString& path) {
QDir dir;
dir.mkpath(path);
}
static std::string getCurrentTime() {
// 获取当前时间点
auto now = std::chrono::system_clock::now();
// 转换为字符串
auto currentTime = std::chrono::system_clock::to_time_t(now);
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 100;
std::tm* localTime = std::localtime(&currentTime);
std::stringstream ss;
ss << std::put_time(localTime, "%H-%M-%S") << "-" << std::setfill('0') << std::setw(2) << ms.count();
return ss.str();
}
static QString getCurrentDate()
{
QDateTime currentDateTime = QDateTime::currentDateTime();
return currentDateTime.toString("yyyy-MM-dd");
}
static QString getCurrentHour()
{
QDateTime currentDateTime = QDateTime::currentDateTime();
return QString::number(currentDateTime.time().hour()) + "H";
}
inline std::string utf8_to_gbk(const std::string& str)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
std::wstring tmp_wstr = conv.from_bytes(str);
//GBK locale name in windows
const char* GBK_LOCALE_NAME = ".936";
std::wstring_convert<std::codecvt_byname<wchar_t, char, mbstate_t>> convert(new std::codecvt_byname<wchar_t, char, mbstate_t>(GBK_LOCALE_NAME));
return convert.to_bytes(tmp_wstr);
}
QString byteArrayToUnicode(const QByteArray array) {
// state用于保存转换状态,它的成员invalidChars,可用来判断是否转换成功
// 如果转换成功,则值为0,如果值大于0,则说明转换失败
QTextCodec::ConverterState state;
// 先尝试使用utf-8的方式把QByteArray转换成QString
QString text = QTextCodec::codecForName("UTF-8")->toUnicode(array.constData(), array.size(), &state);
// 如果转换时无效字符数量大于0,说明编码格式不对
if (state.invalidChars > 0)
{
// 再尝试使用GBK的方式进行转换,一般就能转换正确(当然也可能是其它格式,但比较少见了)
text = QTextCodec::codecForName("GBK")->toUnicode(array);
}
return text;
}
// 获取当前时间点
auto now = std::chrono::system_clock::now();
// 转换为字符串
auto currentTime = std::chrono::system_clock::to_time_t(now);
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 100;
std::tm* localTime = std::localtime(&currentTime);
std::stringstream ss;
ss << std::put_time(localTime, "%H-%M-%S") << "-" << std::setfill('0') << std::setw(2) << ms.count();
return ss.str();
}
static QString getCurrentDate()
{
QDateTime currentDateTime = QDateTime::currentDateTime();
return currentDateTime.toString("yyyy-MM-dd");
}
static QString getCurrentHour()
{
QDateTime currentDateTime = QDateTime::currentDateTime();
return QString::number(currentDateTime.time().hour())+"H";
}
QString byteArrayToUnicode(const QByteArray array) {
// state用于保存转换状态,它的成员invalidChars,可用来判断是否转换成功
// 如果转换成功,则值为0,如果值大于0,则说明转换失败
QTextCodec::ConverterState state;
// 先尝试使用utf-8的方式把QByteArray转换成QString
QString text = QTextCodec::codecForName("UTF-8")->toUnicode(array.constData(), array.size(), &state);
// 如果转换时无效字符数量大于0,说明编码格式不对
if (state.invalidChars > 0)
{
// 再尝试使用GBK的方式进行转换,一般就能转换正确(当然也可能是其它格式,但比较少见了)
text = QTextCodec::codecForName("GBK")->toUnicode(array);
}
return text;
}
static cv::Rect findMaxAreaContour(cv::Mat src)
{
int maxIndex = 0, maxArea = 0;
std::vector<std::vector<cv::Point>>contours;
cv::findContours(src, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
if (contours.size() == 0)
return cv::Rect(0, 0, 0, 0);
for (int i = 0; i < contours.size(); i++)
{
int Area = cv::contourArea(contours[i]);
if (Area > maxArea)
{
maxArea = Area;
maxIndex = i;
}
}
if (contours.size() != 0)
return cv::boundingRect(contours[maxIndex]);
return cv::Rect(0, 0, 0, 0);
}
inline std::string utf8_to_gbk(const std::string& str)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
std::wstring tmp_wstr = conv.from_bytes(str);
//GBK locale name in windows
const char* GBK_LOCALE_NAME = ".936";
std::wstring_convert<std::codecvt_byname<wchar_t, char, mbstate_t>> convert(new std::codecvt_byname<wchar_t, char, mbstate_t>(GBK_LOCALE_NAME));
return convert.to_bytes(tmp_wstr);
}
void getAllFiles(std::string path, std::vector<std::string>& files, std::string format)
{
intptr_t hFile = 0;//文件句柄
struct _finddata_t fileinfo;//文件信息
std::string p;
if ((hFile = _findfirst(p.assign(path).append("\\*" + format).c_str(), &fileinfo)) != -1) //文件存在
{
do
{
if ((fileinfo.attrib & _A_SUBDIR))//判断是否为文件夹
{
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)//文件夹名中不含"."和".."
{
files.push_back(p.assign(path).append("\\").append(fileinfo.name)); //保存文件夹名
getAllFiles(p.assign(path).append("\\").append(fileinfo.name), files, format); //递归遍历文件夹
}
}
else
{
files.push_back(p.assign(path).append("\\").append(fileinfo.name));//如果不是文件夹,储存文件名
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
QString getOriSaveFromat()
{
return oriImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//"
+ "ORI_" + cameraKey_index + "_" + QString::fromStdString(getCurrentTime()) + ".bmp";
}
QString getResSaveFromat()
{
return resImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//"
+ "RES_" + cameraKey_index + "_" + QString::fromStdString(getCurrentTime()) + ".png";
}
// 缺陷信息结构体
typedef struct {
QString defectName = "";//缺陷名称
@@ -223,6 +280,8 @@ void GetStringSize(HDC hdc, const char* str, int* w, int* h)
if (h != 0) *h = size.cy;
}
//在图像写中文,英文也可以写
void putTextZH(cv::Mat& dst, const char* str, cv::Point org, cv::Scalar color, int fontsize,
const char* fn = "Arial", bool italic = false, bool underline = false)
{
@@ -388,7 +447,7 @@ void drawDefects(cv::Mat& sourceMat, QQueue<defectInfo> defectInfoList)
//判断文件夹是否存在,不存在则创建
void Hd_AI_algo_jixing1::isDirExist(QString fullDirName)
void Hd_AI_algo_hanHou::isDirExist(QString fullDirName)
{
QDir* photo = new QDir;
bool exist = photo->exists(fullDirName);
@@ -406,28 +465,27 @@ void Hd_AI_algo_jixing1::isDirExist(QString fullDirName)
photo = nullptr;
}
Hd_AI_algo_jixing1* create()
Hd_AI_algo_hanHou* create()
{
qDebug() << "[INFO] " << " Hd_AI_algo_jixing1 create success!";
return new Hd_AI_algo_jixing1;
qDebug() << "[INFO] " << " Hd_AI_algo_hanHou create success!" ;
return new Hd_AI_algo_hanHou;
}
void destory(Hd_AI_algo_jixing1* ptr)
void destory(Hd_AI_algo_hanHou* ptr)
{
qDebug() << "[INFO] " << "Hd_AI_algo_jixing1 destory success!";
if (ptr)
qDebug() << "[INFO] " << "Hd_AI_algo_hanHou destory success!";
if(ptr)
{
delete ptr;
ptr = nullptr;
}
}
Hd_AI_algo_jixing1::Hd_AI_algo_jixing1()
Hd_AI_algo_hanHou::Hd_AI_algo_hanHou()
{
detect_mutex = new QMutex;
saveStruct_mutex = new QMutex;
ifdetectThread = false;
for (int i = 0; i < 4; i++)
{
QString DirPath = "E:/testImg/source" + QString::number(i);
@@ -447,7 +505,7 @@ Hd_AI_algo_jixing1::Hd_AI_algo_jixing1()
}
}
Hd_AI_algo_jixing1::~Hd_AI_algo_jixing1()
Hd_AI_algo_hanHou::~Hd_AI_algo_hanHou()
{
ifdetectThread = false;
Sleep(10);
@@ -461,29 +519,35 @@ Hd_AI_algo_jixing1::~Hd_AI_algo_jixing1()
delete saveStruct_mutex;
saveStruct_mutex = nullptr;
}
handdleAI::DestroySegObj(seg_hanHouSiLie);
handdleAI::DestroySegObj(seg_hanHouFanZhe);
/*DestroySegObj(pSeg);
DestroyClsObj(pCls);*/
}
//从类中读数据到实例对象
bool Hd_AI_algo_jixing1::readData(std::vector<cv::Mat>& vec_mat, QByteArray& data)
bool Hd_AI_algo_hanHou::readData(std::vector<cv::Mat>&vec_mat,QByteArray &data)
{
detect_mutex->lock();
//qDebug() << __FUNCTION__ << " line:" <<__LINE__ << " data len:" << data.length();
if (resMat.size() > 0)
if (resMat.size()>0)
{
vec_mat.push_back(resMat[0]);
resMat.clear();
}
else
{
if (HikMat.size() > 0)
if(HikMat.size()>0)
vec_mat.push_back(HikMat[0]);
//qDebug() << __FUNCTION__ << " line:" << __LINE__ << " resMat.data err:";
}
//if (allNum++ % 2 == 0)
// data = "2*3*2";// resByte.dequeue();
//else
data = QByteArray::number(algoResult) + "&" + QByteArray::number(algoResult - 1) + "+" + QByteArray::number(algoResult);
data = "1*&" + fanzheResultText + "&" + silieResultText
+ "+" + fanzheResultText + "+" + silieResultText
+ "+" + jiErWidth + "+" + jiErHeight
+ "+" + hanYin1 + "+" + hanYin2
;//1OK,2NG
resByte.clear();
////之后根据结果类修改
//if(resIfNg == true)
@@ -491,41 +555,40 @@ bool Hd_AI_algo_jixing1::readData(std::vector<cv::Mat>& vec_mat, QByteArray& dat
//else data = "OK";
detect_mutex->unlock();
/*if(cameraKey_index.contains('_'))
qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getDetectData--CameraName:"
qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getDetectData--CameraName:"
<< cameraKey_index.split("_")[0] << " imgIndex:" << cameraKey_index.split("_")[1];
else
qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getDetectData--CameraName imgIndex:" << cameraKey_index;*/
return true;
}
//从类中读数据到实例对象
bool Hd_AI_algo_jixing1::encodeResultValue(QVector<std::string> append_value, QByteArray& resultByte)
bool Hd_AI_algo_hanHou::encodeResultValue(QVector<std::string> append_value,QByteArray &resultByte)
{
try
{
std::string sendMsg;
for (int i = 0; i < append_value.size(); i++)
for(int i = 0 ; i < append_value.size();i++)
{
std::string value = append_value.at(1);
//type
int type = 3;
std::string m_type;
m_type.insert(0, 4, '1');
memcpy((void*)m_type.c_str(), (void*)&type, 4);
m_type.insert(0,4,'1');
memcpy ( (void*)m_type.c_str(),(void*)&type,4 );
sendMsg.append(m_type);
//len
int len = value.length();
std::string m_len;
m_len.insert(0, 4, '1');
memcpy((void*)m_len.c_str(), (void*)&len, 4);
m_len.insert(0,4,'1');
memcpy ( (void*)m_len.c_str(),(void*)&len,4 );
sendMsg.append(m_len);
//data x
sendMsg.append(value);
}
resultByte = QByteArray::fromStdString(sendMsg);
}
catch (QString ev)
} catch (QString ev)
{
qCritical() << "[Error] " << " ev:" << ev;
return false;
@@ -533,13 +596,13 @@ bool Hd_AI_algo_jixing1::encodeResultValue(QVector<std::string> append_value, QB
return true;
}
int myallNum[4] = { 0 };
int myallNum[4] = {0};
QMap<int, cv::Mat> lastImgMap;
//接收数据
bool Hd_AI_algo_jixing1::writeData(std::vector<cv::Mat>& vec_mat, QByteArray& data)
bool Hd_AI_algo_hanHou::writeData(std::vector<cv::Mat>& vec_mat, QByteArray &data)
{
//qDebug() << __FUNCTION__ << "line:"<< __LINE__ << " data len" << data.length() ;
if (vec_mat.empty())
if(vec_mat.empty())
{
qCritical() << "[Error] " << " vec_mat is null !";
return false;
@@ -547,7 +610,7 @@ bool Hd_AI_algo_jixing1::writeData(std::vector<cv::Mat>& vec_mat, QByteArray& da
detect_mutex->lock();
HikMat.clear();
for (int i = 0; i < vec_mat.size(); i++)
HikMat.enqueue(vec_mat[i]);
HikMat.enqueue(vec_mat[i]);
QByteArray source_savePath;
QByteArray sData = data;
@@ -558,7 +621,7 @@ bool Hd_AI_algo_jixing1::writeData(std::vector<cv::Mat>& vec_mat, QByteArray& da
cameraKey_index = splitDataList[2];
QByteArray saveDir = splitDataList[0] + "/" + splitDataList[1] + "/";
isDirExist(byteArrayToUnicode(saveDir)); //不存在,创建
QString sdataTime = QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz");
QString sdataTime= QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz");
source_savePath = splitDataList[0] + "/" + splitDataList[1] + "/" + sdataTime.toLocal8Bit() + "-" + splitDataList[2] + "-" + splitDataList[3];// +".bmp";
}
//int index = -1;
@@ -584,11 +647,8 @@ bool Hd_AI_algo_jixing1::writeData(std::vector<cv::Mat>& vec_mat, QByteArray& da
}*/
createDirectoryIfNotExists(oriImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//");
addImgToSaveStruct(HikMat[0], "0", oriImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//"
"ORI" + cameraKey_index + QString::fromStdString(getCurrentTime()) + ".bmp");//保存原图
addImgToSaveStruct(HikMat[0], "0",getOriSaveFromat());//保存原图
//if (!source_savePath.isEmpty())
//{
// //std::cout << "try savePath::" << savePath.toStdString() << std::endl;
@@ -639,7 +699,7 @@ bool Hd_AI_algo_jixing1::writeData(std::vector<cv::Mat>& vec_mat, QByteArray& da
/*saveKey.enqueue("datalist[0]");
Dir2D.enqueue("datalist[1]");
QStringList SN_dataTime;
QStringList SN_dataTime;
SN_dataTime = datalist[3].split('_');
DateTime1 = "SN_dataTime[1]";
SN.enqueue("SN_dataTime[0]");*/
@@ -656,7 +716,7 @@ bool Hd_AI_algo_jixing1::writeData(std::vector<cv::Mat>& vec_mat, QByteArray& da
//传入initParas函数,格式为:相机key+参数名1#参数值1#参数值2+参数名2#参数值1...
//初始化
bool Hd_AI_algo_jixing1::initParas(QByteArray& byte)
bool Hd_AI_algo_hanHou::initParas(QByteArray& byte)
{
initValueList = byte.split('+');
QStringList valueiList;
@@ -681,13 +741,13 @@ bool Hd_AI_algo_jixing1::initParas(QByteArray& byte)
valueiList.append(valuei);
}
/*pSeg = CreateSegObjS(pSeg_modulePath, 128, gpuId);
pCls = CreateClsObjV3(pCls_modulePath, gpuId, 1);*/
//StationNo = vec_ret.at(0).toInt();
seg_hanHouSiLie = handdleAI::CreateSegObjS("./model/seg-yuHanhanHouSiLie.BHD");
seg_hanHouFanZhe = handdleAI::CreateSegObjS("./model/seg-yuHanhanFanZhe.BHD");
//InitThreads(StationNo, img2D);
//InitModels(StationNo, img2D);
@@ -696,9 +756,9 @@ bool Hd_AI_algo_jixing1::initParas(QByteArray& byte)
//线程检测:结果类完成时,使用
//ifThreadRunDetect = true;
//QFuture<void> future1 = QtConcurrent::run(this, &Hd_AI_algo_jixing1::detectThread);
//QFuture<void> future1 = QtConcurrent::run(this, &Hd_AI_algo_hanHou::detectThread);
//运行存图线程
QFuture<void> future2 = QtConcurrent::run(this, &Hd_AI_algo_jixing1::saveImgThread);
QFuture<void> future2 = QtConcurrent::run(this, &Hd_AI_algo_hanHou::saveImgThread);
//detectThread();
//原图总文件夹
@@ -708,48 +768,149 @@ bool Hd_AI_algo_jixing1::initParas(QByteArray& byte)
//结果图总文件夹
isDirExist(resImgSaveDir);
//qDebug() << "[INFO] " << " StationNo:" << StationNo << " img2D:" << img2D ;
return true;
}
// 解码
bool Hd_AI_algo_jixing1::decodeAiValue(QByteArray byte, QVector<QByteArray>& vec_ret)
bool Hd_AI_algo_hanHou::decodeAiValue(QByteArray byte,QVector<QByteArray> &vec_ret)
{
if (byte.isEmpty())
if(byte.isEmpty())
{
qCritical() << "[Error] " << " byte is null!";
return false;
}
/*******************************************/
byte.remove(0, 8);
QByteArray mm_data = byte.mid(0, 4);
memcpy((void*)&paramNum, (void*)mm_data.data(), 4);
byte.remove(0,8);
QByteArray mm_data = byte.mid(0,4);
memcpy((void*)&paramNum,(void*)mm_data.data(), 4);
qDebug() << "[INFO] " << " paramNum:" << paramNum;
byte.remove(0, 4);
byte.remove(0,4);
/*******************************************/
while (!byte.isEmpty())
{
int type = 0;
QByteArray m_type = byte.mid(0, 4);
memcpy((void*)&type, (void*)m_type.data(), 4);
byte.remove(0, 4);
QByteArray m_type = byte.mid(0,4);
memcpy((void*)&type,(void*)m_type.data(), 4);
byte.remove(0,4);
int len = 0;
QByteArray m_len = byte.mid(0, 4);
memcpy((void*)&len, (void*)m_len.data(), 4);
byte.remove(0, 4);
QByteArray m_len = byte.mid(0,4);
memcpy((void*)&len,(void*)m_len.data(), 4);
byte.remove(0,4);
QByteArray mm_data = byte.mid(0, len);
QByteArray mm_data = byte.mid(0,len);
vec_ret.append(mm_data);
byte.remove(0, len);
byte.remove(0,len);
}
return true;
}
void halconAlgoProcess(cv::Mat& img,cv::Mat &Paint)//算法先画
{
HObject ho_Image;
HTuple hv_Pix(0.0303);
HTuple hv_out_line;
HTuple hv_out_Soldering_line;
HTuple hv_distance;
HTuple hv_Make;
MatToHObject(img, &ho_Image);
cs_628_jier_T(ho_Image,hv_Pix,&hv_out_line,&hv_out_Soldering_line,
&hv_distance, & hv_Make);
if (hv_Make.D() == 1)
{
cv::line(Paint,
cv::Point(hv_out_line[1].D() / 2, hv_out_line[0].D() / 2),
cv::Point(hv_out_line[3].D() / 2, hv_out_line[2].D() / 2),
cv::Scalar(0, 255, 0), 5);
cv::line(Paint,
cv::Point(hv_out_line[5].D() / 2, hv_out_line[4].D() / 2),
cv::Point(hv_out_line[7].D() / 2, hv_out_line[6].D() / 2),
cv::Scalar(0, 255, 0), 5);
cv::line(Paint,
cv::Point(hv_out_line[9].D() / 2, hv_out_line[8].D() / 2),
cv::Point(hv_out_line[11].D() / 2, hv_out_line[10].D() / 2),
cv::Scalar(0, 255, 0), 5);
cv::line(Paint,
cv::Point(hv_out_line[13].D() / 2, hv_out_line[12].D() / 2),
cv::Point(hv_out_line[15].D() / 2, hv_out_line[14].D() / 2),
cv::Scalar(0, 255, 0), 5);
cv::line(Paint,
cv::Point(hv_out_Soldering_line[1].D() / 2, hv_out_Soldering_line[0].D() / 2),
cv::Point(hv_out_Soldering_line[3].D() / 2, hv_out_Soldering_line[2].D() / 2),
cv::Scalar(0, 255, 0), 5);
cv::line(Paint,
cv::Point(hv_out_Soldering_line[5].D() / 2, hv_out_Soldering_line[4].D() / 2),
cv::Point(hv_out_Soldering_line[7].D() / 2, hv_out_Soldering_line[6].D() / 2),
cv::Scalar(0, 255, 0), 5);
double height = hv_distance[0].D();
double weight = hv_distance[1].D();
double upEdge = hv_distance[2].D();
double leftEdge = hv_distance[3].D();
jiErWidth = QByteArray::number(weight);
jiErHeight = QByteArray::number(height);
hanYin1 = QByteArray::number(upEdge);
hanYin2 = QByteArray::number(leftEdge);
putTextHusky(Paint, utf8_to_gbk("极耳高" + std::to_string(height)).c_str(),
cv::Point(0, 0), cv::Scalar(0, 255, 0), 300);
putTextHusky(Paint, utf8_to_gbk("极耳宽" + std::to_string(weight)).c_str(),
cv::Point(0, 250), cv::Scalar(0, 255, 0), 300);
putTextHusky(Paint, utf8_to_gbk("上间距" + std::to_string(upEdge)).c_str(),
cv::Point(0, 500), cv::Scalar(0, 255, 0), 300);
putTextHusky(Paint, utf8_to_gbk("下间距" + std::to_string(leftEdge)).c_str(),
cv::Point(0, 750), cv::Scalar(0, 255, 0), 300);
}
else
putTextHusky(Paint, utf8_to_gbk("算法异常1").c_str(), cv::Point(0, 0), cv::Scalar(0, 255, 0), 300);
}
void siLieProcess(cv::Mat& segRes, cv::Mat& Paint,bool& result)
{
std::vector<std::vector<cv::Point>> contours;
cv::findContours(segRes, contours, cv::RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
int cnt = 0;
for (auto r : contours)
{
cv::Rect originRect = cv::boundingRect(r);
if (originRect.width < 50 || originRect.height < 50)
continue;
cv::Rect rect = originRect;
//cv::Mat clsImg = cutImg2Cls(rect, img);
//int clsRes = clsPtr->Evaluate(clsImg);
cv::Scalar color = cv::Scalar(0, 0, 255, 30);
cv::rectangle(Paint, originRect, color, 4);
putTextHusky(Paint, utf8_to_gbk("撕裂").c_str(), cv::Point(rect.x - rect.width / 2, rect.y - rect.height / 2), cv::Scalar(0, 255, 0), 100);
result = false;
}
}
void fanZheProcess(cv::Mat& segRes, cv::Mat& Paint, bool& result)
{
std::vector<std::vector<cv::Point>> contours;
cv::findContours(segRes, contours, cv::RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
int cnt = 0;
for (auto r : contours)
{
cv::Rect originRect = cv::boundingRect(r);
if (originRect.width < 100 || originRect.height < 50)
continue;
cv::Rect rect = originRect;
//cv::Mat clsImg = cutImg2Cls(rect, img);
//int clsRes = clsPtr->Evaluate(clsImg);
cv::Scalar color = cv::Scalar(0, 0, 255, 30);
cv::rectangle(Paint, originRect, color, 4);
putTextHusky(Paint, utf8_to_gbk("翻折").c_str(), cv::Point(rect.x- rect.width/2, rect.y-rect.height/2), cv::Scalar(0, 255, 0), 100);
result = false;
}
}
//---------检测流程,根据实际项目修改---------
bool Hd_AI_algo_jixing1::AIdetect(cv::Mat img2D, QString mysaveKey, QString myDir2D, QString mySN, QString myDataTime)
bool Hd_AI_algo_hanHou::AIdetect(cv::Mat img2D, QString mysaveKey, QString myDir2D, QString mySN, QString myDataTime)
{
try
{
@@ -779,63 +940,40 @@ bool Hd_AI_algo_jixing1::AIdetect(cv::Mat img2D, QString mysaveKey, QString myDi
// csvName.write(lines[i].toStdString().c_str());
// csvName.close();
//}
//sourceImg = cv::imread("D:\\mySN15-46-33-86.bmp",-1);
sourceImg = cv::imread("D:/1/Image_20241017204025590.bmp", -1);
cv::Mat Paint;
sourceImg.copyTo(Paint);
if(Paint.channels() == 1)
cvtColor(Paint, Paint, COLOR_GRAY2BGR);
QQueue<defectInfo> defectInfoList;
//极性检测
HObject ho_Image;
HTuple hv_out_Value;
HTuple hv_Make;
//cv::imwrite("C://1.bmp", sourceImg);
MatToHObject(sourceImg, &ho_Image);
_628_1_Polarity_detection(ho_Image, &hv_out_Value, &hv_Make);
//相机1 OK为铝 NG为铜s
if (hv_Make.D() != -1)
{
if (hv_out_Value.D() == 1)//铝
{
putTextHusky(sourceImg, utf8_to_gbk("铝极").c_str(), cv::Point(0, 0), cv::Scalar(0, 255, 0), 300);
//cv::putText(sourceImg, "Aluminium", cv::Point(0, 240), 2, 10, cv::Scalar(0, 255, 0), 10);
cv::putText(sourceImg, "OK", cv::Point(0, 550), 2, 10, cv::Scalar(0, 255, 0), 10);
algoResult = 1;
//Result = 1 ? 2;
//Result = 1;
}
else if (hv_out_Value.D() == 2)//铜
{
putTextHusky(sourceImg, utf8_to_gbk("铜极").c_str(), cv::Point(0, 0), cv::Scalar(0, 255, 0), 300);
//cv::putText(sourceImg, "Copper", cv::Point(0, 240), 2, 10, cv::Scalar(0, 255, 0), 10);
cv::putText(sourceImg, "NG", cv::Point(0, 550), 2, 10, cv::Scalar(0, 0, 255), 10);
algoResult = 1;
}
else
{
putTextHusky(sourceImg, utf8_to_gbk("算法异常1").c_str(), cv::Point(0, 0), cv::Scalar(0, 255, 0), 300);
// cv::putText(sourceImg, "Algo error1", cv::Point(0, 240), 2, 10, cv::Scalar(0, 0, 255), 10);
//Result = 2;
}
}
else
{
putTextHusky(sourceImg, utf8_to_gbk("算法异常1").c_str(), cv::Point(0, 0), cv::Scalar(0, 255, 0), 300);
// cv::putText(sourceImg, "Algo error2", cv::Point(0, 240), 2, 10, cv::Scalar(0, 0, 255), 10);
}
ho_Image.Clear();
hv_out_Value.Clear();
hv_Make.Clear();
detect_mutex->lock();
//resMat = sourceImg.clone();
//sourceImg.copyTo(resMat);
resMat.push_back(sourceImg);
//结果图画框和缺陷,在resMat上绘制
if (resMat.size() > 0)
drawDefects(resMat[0], defectInfoList);
auto futrue = std::async(std::launch::async, halconAlgoProcess, sourceImg, Paint);//异步执行
cv::Mat segProcess;
cv::resize(sourceImg, segProcess, cv::Size(), 0.5, 0.5);
//撕裂检测
cv::Mat siLieSegRes = ~seg_hanHouSiLie->Evaluate(segProcess);//撕裂
cv::Mat fanZheSegRes = ~seg_hanHouFanZhe->Evaluate(segProcess);//翻折
futrue.wait();//等待halcon算法完成
bool silieOk = true, fanZheOk = true;
siLieProcess(siLieSegRes, Paint, silieOk);
fanZheProcess(fanZheSegRes, Paint, fanZheOk);
//QByteArray,根据实际项目进行解析
//参数,例:返回结果图;相机关键字(SN或userID)+保存路径+缺陷信息列表(缺陷名称,缺陷位置int(x,y,w,h),画框颜色Scalar(a,b,c),缺陷面积double)
if (silieOk == true)//OK
putTextHusky(Paint, utf8_to_gbk("撕裂OK").c_str(), cv::Point(4800, 50), cv::Scalar(0, 255, 0), 500);
else
putTextHusky(Paint, utf8_to_gbk("撕裂NG").c_str(), cv::Point(4800, 50), cv::Scalar(0, 0, 255), 500);
if (fanZheOk == true)//OK
putTextHusky(Paint, utf8_to_gbk("翻折OK").c_str(), cv::Point(4800, 300), cv::Scalar(0, 255, 0), 500);
else
putTextHusky(Paint, utf8_to_gbk("翻折NG").c_str(), cv::Point(4800, 300), cv::Scalar(0, 0, 255), 500);
resMat.push_back(Paint);
QJsonArray detaillists;
//QByteArrayList resQbyte;
for (int i = 0; i < defectInfoList.size(); i++)
@@ -857,10 +995,10 @@ bool Hd_AI_algo_jixing1::AIdetect(cv::Mat img2D, QString mysaveKey, QString myDi
detailObj.insert("defectRect.width", QString::number(mdefect.defectRect.width));
detailObj.insert("defectRect.height", QString::number(mdefect.defectRect.height));
detailObj.insert("defectScalar0", QString::number(mdefect.defectScalar[0]));
detailObj.insert("defectScalar1", QString::number(mdefect.defectScalar[1]));
detailObj.insert("defectScalar1", QString::number(mdefect.defectScalar[1]));
detailObj.insert("defectScalar2", QString::number(mdefect.defectScalar[2]));
detailObj.insert("defectArea", QString::number(mdefect.defectArea));
detailObj.insert("defectLength", QString::number(sqrt(mdefect.defectRect.width * mdefect.defectRect.width + mdefect.defectRect.height * mdefect.defectRect.height)));
detailObj.insert("defectLength", QString::number(sqrt(mdefect.defectRect.width* mdefect.defectRect.width+ mdefect.defectRect.height* mdefect.defectRect.height)));
detaillists.append(detailObj);
}
@@ -873,15 +1011,13 @@ bool Hd_AI_algo_jixing1::AIdetect(cv::Mat img2D, QString mysaveKey, QString myDi
//emit sendResultData(resMat, resQbyte);
//resQbyte.clear();
isDirExist(resImgSaveDir + mysaveKey1 + "/");
//isDirExist(resImgSaveDir + mysaveKey1 + "/");
QString qimgsavePath = resImgSaveDir + mysaveKey1 + "/" + mySN + myDataTime + ".png";
//存图数据入队,按需
QString sdataTime = QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz");
if (resMat.size() > 0)
if (resMat.size() > 0 )
{
createDirectoryIfNotExists(oriImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//");
addImgToSaveStruct(HikMat[0], "0", resImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//"
+ "RES" + cameraKey_index + QString::fromStdString(getCurrentTime()) + ".png");//保存原图
createDirectoryIfNotExists(resImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//");
addImgToSaveStruct(resMat[0], "0", getResSaveFromat());//保存原图
}
detect_mutex->unlock();
@@ -925,7 +1061,7 @@ bool Hd_AI_algo_jixing1::AIdetect(cv::Mat img2D, QString mysaveKey, QString myDi
}
//存图加入队列
void Hd_AI_algo_jixing1::addImgToSaveStruct(cv::Mat img2D, QString mysaveKey, QString savePath)
void Hd_AI_algo_hanHou::addImgToSaveStruct(cv::Mat img2D, QString mysaveKey, QString savePath)
{
//存图数据加保存队列,加锁,避免数据访问冲突
saveStruct_mutex->lock();
@@ -937,7 +1073,7 @@ void Hd_AI_algo_jixing1::addImgToSaveStruct(cv::Mat img2D, QString mysaveKey, QS
saveStruct.enqueue(mySave);
saveStruct_mutex->unlock();
}
void Hd_AI_algo_jixing1::saveImgThread()
void Hd_AI_algo_hanHou::saveImgThread()
{
while (1)
{
@@ -953,7 +1089,7 @@ void Hd_AI_algo_jixing1::saveImgThread()
saveImgStruct mysaveStruct = saveStruct.dequeue();
saveStruct_mutex->unlock();
stop = clock();
if (stop - start > 1000)
if(stop-start >1000)
std::cout << "lock stop-start >1000::************************" << stop - start << std::endl;
start = clock();
if (mysaveStruct.out_Mat.data)
@@ -961,17 +1097,17 @@ void Hd_AI_algo_jixing1::saveImgThread()
//std::cout << "savePath::" << mysaveStruct.savePath << std::endl;
stop = clock();
if (stop - start > 1000)
std::cout << "imwrite stop-start >1000::--------------------------" << stop - start << std::endl;
std::cout << "imwrite stop-start >1000::--------------------------"<< stop - start << std::endl;
_sleep(1);
}
}
}
//检测线程,应当只运行一次
void Hd_AI_algo_jixing1::detectThread()
void Hd_AI_algo_hanHou::detectThread()
{
do
{
if (!ifdetectThread)return;
if (!ifdetectThread)return;
//此两行代码,避免程序卡死;_sleep的时间根据实际项目调整
_sleep(2);
@@ -1001,9 +1137,9 @@ void Hd_AI_algo_jixing1::detectThread()
isDirExist(resImgSaveDir + mysaveKey);
}
//测试相机的,
//while (sourceImg1.cols > 2000)cv::resize(sourceImg1, sourceImg1, cv::Size(), 0.5, 0.5);
// while (sourceImg1.cols > 2000)cv::resize(sourceImg1, sourceImg1, cv::Size(), 0.5, 0.5);
//存图数据入队
//addImgToSaveStruct(sourceImg1, mysaveKey, oriImgSaveDir + mysaveKey + "/" + mySN + myDataTime + ".bmp");
@@ -1016,14 +1152,14 @@ void Hd_AI_algo_jixing1::detectThread()
myDir2D.clear();
mySN.clear();
myDataTime.clear();
qApp->processEvents();
qApp->processEvents();
} while (ifThreadRunDetect);
}
static int runNum = 0;
bool Hd_AI_algo_jixing1::run()
bool Hd_AI_algo_hanHou::run()
{
clock_t start, stop;
start = clock();
@@ -1031,14 +1167,14 @@ bool Hd_AI_algo_jixing1::run()
//Sleep(1000);
detectThread();
stop = clock();
qDebug() << __FUNCTION__ << "line:" << __LINE__ << " run start ::runNum::" << runNum++ << " cutTime::" << stop - start;
qDebug() << __FUNCTION__ << "line:" << __LINE__ << " run start ::runNum::" << runNum++<<" cutTime::"<<stop-start;
//qDebug() << __FUNCTION__ << "line:" << __LINE__ << "[INFO] " << "Mat_name: " << Mat_name << " run end";
return true;
}
bool Hd_AI_algo_jixing1::checkStatus()
bool Hd_AI_algo_hanHou::checkStatus()
{
status = moduleStatus;
return status;
@@ -1,5 +1,5 @@
#ifndef Hd_AI_algo_jixing1_H
#define Hd_AI_algo_jixing1_H
#ifndef Hd_AI_algo_hanHou_H
#define Hd_AI_algo_hanHou_H
#include <assert.h>
#include <atlstr.h>
@@ -15,13 +15,11 @@
#include <fstream>
#include <string>
#include <ctime>
#include <halconcpp/HalconCpp.h>
#include <opencv2/opencv.hpp>
#include "imgproc/imgproc_c.h"
#include "base.h"
#include "handleAI.h"
#pragma execution_character_set("utf-8")
@@ -34,14 +32,14 @@ struct saveImgStruct;
// std::string savePath; //保存路径
//};
//初始化流程(一次):Hd_AI_algo_jixing1,initParas
//初始化流程(一次):Hd_AI_algo_hanHou,initParas
//运行流程:writeData主线程把数据传过来,run,readData此线程把数据传主线程
class Hd_AI_algo_jixing1 :public Base
class Hd_AI_algo_hanHou :public Base
{
Q_OBJECT
public:
Hd_AI_algo_jixing1();
virtual ~Hd_AI_algo_jixing1();
Hd_AI_algo_hanHou();
virtual ~Hd_AI_algo_hanHou();
//从类中读数据到实例对象
bool readData(std::vector<cv::Mat>&,QByteArray&);
//实例对象把数据写入到类
@@ -56,11 +54,10 @@ public:
bool decodeAiValue(QByteArray byte,QVector<QByteArray> &vec_ret);
//---------检测流程,根据实际项目修改---------
bool AIdetect(cv::Mat img2D, QString saveKey, QString Dir2D, QString SN, QString DataTime);
handdleAI::pSegmentation* seg_hanHouSiLie;
handdleAI::pSegmentation* seg_hanHouFanZhe;
private:
int allNum = 0;
int StationNo=0;
int img2D = 2;
@@ -106,8 +103,8 @@ private:
extern "C"
{
Q_DECL_EXPORT Hd_AI_algo_jixing1 * create();
Q_DECL_EXPORT void destory(Hd_AI_algo_jixing1 * ptr);
Q_DECL_EXPORT Hd_AI_algo_hanHou * create();
Q_DECL_EXPORT void destory(Hd_AI_algo_hanHou * ptr);
}
//保存图片的结构体
struct saveImgStruct
@@ -3,7 +3,7 @@ get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME)
string(TIMESTAMP RUN_TIME)
message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME})
set(DLL_NAMES "opencv" "halcon" "Myalgo" "myTools" )
set(DLL_NAMES "opencv" "halcon" "halconAlgo""myTools" )
foreach(child ${DLL_NAMES})
LIST(APPEND ENV_INCLUDE ${${child}_include})
LIST(APPEND ENV_LIB ${${child}_lib})
@@ -4,9 +4,9 @@
#include <QtConcurrent/QtConcurrent>
#include <qfuture.h>
#include <QTextCodec>
#include "Myalgo.h"
#include <corecrt_wstring.h>
#include <myTools.h>
#include <algo.h>
using namespace cv;
//原图保存文件夹
@@ -14,7 +14,7 @@ using namespace cv;
//原图class图保存文件夹
QString classImgSaveDir = "D:/601线/超声波预焊01机/极性检测CCD/class图/";
//结果保存文件夹
QString resImgSaveDir = "D:\\601线\\超声波超声波预焊01机\\极性检测CCD\\结果图\\";
QString resImgSaveDir = "D:/601线/超声波超声波预焊01机/极性检测CCD/结果图/";
//切图的class的width,根据项目实际设置!
int sizeW = 150;
@@ -71,7 +71,16 @@ int algoResult;
std::wstring_convert<std::codecvt_byname<wchar_t, char, mbstate_t>> convert(new std::codecvt_byname<wchar_t, char, mbstate_t>(GBK_LOCALE_NAME));
return convert.to_bytes(tmp_wstr);
}
QString getOriSaveFromat()
{
return oriImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//"
+ "ORI_" + cameraKey_index + "_" + QString::fromStdString(getCurrentTime()) + ".bmp";
}
QString getResSaveFromat()
{
return resImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//"
+ "RES_" + cameraKey_index + "_" + QString::fromStdString(getCurrentTime()) + ".png";
}
QString byteArrayToUnicode(const QByteArray array) {
// state用于保存转换状态,它的成员invalidChars,可用来判断是否转换成功
@@ -586,8 +595,7 @@ bool Hd_AI_algo_jixing1::writeData(std::vector<cv::Mat>& vec_mat, QByteArray &da
createDirectoryIfNotExists(oriImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//");
addImgToSaveStruct(HikMat[0], "0", oriImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//"
"ORI" +cameraKey_index +QString::fromStdString(getCurrentTime())+".bmp");//保存原图
addImgToSaveStruct(HikMat[0], "0", getOriSaveFromat());//保存原图
//if (!source_savePath.isEmpty())
//{
// //std::cout << "try savePath::" << savePath.toStdString() << std::endl;
@@ -879,8 +887,7 @@ bool Hd_AI_algo_jixing1::AIdetect(cv::Mat img2D, QString mysaveKey, QString myDi
if (resMat.size() > 0)
{
createDirectoryIfNotExists(oriImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//");
addImgToSaveStruct(HikMat[0], "0", resImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//"
+ "RES" + cameraKey_index + QString::fromStdString(getCurrentTime()) + ".png");//保存原图
addImgToSaveStruct(resMat[0], "0", getResSaveFromat());//保存原图
}
detect_mutex->unlock();
@@ -3,7 +3,7 @@ get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME)
string(TIMESTAMP RUN_TIME)
message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME})
set(DLL_NAMES "opencv" "halcon" "Myalgo" "myTools" )
set(DLL_NAMES "opencv" "halcon" "halconAlgo" "myTools" )
foreach(child ${DLL_NAMES})
LIST(APPEND ENV_INCLUDE ${${child}_include})
LIST(APPEND ENV_LIB ${${child}_lib})
@@ -4,7 +4,7 @@
#include <QtConcurrent/QtConcurrent>
#include <qfuture.h>
#include <QTextCodec>
#include "Myalgo.h"
#include <algo.h>
#include <corecrt_wstring.h>
#include <codecvt>
#include <myTools.h>
@@ -15,7 +15,7 @@ using namespace cv;
//原图class图保存文件夹
QString classImgSaveDir = "D:/601线/超声波预焊01机/极性检测CCD/class图/";
//结果保存文件夹
QString resImgSaveDir = "D:\\601线\\超声波超声波预焊01机\\极性检测CCD\\结果图\\";
QString resImgSaveDir = "D:/601线/超声波超声波预焊01机/极性检测CCD/结果图/";
//切图的class的width,根据项目实际设置!
int sizeW = 150;
@@ -87,7 +87,16 @@ int algoResult;
}
return text;
}
QString getOriSaveFromat()
{
return oriImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//"
+ "ORI_" + cameraKey_index + "_" + QString::fromStdString(getCurrentTime()) + ".bmp";
}
QString getResSaveFromat()
{
return resImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//"
+ "RES_" + cameraKey_index + "_" + QString::fromStdString(getCurrentTime()) + ".png";
}
// 缺陷信息结构体
typedef struct {
@@ -586,8 +595,7 @@ bool Hd_AI_algo_jixing1::writeData(std::vector<cv::Mat>& vec_mat, QByteArray &da
createDirectoryIfNotExists(oriImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//");
addImgToSaveStruct(HikMat[0], "0", oriImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//"
"ORI" +cameraKey_index +QString::fromStdString(getCurrentTime())+".bmp");//保存原图
addImgToSaveStruct(HikMat[0], "0", getOriSaveFromat());//保存原图
//if (myallNum[index] == 1)
//{
@@ -862,8 +870,7 @@ bool Hd_AI_algo_jixing1::AIdetect(cv::Mat img2D, QString mysaveKey, QString myDi
if (resMat.size() > 0)
{
createDirectoryIfNotExists(oriImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//");
addImgToSaveStruct(HikMat[0], "0", resImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//"
+ "RES" + cameraKey_index + QString::fromStdString(getCurrentTime()) + ".png");//保存原图
addImgToSaveStruct(resMat[0], "0", getResSaveFromat());//保存原图
}
detect_mutex->unlock();
File diff suppressed because it is too large Load Diff
@@ -1,119 +0,0 @@
#ifndef Hd_AI_algo_jixing1_H
#define Hd_AI_algo_jixing1_H
#include <assert.h>
#include <atlstr.h>
#include <chrono>
#include <QtCore/qglobal.h>
#include <QByteArray>
#include <iostream>
#include <QDebug>
#include <qqueue.h>
#include <opencv2/imgproc.hpp>
#include <string.h>
#include <fstream>
#include <string>
#include <ctime>
#include <halconcpp/HalconCpp.h>
#include <opencv2/opencv.hpp>
#include "imgproc/imgproc_c.h"
#include "base.h"
#pragma execution_character_set("utf-8")
//保存图片的结构体
struct saveImgStruct;
//{
// cv::Mat out_Mat;
// std::string saveKey; //关键字,用于LOG日志
// std::string savePath; //保存路径
//};
//初始化流程(一次):Hd_AI_algo_jixing1,initParas
//运行流程:writeData主线程把数据传过来,run,readData此线程把数据传主线程
class Hd_AI_algo_jixing1 :public Base
{
Q_OBJECT
public:
Hd_AI_algo_jixing1();
virtual ~Hd_AI_algo_jixing1();
//从类中读数据到实例对象
bool readData(std::vector<cv::Mat>&,QByteArray&);
//实例对象把数据写入到类
bool writeData(std::vector<cv::Mat>&, QByteArray&);
bool initParas(QByteArray&);
//运行(Logic_taskthread.cpp)
bool run();
//线程状态
bool checkStatus();// { return true; };
bool encodeResultValue(QVector<std::string> append_value,QByteArray &resultByte);
bool decodeAiValue(QByteArray byte,QVector<QByteArray> &vec_ret);
//---------检测流程,根据实际项目修改---------
bool AIdetect(cv::Mat img2D, QString saveKey, QString Dir2D, QString SN, QString DataTime);
private:
int allNum = 0;
int StationNo=0;
int img2D = 2;
bool moduleStatus = true;
//输入图片队列
QQueue<cv::Mat> HikMat;
//输入关键字队列
QString saveKey="saveKey";
//结果路径文件夹队列
QString Dir2D="Dir2D";
//产品SN队列
QString SN="SN";
//产品时间戳队列
QString DateTime1="DateTime1";
int paramNum;
//是否使用线程检测方式
bool ifThreadRunDetect = false;
//检测结果图
std::vector<cv::Mat> resMat;
//检测结果
bool resIfNg = false;
QQueue<QByteArray> resByte;
//检测线程
void detectThread();
//存图线程
void saveImgThread();
//保存图片队列
QQueue<saveImgStruct> saveStruct;
//判断文件夹是否存在,不存在则创建
void isDirExist(QString fullDirName);
//存图加入队列
void addImgToSaveStruct(cv::Mat img2D, QString saveKey, QString savePath);
};
extern "C"
{
Q_DECL_EXPORT Hd_AI_algo_jixing1 * create();
Q_DECL_EXPORT void destory(Hd_AI_algo_jixing1 * ptr);
}
//保存图片的结构体
struct saveImgStruct
{
cv::Mat out_Mat;
std::string saveKey; //关键字,用于LOG日志
std::string savePath; //保存路径
};
#endif // Hd_AI_927_2D_module_H
-69
View File
@@ -1,69 +0,0 @@
#ifndef __BASECLASS_H__
#define __BASECLASS_H__
#include <iostream>
#include <QObject>
#include <QByteArray>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include<QJsonDocument>
#include<QJsonObject>
#include<QJsonArray>
class Base :public QObject
{
Q_OBJECT
public:
bool init_flag; //是否初始化,false,true
bool status = true; //相机状态(判断相机是否断开连接)
std::string paras; //传输数据
std::vector<cv::Mat> m_mat; //传输图片
std::string moduleName; //模块名称
public:
Base(){}
virtual ~Base(){}
virtual bool readData(std::vector<cv::Mat>&,QByteArray&){return true;}
virtual bool writeData(std::vector<cv::Mat>&,QByteArray&){return true;}
virtual bool initParas(QByteArray&){return true;}
virtual bool run() {return true;}
virtual bool checkStatus() { return true; }
//signals:
//QByteArrayList,根据实际项目进行解析;因不确定每个参数的长度,固用队列的方式。每个QByteArray表示一个值,使用时先转换为QString
//参数,例:返回结果图;相机关键字(SN或userID)+保存路径+缺陷信息列表(缺陷名称,缺陷位置int(x,y,w,h),画框颜色Scalar(a,b,c),缺陷面积double)
//void sendResultData(cv::Mat resMat, QJsonObject resQbj);
};
/*
//QJsonObject 转QByteArray
{
QJsonDocument document;
QJsonObject obj;
obj.insert(password, "pwd");
obj.insert(userName, "usr");
document.setObject(obj);
QByteArray abyte = document.toJson(QJsonDocument::Compact);
}
//QByteArray转QJsonObject
{
QByteArray ba = reply->readAll();
QJsonDocument doc = QJsonDocument::fromJson(ba);
QJsonObject obj = doc.object();
}
*/
/*
//从类中读数据到实例对象
virtual bool readData(std::vector<cv::Mat>&,QByteArray&){return true;}
*/
#endif
@@ -3,7 +3,7 @@ get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME)
string(TIMESTAMP RUN_TIME)
message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME})
set(DLL_NAMES "opencv" "halcon" "Myalgo""myTools" )
set(DLL_NAMES "mvs" "opencv")
foreach(child ${DLL_NAMES})
LIST(APPEND ENV_INCLUDE ${${child}_include})
LIST(APPEND ENV_LIB ${${child}_lib})
@@ -0,0 +1,722 @@
#include "Hd_CameraModule_HIK_soft.h"
using namespace std;
int firstExposureTime = 3000;
int secondExposureTime = 3000;
std::mutex triggerLock;
#include <QThread>
#include <QQueue>
#include <QMutex>
#include <QTextCodec>
QByteArray mv_Status = "connected";//0106 新增相机断联报警
//cv::Mat srcImage;
int index = -1; //相机序号
void* handle; //相机指针
string Username = "";
bool m_flag = false;
MV_CC_DEVICE_INFO_LIST m_stDevList;//相机设备
bool moduleStatus = true;
QQueue<cv::Mat> queuepic;
cv::Mat matList[1000] = { cv::Mat() };
//data == "rest_newProductIn"时要结束run;机台报警,取图超时,复位后重新拍的情况。
bool ifBreak = false;
//ifRunning减少ifBreak的判断;"rest_newProductIn"时,Logic_camera_thread框架会结束未处理完的相相机取图
bool ifRunning = false;
bool ifChangeExpourseAndGain = true;
MV_CAM_TRIGGER_SOURCE initTriggerSource = MV_TRIGGER_SOURCE_SOFTWARE;
MV_CAM_TRIGGER_SOURCE currentTriggerSource = MV_TRIGGER_SOURCE_SOFTWARE;
QString byteArrayToUnicode(const QByteArray array) {
// state用于保存转换状态,它的成员invalidChars,可用来判断是否转换成功
// 如果转换成功,则值为0,如果值大于0,则说明转换失败
QTextCodec::ConverterState state;
// 先尝试使用utf-8的方式把QByteArray转换成QString
QString text = QTextCodec::codecForName("UTF-8")->toUnicode(array.constData(), array.size(), &state);
// 如果转换时无效字符数量大于0,说明编码格式不对
if (state.invalidChars > 0)
{
// 再尝试使用GBK的方式进行转换,一般就能转换正确(当然也可能是其它格式,但比较少见了)
text = QTextCodec::codecForName("GBK")->toUnicode(array);
}
return text;
}
#pragma execution_character_set("utf-8")
QMutex* n_mutex;// = new QMutex();
//是否为标准通信流程:
//标准通信流程,run函数设置曝光/增益;非标准通信流程(简单通信流程),回调函数设置曝光/增益
bool ifStandard = false;
//相机取图超时时间
int getImageTimeOut = 1000;
//总取图数
int imgIndex = 0;
//曝光值列表
QQueue<float> expourseTimeList;
//增益列表
QQueue<float> gainList;
//0106 断线重连
void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser);
void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0);
bool IsColor(MvGvspPixelType enType)
{
switch (enType)
{
case PixelType_Gvsp_RGB8_Packed:
case PixelType_Gvsp_YUV422_Packed:
case PixelType_Gvsp_YUV422_YUYV_Packed:
case PixelType_Gvsp_BayerGR8:
case PixelType_Gvsp_BayerRG8:
case PixelType_Gvsp_BayerGB8:
case PixelType_Gvsp_BayerBG8:
case PixelType_Gvsp_BayerGB10:
case PixelType_Gvsp_BayerGB10_Packed:
case PixelType_Gvsp_BayerBG10:
case PixelType_Gvsp_BayerBG10_Packed:
case PixelType_Gvsp_BayerRG10:
case PixelType_Gvsp_BayerRG10_Packed:
case PixelType_Gvsp_BayerGR10:
case PixelType_Gvsp_BayerGR10_Packed:
case PixelType_Gvsp_BayerGB12:
case PixelType_Gvsp_BayerGB12_Packed:
case PixelType_Gvsp_BayerBG12:
case PixelType_Gvsp_BayerBG12_Packed:
case PixelType_Gvsp_BayerRG12:
case PixelType_Gvsp_BayerRG12_Packed:
case PixelType_Gvsp_BayerGR12:
case PixelType_Gvsp_BayerGR12_Packed:
return true;
default:
return false;
}
}
//搜索所有设备
int SearchDevice()
{
memset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));
// ch:枚举子网内所有设备 | en:Enumerate all devices within subnet
int nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE || MV_USB_DEVICE, &m_stDevList);
for (int i = 0; i < m_stDevList.nDeviceNum; i++)
{
//SN
unsigned char* name = m_stDevList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.chSerialNumber;
//userID
//unsigned char* name=m_stDevList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.chUserDefinedName;
string userName = static_cast<string>((LPCSTR)name);
if (Username == userName)
{
index = i;
break;
}
}
if (MV_OK != nRet)
{
return 0;
}
return -1;
}
bool connctDevice()
{
index = -1;
SearchDevice();
if (index == -1)
{
//未匹配到相机
qDebug() << "[Waring] " << "Hd_CameraModule_HIK_soft not match --CameraName:" << QString::fromStdString(Username);
return false;
}
unsigned char* name = m_stDevList.pDeviceInfo[index]->SpecialInfo.stGigEInfo.chUserDefinedName;
string userName = static_cast<string>((LPCSTR)name);
qDebug() << "[INFO] " << " start" << "--UserName:" << QString::fromStdString(userName);
if (handle != NULL)
{
MV_CC_StopGrabbing(handle);
MV_CC_CloseDevice(handle);
MV_CC_DestroyHandle(handle);
}
//打开相机
MV_CC_CreateHandle(&handle, m_stDevList.pDeviceInfo[index]);
int nRet = MV_CC_OpenDevice(handle);
////触发模式
MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_SOFTWARE);
MV_CC_SetEnumValue(handle, "TriggerMode", MV_TRIGGER_MODE_ON);
// //加载用户集,相机设置应当UserSet1
nRet = MV_CC_SetEnumValueByString(handle, "UserSetSelector", "UserSet1");
if (MV_OK != nRet)
{
qDebug() << "Set UserSetSelector fail! nRet " << nRet;
}
// ch:注册抓图回调 | en:Register image callback
MV_CC_SetIntValueEx(handle, "GevHeartbeatTimeout", 3000);//心跳日志
nRet = MV_CC_RegisterImageCallBackEx(handle, ImageCallBackEx, handle);//注册回调
if (MV_OK != nRet)
return false;
nRet = MV_CC_RegisterExceptionCallBack(handle, ReconnectDevice, NULL);//断线重连
if (MV_OK != nRet)
return false;
MV_CC_StartGrabbing(handle);
return true;
}
//0106 断线重连
void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser)
{
mv_Status = "disconnect";
qDebug() << "[Error] " << " MV camera disconnects!";
moduleStatus = false;
if (nMsgType == MV_EXCEPTION_DEV_DISCONNECT)
{
//断开连接
MV_CC_CloseDevice(handle);
int nRet = MV_CC_DestroyHandle(handle);
handle = nullptr;
BOOL bConnected = FALSE;
while (1)
{
Sleep(100);
if (connctDevice() == true)
{
qWarning() << "[Hd_CameraModule_HIK_soft] " << " Hd_CameraModule_HIK_soft create success again! ";
moduleStatus = true;
break;
}
}
}
}
void _stdcall ExceptionCB(unsigned int nMesgType, void* pUser) {
mv_Status = "disconnect";
qDebug() << "[Error] " << " MV camera disconnects!";
moduleStatus = false;
}
int RGB2BGR(unsigned char* pRgbData, unsigned int nWidth, unsigned int nHeight)
{
if (NULL == pRgbData)
{
return MV_E_PARAMETER;
}
for (unsigned int j = 0; j < nHeight; j++)
{
for (unsigned int i = 0; i < nWidth; i++)
{
unsigned char red = pRgbData[j * (nWidth * 3) + i * 3];
pRgbData[j * (nWidth * 3) + i * 3] = pRgbData[j * (nWidth * 3) + i * 3 + 2];
pRgbData[j * (nWidth * 3) + i * 3 + 2] = red;
}
}
return MV_OK;
}
Hd_CameraModule_HIK_soft* create()
{
qDebug() << "[INFO] " << "Hd_CameraModule_HIK_soft create success!" ;
return new Hd_CameraModule_HIK_soft;
}
void destory(Hd_CameraModule_HIK_soft * ptr)
{
if(ptr)
{
delete ptr;
ptr = nullptr;
}
qDebug() << "[INFO] " << "Hd_CameraModule_HIK_soft destory success!";
}
//回调函数;
//经测试,相机像素格式Mono8、RGB8是可以正常转换的,YUV422还需要优化;RGB8格式比YUV422帧率低;BGR格式会导致异色问题
void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0)
{
SetExposureTime(secondExposureTime);
triggerLock.unlock();
n_mutex->lock();
double time_Start = (double)clock();
int frameNum = 0;
cv::Mat srcImage = cv::Mat();
if (pFrameInfo0)
{
//获取的是单通道灰度图
if (pFrameInfo0->enPixelType == PixelType_Gvsp_Mono8)//获取当前采集到的图像格式
{
srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC1, pData0);
}
//获取的是RGB8图
else if (pFrameInfo0->enPixelType == PixelType_Gvsp_BGR8_Packed)
{
srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, pData0);
}
////获取的是RGB8图
//else if (pFrameInfo0->enPixelType == PixelType_Gvsp_RGB8_Packed)
//{
// cv::Mat dst = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, pData0);
// //cv::cvtColor(matimage, matimage, cv::COLOR_RGB2BGR);
// srcImage = cv::Mat::zeros(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3);
// std::vector<cv::Mat> channels;
// cv::split(dst, channels);//分割matimage的通道
// std::vector<cv::Mat> dstchannels;
// for (int i = 2; i >= 0; i--)
// {
// dstchannels.push_back(channels[i]);
// }
// merge(dstchannels, srcImage);
//}
else if (IsColor(pFrameInfo0->enPixelType)) //其它格式彩色图
{
MvGvspPixelType enDstPixelType = PixelType_Gvsp_Undefined;
enDstPixelType = PixelType_Gvsp_BGR8_Packed;
unsigned char* pConvertData = NULL;
pConvertData = (unsigned char*)malloc(pFrameInfo0->nWidth * pFrameInfo0->nHeight * 3);
if (NULL == pConvertData)
{
printf("malloc pConvertData fail!\n");
}
else
{
unsigned int nConvertDataSize = 0;
nConvertDataSize = pFrameInfo0->nWidth * pFrameInfo0->nHeight * 3;
// ch:像素格式转换 | en:Convert pixel format
MV_CC_PIXEL_CONVERT_PARAM stConvertParam = { 0 };
frameNum = pFrameInfo0->nFrameNum; //ch:帧号 | en:frame number
stConvertParam.nWidth = pFrameInfo0->nWidth; //ch:图像宽 | en:image width
stConvertParam.nHeight = pFrameInfo0->nHeight; //ch:图像高 | en:image height
stConvertParam.pSrcData = pData0; //ch:输入数据缓存 | en:input data buffer
stConvertParam.nSrcDataLen = pFrameInfo0->nFrameLen; //ch:输入数据大小 | en:input data size
stConvertParam.enSrcPixelType = pFrameInfo0->enPixelType; //ch:输入像素格式 | en:input pixel format
stConvertParam.enDstPixelType = enDstPixelType; //ch:输出像素格式 | en:output pixel format
stConvertParam.pDstBuffer = pConvertData; //ch:输出数据缓存 | en:output data buffer
stConvertParam.nDstBufferSize = nConvertDataSize; //ch:输出缓存大小 | en:output buffer size
int nRet = MV_CC_ConvertPixelType(handle, &stConvertParam);
Mat mysrcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, stConvertParam.pDstBuffer);
mysrcImage.copyTo(srcImage);
free(pConvertData);
pConvertData = NULL;
stConvertParam = { 0 };
}
}
}
if(srcImage.empty())
{
srcImage = cv::Mat(5, 5, CV_8UC1).setTo(0);
}
m_flag = true;
queuepic.push_back(srcImage.clone());
n_mutex->unlock();
pData0 = { 0 };
double time_End = (double)clock();
qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getImg,Time:" << (time_End - time_Start) << "ms"
<< "--CameraName:" << QString::fromStdString(Username) << " imgIndex:" << imgIndex << "nFrameNum : " << frameNum;
/*QString savePath = "../runtime/Bin_DEVICE/testImg/camera_" + QString::number(imgIndex + 1)+".png";
cv::Mat resizeS;
cv::resize(srcImage, resizeS, cv::Size(), 0.1, 0.1);
cv::imwrite(savePath.toStdString(), resizeS);*/
}
void SetExposureTime(float exposureValue)
{
qDebug() << "[INFO] " << "exposureValue:" << exposureValue;
MV_CC_SetEnumValue(handle, "ExposureAuto", MV_EXPOSURE_AUTO_MODE_OFF);
MV_CC_SetFloatValue(handle, "ExposureTime", exposureValue);
}
void SetGain(float GainValue)
{
qDebug() << "[INFO] " << "GainValue:" << GainValue;
MV_CC_SetEnumValue(handle, "GainAuto", 0);
MV_CC_SetFloatValue(handle, "Gain", GainValue);
}
Hd_CameraModule_HIK_soft::Hd_CameraModule_HIK_soft()
{
n_mutex = new QMutex();
m_thread = new MyThread;
}
//关闭设备
void CloseDevice()
{
MV_CC_StopGrabbing(handle);
MV_CC_CloseDevice(handle);
MV_CC_DestroyHandle(handle);
handle = nullptr; //此处注释掉的话,软件断开再连接,回调函数不出图
}
Hd_CameraModule_HIK_soft::~Hd_CameraModule_HIK_soft()
{
m_flag = true;
Sleep(10);
CloseDevice();
if (n_mutex)
{
delete n_mutex;
n_mutex = nullptr;
}
if(m_thread)
{
m_thread->exit();
m_thread->wait(1);
delete m_thread;
m_thread = nullptr;
}
qDebug() << "[INFO] " << " delete success!";
}
//从类中读数据到实例对象
bool Hd_CameraModule_HIK_soft::readData(std::vector<cv::Mat> &mat,QByteArray &data)
{
if (queuepic.isEmpty())
{
qCritical() << __FUNCTION__ << " line:" <<__LINE__ << " srcImage is null";
return false;
}
n_mutex->lock();
cv::Mat img = cv::Mat();
queuepic.dequeue().copyTo(img);
mat.push_back(img.clone());
n_mutex->unlock();
QString qimgIndex = "imgIndex_" + QString::number(imgIndex-1)+"_中文测试";
data = qimgIndex.toLocal8Bit();
qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg readData--CameraName:" << QString::fromStdString(Username) << "--imgIndex : " << imgIndex-1;
return true;
}
//实例对象把数据写入到类
bool Hd_CameraModule_HIK_soft::writeData(std::vector<cv::Mat> &mat,QByteArray &data)
{
//2024.02.18更新,相机对应的读SN信号时,表示新产品进入,设置初始值
if (data == "rest_newProductIn")
{
//根据实际项目,设置初始值:曝光、增益,ROI区域等
{
if (expourseTimeList.size() > 0)
SetExposureTime(expourseTimeList[0]);
if (gainList.size() > 0)
SetGain(gainList[0]);
}
if (queuepic.size() > 0)
{
n_mutex->lock();
queuepic.clear();
n_mutex->unlock();
std::cout << "rest_newProductIn , queuePic.size() > 0 ,signal maybe too fast " << Username << std::endl;
qWarning() << __FUNCTION__ << " line: " << __LINE__ << "rest_newProductIn , queuePic.size() > 0 ,signal maybe too fast " << QString::fromStdString(Username);
}
if (ifRunning == true)
{
ifBreak = true;
Sleep(10);
}
imgIndex = 0;
return true;
}
else
{
m_flag = false;
//expourseTimeList.clear();
//gainList.clear();
}
if (data == "ifChangeExpourseAndGain_false")
ifChangeExpourseAndGain = false;
else
ifChangeExpourseAndGain = true;
if (data.contains("SetExposureTime_"))
{
QByteArrayList dataList = data.split('#');
for (int i = 0; i < dataList.size(); i++)
{
if (dataList[i].contains("SetExposureTime_"))
{
int value = byteArrayToUnicode(dataList[i]).split("SetExposureTime_")[1].toInt();
SetExposureTime(value);
}
if (dataList[i].contains("SetGain_"))
{
double value = byteArrayToUnicode(dataList[i]).split("SetGain_")[1].toInt();
SetGain(value);
}
if (dataList[i].contains("TriggerMode_"))
{
QString value = byteArrayToUnicode(dataList[i]).split("TriggerMode_")[1];
if (value == "软触发")
////触发模式
{
MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_SOFTWARE);
currentTriggerSource = MV_TRIGGER_SOURCE_SOFTWARE;
}
else
{
MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_LINE0);
currentTriggerSource = MV_TRIGGER_SOURCE_LINE0;
}
}
}
}
//调试模式下,data==ifChangeExpourseAndGain_false;非调试模式运行时,data不包含SetExposureTime_
else if (data != "ifChangeExpourseAndGain_false" && initTriggerSource != currentTriggerSource)
{
MV_CC_SetEnumValue(handle, "TriggerSource", initTriggerSource);
currentTriggerSource = initTriggerSource;
}
/*data.append("SetExposureTime_" + ui.spinBox->text() + "#");
data.append("SetGain_" + ui.doubleSpinBox->text() + "#");
data.append("TriggerMode_" + ui.comboBox_triggerMode->currentText());*/
qDebug() << "Hd_CameraModule_HIK_soft::writeData::" << data;
m_flag = false;
//Username = data.toStdString();
return true;
}
//传入initParas函数,格式为:相机key+参数名1#参数值1#参数值2+参数名2#参数值1...
bool Hd_CameraModule_HIK_soft::initParas(QByteArray& initData)
{
QByteArrayList valueList = initData.split('+');
Username = valueList[0];
imgIndex = 0;
expourseTimeList.clear();
gainList.clear();
bool ifOk = true;
if (handle == NULL)
ifOk = connctDevice();
if (ifOk == false)
return false;
if (valueList.size() > 1)
for (int i = 1; i < valueList.size(); i++)
{
QString valuei = byteArrayToUnicode(valueList[i]);
//valuei.prepend(valueList[i]);
if (valuei.contains("expourseTime"))
{
QStringList expourseTimeL = valuei.split('#');
if (expourseTimeL.size() > 1)
for (int j = 1; j < expourseTimeL.size(); j++)
expourseTimeList.enqueue(expourseTimeL[j].toFloat());
}
if (valuei.contains("gain"))
{
QStringList gainL = valuei.split('#');
if (gainL.size() > 1)
for (int j = 1; j < gainL.size(); j++)
gainList.enqueue(gainL[j].toFloat());
}
if (valuei.contains("是否为标准通信流程"))
{
if (valuei.contains("true"))
ifStandard = true;
}
if (valuei.contains("取图超时"))
{
QStringList gainL = valuei.split('#');
if (gainL.size() > 1)
getImageTimeOut = gainL[1].toInt();
if (getImageTimeOut < 50)
getImageTimeOut = 1000;
}
if (valuei.contains("OffsetX"))
{
QStringList valueL = valuei.split('#');
if (valueL.size() > 1)
if(valueL[1].toInt()>=0)
MV_CC_SetIntValue(handle, "OffsetX", valueL[1].toInt());
}
if (valuei.contains("OffsetY"))
{
QStringList valueL = valuei.split('#');
if (valueL.size() > 1)
if (valueL[1].toInt() >= 0)
MV_CC_SetIntValue(handle, "OffsetY", valueL[1].toInt());
}
if (valuei.contains("Width"))
{
QStringList valueL = valuei.split('#');
if (valueL.size() > 1)
if (valueL[1].toInt() >= 0)
MV_CC_SetIntValue(handle, "Width", valueL[1].toInt());
}
if (valuei.contains("Height"))
{
QStringList valueL = valuei.split('#');
if (valueL.size() > 1)
if (valueL[1].toInt() >= 0)
MV_CC_SetIntValue(handle, "Height", valueL[1].toInt());
}
if (valuei.contains("触发方式"))
{
QStringList valueL = valuei.split('#');
if (valueL.size() > 1)
if (valueL[1].toInt() >= 0)
if (valueL[1] == "软触发")
{
MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_SOFTWARE);
currentTriggerSource = MV_TRIGGER_SOURCE_SOFTWARE;
initTriggerSource = MV_TRIGGER_SOURCE_SOFTWARE;
}
else
{
MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_LINE0);
currentTriggerSource = MV_TRIGGER_SOURCE_LINE0;
initTriggerSource = MV_TRIGGER_SOURCE_LINE0;
}
}
}
if (ifOk == true)
{
if (expourseTimeList.size() > 0)
SetExposureTime(expourseTimeList[0]);
if (gainList.size() > 0)
SetGain(gainList[0]);
}
imgIndex = 0;
if (ifOk == true)
{
MVCC_FLOATVALUE mf = { 0 };
MV_CC_GetFloatValue(handle, "ExposureTime", &mf);
std::cout << "ExposureTime::" << mf.fCurValue << std::endl;
mf = { 0 };
MV_CC_GetFloatValue(handle, "Gain", &mf);
std::cout << "Gain::" << mf.fCurValue << std::endl;
MVCC_INTVALUE mI = { 0 };
MV_CC_GetIntValue(handle, "OffsetX", &mI);
std::cout << "OffsetX::" << mI.nCurValue << std::endl;
mI = { 0 };
MV_CC_GetIntValue(handle, "OffsetY", &mI);
std::cout << "OffsetY::" << mI.nCurValue << std::endl;
mI = { 0 };
MV_CC_GetIntValue(handle, "Width", &mI);
std::cout << "Width::" << mI.nCurValue << std::endl;
mI = { 0 };
MV_CC_GetIntValue(handle, "Height", &mI);
std::cout << "Height::" << mI.nCurValue << std::endl;
MVCC_ENUMVALUE me = { 0 };
MV_CC_GetEnumValue(handle,"BalanceWhiteAuto",&me); //自动白平衡
std::cout << "BalanceWhiteAuto::" << me.nCurValue << std::endl;
}
return ifOk;
}
bool Hd_CameraModule_HIK_soft::run()
{
if (imgIndex == expourseTimeList.size())
imgIndex = 0;
//Sleep(100);
qDebug() << "[INFO] " << " run start" <<QString::fromStdString(Username);
bool result = false;
ifRunning = true;
ifBreak = false;
//srcImage.release();
try
{
//n_mutex->lock();
m_flag = false;
//Sleep(2);
//n_mutex->unlock();
//m_thread->run(); //start()线程运行,频率高时有低概率无响应;
if (currentTriggerSource == MV_TRIGGER_SOURCE_SOFTWARE)
{
MV_CC_SetCommandValue(handle, "TriggerSoftware");
qDebug() << "[INFO] " << "TriggerSoftware";
}
else
qDebug() << "[INFO] " << "TriggerHardware";
//MV_CC_SetCommandValue(handle, "TriggerSoftware");
//Sleep(15);
int mytime = 0;
qDebug() << "[INFO] " << " waite Img" << QString::fromStdString(Username);
while (true)
{
if (moduleStatus == false || mytime++ > getImageTimeOut || ifBreak == true )//|| m_flag==true)
{
result = false;
break;
}
n_mutex->lock();
if (queuepic.size() > 0)
{
n_mutex->unlock();
result = true;
break;
}
n_mutex->unlock();
Sleep(1);
}
Sleep(1);
//qDebug() << "[INFO] " << " expourseTimeList " << QString::fromStdString(Username);
//软触发,不考虑误触发、漏触发
if (ifChangeExpourseAndGain == true)
{
imgIndex++;
if (expourseTimeList.size() > 1 && expourseTimeList[imgIndex % expourseTimeList.size()] != expourseTimeList[(imgIndex - 1) % expourseTimeList.size()])
SetExposureTime(expourseTimeList[imgIndex % expourseTimeList.size()]);
//Sleep(1);
if (gainList.size() > 1 && gainList[imgIndex % gainList.size()] != gainList[(imgIndex - 1) % gainList.size()])
SetGain(gainList[imgIndex % gainList.size()]);
//Sleep(1);
}
if (result == false)
{
QString currPath = "../runtime/Bin_DEVICE/testImg/testImg_";
if (ifChangeExpourseAndGain == true)
currPath +=QString::number(imgIndex-1);
else
currPath += QString::number(imgIndex);
currPath += ".jpg";
cv::Mat readMat = cv::imread(currPath.toStdString());
queuepic.push_back(readMat);
qDebug() << "取图失败,读取图片:" << currPath;
result = true;
}
}
catch (QString ev)
{
qDebug() << "[Error] " << " ev:" << ev ;
}
qDebug() << "[INFO] " << __LINE__ << " run end" ;
return result;
}
//相机连接状态:正常连接或断开
bool Hd_CameraModule_HIK_soft::checkStatus()
{
//status = moduleStatus;
return moduleStatus;
}
void MyThread::run()
{
SetExposureTime(firstExposureTime);//第一次曝光数值
MV_CC_SetCommandValue(handle, "TriggerSoftware");
triggerLock.lock();
triggerLock.lock();
MV_CC_SetCommandValue(handle, "TriggerSoftware");
}
@@ -0,0 +1,59 @@
#ifndef Hd_CameraModule_HIK_soft_H
#define Hd_CameraModule_HIK_soft_H
#include <QtCore/qglobal.h>
#include<opencv2/opencv.hpp>
#include <MvCameraControl.h>
#include <opencv.hpp>
#include <QByteArray>
#include <QDebug>
#include<iostream>
#include <Windows.h>
#include <time.h>
#include <QScopedPointer>
#include <QThread>
#include "base.h"
using namespace cv;
#pragma execution_character_set("utf-8")
class MyThread;
class Hd_CameraModule_HIK_soft :public Base
{
public:
Hd_CameraModule_HIK_soft();
virtual ~Hd_CameraModule_HIK_soft();
//从类中读数据到实例对象
bool readData(std::vector<cv::Mat>& mat, QByteArray& data);
//实例对象把数据写入到类
bool writeData(std::vector<cv::Mat>& mat, QByteArray& data);
bool initParas(QByteArray&);
bool run();
bool checkStatus();
private:
MyThread *m_thread = nullptr;
};
class MyThread : public QThread
{
Q_OBJECT
public:
explicit MyThread(QObject *parent = nullptr):m_obj(parent){}
void run();
private:
QObject *m_obj;
signals:
};
extern "C"
{
Q_DECL_EXPORT Hd_CameraModule_HIK_soft * create();
Q_DECL_EXPORT void destory(Hd_CameraModule_HIK_soft * ptr);
}
#endif // Hd_CameraModule_HIK_soft_H
@@ -0,0 +1,33 @@
#ifndef __BASECLASS_H__
#define __BASECLASS_H__
#include <iostream>
#include <QObject>
#include <QByteArray>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
class Base :public QObject
{
Q_OBJECT
public:
bool init_flag; //是否初始化,false,true
bool status = true; //相机状态(判断相机是否断开连接)
std::string paras; //传输数据
std::vector<cv::Mat> m_mat; //传输图片
std::string moduleName; //模块名称
public:
Base(){}
virtual ~Base(){}
virtual bool readData(std::vector<cv::Mat>&,QByteArray&){return true;}
virtual bool writeData(std::vector<cv::Mat>&,QByteArray&){return true;}
virtual bool initParas(QByteArray&){return true;}
virtual bool run() {return true;}
virtual bool checkStatus() { return true; }
signals:
void trigged(bool);
};
#endif
+1 -1
View File
@@ -127,7 +127,7 @@ if(ON)
else()
SET( ${child}_target_link "opencv_world410" )
endif()
elseif(${child} MATCHES "Myalgo")
elseif(${child} MATCHES "halconAlgo")
SET( ${child}_target_link "Inspection" )
elseif(${child} MATCHES "basler")
SET( ${child}_target_link
BIN
View File
Binary file not shown.
-110
View File
@@ -1,110 +0,0 @@
#pragma once
#include<halconcpp/HalconCpp.h>
#include<halconcpp/HDevThread.h>
#include<Halcon.h>
//#include <opencv2/opencv.hpp>
//#include <opencv2/imgcodecs/imgcodecs.hpp>
using namespace HalconCpp;
#if 1 后端调用函数
/*
ho_Image:输入原图
hv_out_Value:输出检测结果 1为铝,2为铜
hv_Make:算法执行状态-1为算法NG,1为算法ok
极性检测函数
三协机台
*/
extern "C" __declspec(dllexport) void _stdcall _628_1_Polarity_detection(HObject ho_Image, HTuple* hv_out_Value, HTuple* hv_Make);
/*
* ho_Image:输入图片(原图)
* hv_model:赋值为1时是基准标定模式,0为正常检测模式
* hv_BenchmarkFile:基准标定文件的路径
* hv_NinePointDocument:九点文件的路径
*hv_CameraNumber:上钉相机编号
* hv_out_Cirle:输出放钉孔的圆心x,圆心y,半径。数组形式
* hv_Make:输出-1为算法错误,输出1为算法正常执行,输出为2为基准标定成功
* hv_offset_x:x轴方向上相对于基准位置的偏差
* hv_offset_y:y轴方向上相对于基准位置的偏差
* 上钉引导函数
*/
extern "C" __declspec(dllexport) void _stdcall _628_SealingNails(HObject ho_Image, HTuple hv_model, HTuple hv_BenchmarkFile,
HTuple hv_NinePointDocument, HTuple hv_CameraNumber, HTuple* hv_out_Cirle, HTuple* hv_Make,
HTuple* hv_offset_x, HTuple* hv_offset_y);
/*
* ho_Image:输入图片(原图)
* hv_model:赋值为1时是基准标定模式,0为正常检测模式
* hv_BenchmarkFile:基准标定文件的路径
* hv_NinePointDocument:九点文件的路径
*hv_CameraNumber:预焊相机编号
* hv_out_Cirle:输出放钉孔的圆心x,圆心y,半径。数组形式
* hv_Make:输出-1为算法错误,输出1为算法正常执行,输出为2为基准标定成功
* hv_offset_x:x轴方向上相对于基准位置的偏差
* hv_offset_y:y轴方向上相对于基准位置的偏差
* hv_Text:输出报警信息包括(ok,无钉,翘钉,反钉)
* 预焊函数
*/
extern "C" __declspec(dllexport) void _stdcall _628_yuhan(HObject ho_Image, HTuple hv_Model, HTuple hv_BenchmarkFile, HTuple hv_NinePointDocument,
HTuple hv_CameraNumber, HTuple* hv_out_Cirle, HTuple* hv_Make, HTuple* hv_offset_x,
HTuple* hv_offset_y, HTuple* hv_Text);
/*
* ho_Image:输入图片(原图)
* hv_model:赋值为1时是基准标定模式,0为正常检测模式
* hv_BenchmarkFile:基准标定文件的路径
* hv_NinePointDocument:九点文件的路径
*hv_CameraNumber:预焊相机编号
* hv_out_Cirle:输出放钉孔的圆心x,圆心y,半径。数组形式
* hv_Make:输出-1为算法错误,输出1为算法正常执行,输出为2为基准标定成功
* hv_offset_x:x轴方向上相对于基准位置的偏差
* hv_offset_y:y轴方向上相对于基准位置的偏差
* 终焊函数
*/
extern "C" __declspec(dllexport) void _stdcall _628_FinalWelding(HObject ho_Image, HTuple hv_model, HTuple hv_BenchmarkFile,
HTuple hv_NinePointDocument, HTuple hv_CameraNumber, HTuple* hv_out_Cirle, HTuple* hv_Make,
HTuple* hv_offset_x, HTuple* hv_offset_y);
#endif
#if 1 halcon调用函数
void gen_arrow_contour_xld(HObject* ho_Arrow, HTuple hv_Row1, HTuple hv_Column1,
HTuple hv_Row2, HTuple hv_Column2, HTuple hv_HeadLength, HTuple hv_HeadWidth);
void Get_Rectangle2_Corner_new(HObject ho_Rectangle, HTuple* hv_out_Row, HTuple* hv_out_Col);
void pts_to_best_line(HObject* ho_Line, HTuple hv_Rows, HTuple hv_Cols, HTuple hv_ActiveNum,
HTuple* hv_Row1, HTuple* hv_Column1, HTuple* hv_Row2, HTuple* hv_Column2);
void rake(HObject ho_Image, HObject* ho_Regions, HTuple hv_Elements, HTuple hv_DetectHeight,
HTuple hv_DetectWidth, HTuple hv_Sigma, HTuple hv_Threshold, HTuple hv_Transition,
HTuple hv_Select, HTuple hv_Row1, HTuple hv_Column1, HTuple hv_Row2, HTuple hv_Column2,
HTuple* hv_ResultRow, HTuple* hv_ResultColumn);
void pts_to_best_circle(HObject* ho_Circle, HTuple hv_Rows, HTuple hv_Cols, HTuple hv_ArcType,
HTuple hv_ActiveNum, HTuple* hv_RowCenter, HTuple* hv_ColCenter, HTuple* hv_Radius,
HTuple* hv_StartPhi, HTuple* hv_EndPhi, HTuple* hv_PointOrder, HTuple* hv_ArcAngle);
void region_to_spoke(HObject ho_Region, HTuple hv_Offset, HTuple* hv_SpokeRows,
HTuple* hv_SpokeCols);
void spoke(HObject ho_Image, HObject* ho_Regions, HTuple hv_Elements, HTuple hv_DetectHeight,
HTuple hv_DetectWidth, HTuple hv_Sigma, HTuple hv_Threshold, HTuple hv_Transition,
HTuple hv_Select, HTuple hv_ROIRows, HTuple hv_ROICols, HTuple hv_Direct, HTuple* hv_ResultRow,
HTuple* hv_ResultColumn, HTuple* hv_ArcType);
void _628_PreWelded(HObject ho_Image, HTuple hv_model, HTuple hv_BenchmarkFile,
HTuple hv_NinePointDocument, HTuple hv_CameraNumber, HTuple* hv_out_Cirle, HTuple* hv_Make,
HTuple* hv_offset_x, HTuple* hv_offset_y);
#endif
BIN
View File
Binary file not shown.
Binary file not shown.
+272
View File
@@ -0,0 +1,272 @@
#pragma once
#include<halconcpp/HalconCpp.h>
#include<halconcpp/HDevThread.h>
#include<Halcon.h>
//#include <opencv2/opencv.hpp>
//#include <opencv2/imgcodecs/imgcodecs.hpp>
using namespace HalconCpp;
#if 1 后端调用函数
/*
ho_Image:输入原图
hv_out_Value:输出检测结果 1为铝,2为铜
hv_Make:算法执行状态-1为算法NG,1为算法ok
极性检测函数
预焊三协机台
*/
extern "C" __declspec(dllexport) void _stdcall _628_1_Polarity_detection(HObject ho_Image, HTuple* hv_out_Value, HTuple* hv_Make);
/*
* ho_Image:输入图片(原图)
* hv_NinePointDocument:九点文件的路径
* hv_SetNumber:设置胶钉的最小个数
* hv_Circle_Point:输出放钉孔的圆心x,圆心y,半径。数组形式
* hv_Make:输出-1为算法错误,输出1为算法正常执行
*hv_Out_Roboot1:吸嘴1-> 吸嘴编号,x绝对坐标,y绝对坐标
* hv_Out_Roboot2:吸嘴2->吸嘴编号,x绝对坐标,y绝对坐标
* hv_Out_Roboot3:吸嘴3->吸嘴编号,x绝对坐标,y绝对坐标
* 机器人引导函数
* 三协机台
*/
extern "C" __declspec(dllexport) void _stdcall _628_BootTheMachine(HObject ho_Image, HTuple hv_NinePointDocument, HTuple hv_SetNumber,
HTuple* hv_Circle_Point, HTuple* hv_Make, HTuple* hv_Out_Roboot1, HTuple* hv_Out_Roboot2,HTuple* hv_Out_Roboot3);
/*
*ho_Image:输入图片(原图)
* hv_Pix:像素精度
* hv_out_line:输出直线坐标
* hv_distance:输出测量值 ->高,宽。数组形式
* hv_Make:输出-1为算法错误,输出1为算法正常执行
* 铜极耳裁剪测量函数
* 三协预焊机台
*/
extern "C" __declspec(dllexport) void _stdcall cs_628_jier_T(HObject ho_Image, HTuple hv_Pix, HTuple* hv_out_line, HTuple* hv_out_Soldering_line,
HTuple* hv_distance, HTuple* hv_Make);
/*
* ho_Image:输入图片(原图)
* hv_model:赋值为1时是基准标定模式,0为正常检测模式
* hv_BenchmarkFile:基准标定文件的路径
* hv_NinePointDocument:九点文件的路径
*hv_CameraNumber:上钉相机编号
* hv_out_Cirle:输出放钉孔的圆心x,圆心y,半径。数组形式
* hv_Make:输出-1为算法错误,输出1为算法正常执行,输出为2为基准标定成功
* hv_offset_x:x轴方向上相对于基准位置的偏差
* hv_offset_y:y轴方向上相对于基准位置的偏差
* 打钉钉引导函数
* 三协的机台
*/
extern "C" __declspec(dllexport) void _stdcall _628_NailingPosition(HObject ho_Image, HTuple hv_model, HTuple hv_BenchmarkFile,
HTuple hv_NinePointDocument, HTuple hv_CameraNumber, HTuple* hv_out_Cirle, HTuple* hv_Make,
HTuple* hv_offset_x, HTuple* hv_offset_y);
/*
ho_Image:输入原图
hv_out_Value:输出检测结果[1,1] .1为铝,[2,2] 2为铜
hv_Make:算法执行状态-1为算法NG,1为算法ok
极性检测函数
终焊三协机台
*/
extern "C" __declspec(dllexport) void _stdcall _628_2_Polarity_detection(HObject ho_Image, HTuple* hv_out_Value, HTuple* hv_Make);
/*
* ho_Image_L:输入图片铝
* ho_Image_T:输入图片铜
* hv_Pix_T:铜极像素精度
* hv_Pix_L:铝极像素精度
* hv_Out_Vale_L:输出铝极测量值包括两个值
* hv_Out_Line_L:输出铝极划线坐标
* hv_Out_Vale_T:输出铝极测量值包括两个值
* hv_Out_Line_T:输出铜极极划线坐标
* hv_Out_extremum_Value:输出两极之间的距离
* hv_Make:输出-1为算法错误,输出1为算法正常执行
* 预焊焊前测量函数
* 三协的机台
*/
extern "C" __declspec(dllexport) void _stdcall _628_2_BeforeWelding_Distnce(HObject ho_Image_L, HObject ho_Image_T, HTuple hv_Pix_T,
HTuple hv_Pix_L, HTuple* hv_Out_Vale_L, HTuple* hv_Out_Line_L, HTuple* hv_Out_Vale_T,
HTuple* hv_Out_Line_T, HTuple* hv_Out_extremum_Value, HTuple* hv_Makes);
/*
* ho_Image :输入图片铝极
* ho_ImageSeg :输入图片seg图(二值图)
* hv_Pix : 铝极像素精度
* hv_Out_TopLeft_Line : 左上输出线的端点坐标
* hv_Out_TopLeft_Value :左上输出的测量值(2个值)
* hv_Out_TopRight_Line :右上输出线的端点坐标
* hv_Out_TopRight_Value :右上输出的测量值(2个值)
* hv_Out_BottomLeft_Line :左下输出线的端点坐标
* hv_Out_BottomLeft_Value :左下输出的测量值(2个值)
** hv_Out_BottomRight_Line :右下输出线的端点坐标
* hv_Out_BottomRight_Value :右下输出的测量值(2个值)
* hv_Make:输出-1为算法错误,输出1为算法正常执行
* 预焊焊后测量铝极函数
* 三协的机台
*/
extern "C" __declspec(dllexport) void _stdcall _628_AfterWelding_Distance_L(HObject ho_Image, HObject ho_ImageSeg, HTuple hv_Pix,
HTuple* hv_Out_TopLeft_Line, HTuple* hv_Out_TopLeft_Value, HTuple* hv_Out_TopRight_Line,
HTuple* hv_Out_TopRight_Value, HTuple* hv_Out_BottomLeft_Line, HTuple* hv_Out_BottomLeft_Value,
HTuple* hv_Out_BottomRight_Line, HTuple* hv_Out_BottomRight_Value, HTuple* hv_Make);
/*
* ho_Image :输入图片铝极
* ho_ImageSeg :输入图片seg图(二值图)
* hv_Pix : 铝极像素精度
* hv_Out_TopLeft_Line : 左上输出线的端点坐标
* hv_Out_TopLeft_Value :左上输出的测量值(2个值)
* hv_Out_TopRight_Line :右上输出线的端点坐标
* hv_Out_TopRight_Value :右上输出的测量值(2个值)
* hv_Out_BottomLeft_Line :左下输出线的端点坐标
* hv_Out_BottomLeft_Value :左下输出的测量值(2个值)
** hv_Out_BottomRight_Line :右下输出线的端点坐标
* hv_Out_BottomRight_Value :右下输出的测量值(2个值)
* hv_Make:输出-1为算法错误,输出1为算法正常执行
* 预焊焊后测量铜极函数
* 三协的机台
*/
extern "C" __declspec(dllexport) void _stdcall _628_AfterWelding_Distance_T(HObject ho_Image, HObject ho_ImageSeg, HTuple hv_Pix,
HTuple* hv_Out_TopLeft_Line, HTuple* hv_Out_TopLeft_Value, HTuple* hv_Out_TopRight_Line,
HTuple* hv_Out_TopRight_Value, HTuple* hv_Out_BottomLeft_Line, HTuple* hv_Out_BottomLeft_Value,
HTuple* hv_Out_BottomRight_Line, HTuple* hv_Out_BottomRight_Value, HTuple* hv_Make);
/*
* ho_Image:输入图片(原图)
* hv_model:赋值为1时是基准标定模式,0为正常检测模式
* hv_BenchmarkFile:基准标定文件的路径
* hv_NinePointDocument:九点文件的路径
*hv_CameraNumber:上钉相机编号
* hv_out_Cirle:输出放钉孔的圆心x,圆心y,半径。数组形式
* hv_Make:输出-1为算法错误,输出1为算法正常执行,输出为2为基准标定成功
* hv_offset_x:x轴方向上相对于基准位置的偏差
* hv_offset_y:y轴方向上相对于基准位置的偏差
* 上钉引导函数
* 赢合的机台
*/
extern "C" __declspec(dllexport) void _stdcall _628_SealingNails(HObject ho_Image, HTuple hv_model, HTuple hv_BenchmarkFile,
HTuple hv_NinePointDocument, HTuple hv_CameraNumber, HTuple* hv_out_Cirle, HTuple* hv_Make,
HTuple* hv_offset_x, HTuple* hv_offset_y);
/*
* ho_Image:输入图片(原图)
* hv_model:赋值为1时是基准标定模式,0为正常检测模式
* hv_BenchmarkFile:基准标定文件的路径
* hv_NinePointDocument:九点文件的路径
*hv_CameraNumber:预焊相机编号
* hv_out_Cirle:输出放钉孔的圆心x,圆心y,半径。数组形式
* hv_Make:输出-1为算法错误,输出1为算法正常执行,输出为2为基准标定成功
* hv_offset_x:x轴方向上相对于基准位置的偏差
* hv_offset_y:y轴方向上相对于基准位置的偏差
* hv_Text:输出报警信息包括(ok,无钉,翘钉,反钉)
* 赢合机台
* 预焊函数
*/
extern "C" __declspec(dllexport) void _stdcall _628_yuhan(HObject ho_Image, HTuple hv_Model, HTuple hv_BenchmarkFile, HTuple hv_NinePointDocument,
HTuple hv_CameraNumber, HTuple* hv_out_Cirle, HTuple* hv_Make, HTuple* hv_offset_x,
HTuple* hv_offset_y, HTuple* hv_Text);
/*
* ho_Image:输入图片(原图)
* hv_model:赋值为1时是基准标定模式,0为正常检测模式
* hv_BenchmarkFile:基准标定文件的路径
* hv_NinePointDocument:九点文件的路径
*hv_CameraNumber:预焊相机编号
* hv_out_Cirle:输出放钉孔的圆心x,圆心y,半径。数组形式
* hv_Make:输出-1为算法错误,输出1为算法正常执行,输出为2为基准标定成功
* hv_offset_x:x轴方向上相对于基准位置的偏差
* hv_offset_y:y轴方向上相对于基准位置的偏差
* 终焊函数
* 赢合的机台
*/
extern "C" __declspec(dllexport) void _stdcall _628_FinalWelding(HObject ho_Image, HTuple hv_model, HTuple hv_BenchmarkFile,
HTuple hv_NinePointDocument, HTuple hv_CameraNumber, HTuple* hv_out_Cirle, HTuple* hv_Make,
HTuple* hv_offset_x, HTuple* hv_offset_y);
/*
* ho_Image1:输入图片(原图)
* ho_Image2:输入图片(原图)
* ho_Image3:输入图片(原图)
* ho_Image4:输入图片(原图)
*ho_Out_Image1:输出图片1
* ho_Out_image2:输出图片2
* hv_Make:输出-1为算法错误,输出1为算法正常执行,输出为2为基准标定成功
* hv_sacats:光源与光轴夹角
* hv_Tilts:光源安装位置
*/
extern "C" __declspec(dllexport) void _stdcall _628_25D(HObject ho_Image1, HObject ho_Image2, HObject ho_Image3, HObject ho_Image4,
HObject* ho_Out_Image1, HObject* ho_Out_image2, HTuple hv_sacats, HTuple hv_Tilts,
HTuple* hv_Make);
#endif
#if 1 halcon调用函数
void gen_arrow_contour_xld(HObject* ho_Arrow, HTuple hv_Row1, HTuple hv_Column1,
HTuple hv_Row2, HTuple hv_Column2, HTuple hv_HeadLength, HTuple hv_HeadWidth);
void Get_Rectangle2_Corner_new(HObject ho_Rectangle, HTuple* hv_out_Row, HTuple* hv_out_Col);
void pts_to_best_line(HObject* ho_Line, HTuple hv_Rows, HTuple hv_Cols, HTuple hv_ActiveNum,
HTuple* hv_Row1, HTuple* hv_Column1, HTuple* hv_Row2, HTuple* hv_Column2);
void rake(HObject ho_Image, HObject* ho_Regions, HTuple hv_Elements, HTuple hv_DetectHeight,
HTuple hv_DetectWidth, HTuple hv_Sigma, HTuple hv_Threshold, HTuple hv_Transition,
HTuple hv_Select, HTuple hv_Row1, HTuple hv_Column1, HTuple hv_Row2, HTuple hv_Column2,
HTuple* hv_ResultRow, HTuple* hv_ResultColumn);
void pts_to_best_circle(HObject* ho_Circle, HTuple hv_Rows, HTuple hv_Cols, HTuple hv_ArcType,
HTuple hv_ActiveNum, HTuple* hv_RowCenter, HTuple* hv_ColCenter, HTuple* hv_Radius,
HTuple* hv_StartPhi, HTuple* hv_EndPhi, HTuple* hv_PointOrder, HTuple* hv_ArcAngle);
void region_to_spoke(HObject ho_Region, HTuple hv_Offset, HTuple* hv_SpokeRows,
HTuple* hv_SpokeCols);
void spoke(HObject ho_Image, HObject* ho_Regions, HTuple hv_Elements, HTuple hv_DetectHeight,
HTuple hv_DetectWidth, HTuple hv_Sigma, HTuple hv_Threshold, HTuple hv_Transition,
HTuple hv_Select, HTuple hv_ROIRows, HTuple hv_ROICols, HTuple hv_Direct, HTuple* hv_ResultRow,
HTuple* hv_ResultColumn, HTuple* hv_ArcType);
void _628_PreWelded(HObject ho_Image, HTuple hv_model, HTuple hv_BenchmarkFile,
HTuple hv_NinePointDocument, HTuple hv_CameraNumber, HTuple* hv_out_Cirle, HTuple* hv_Make,
HTuple* hv_offset_x, HTuple* hv_offset_y);
void BeforeWelding_L(HObject ho_Image_L, HTuple hv_Pix_T, HTuple* hv_Make, HTuple* hv_Out_Line,
HTuple* hv_Out_Vale, HTuple* hv_Out_PointRow, HTuple* hv_Out_PointCol);
void BeforeWelding_T(HObject ho_Image_T, HTuple hv_Pix_T, HTuple* hv_Make, HTuple* hv_Out_Line,
HTuple* hv_Out_Vale, HTuple* hv_Out_PointRow, HTuple* hv_Out_PointCol);
#endif
Binary file not shown.
+4 -3
View File
@@ -1,4 +1,4 @@
#pragma once
#pragma once
#include <io.h>
#include <direct.h>
#define FENGZHUANG_API __declspec(dllexport)
@@ -10,13 +10,14 @@
#include <opencv2/opencv.hpp>
#include <windows.h>
#include <stdlib.h>
#include <corecrt_wstring.h>
using namespace cv;
FENGZHUANG_API void putTextHusky(Mat& dst, const char* str, Point org, Scalar color, int fontSize,
const char* fn = "Arial", bool italic = false, bool underline = false);
FENGZHUANG_API int32_t createDirectory(const wstring& directoryPath);
FENGZHUANG_API int32_t createDirectory(const string& directoryPath);
FENGZHUANG_API int32_t createDirectory(const std::wstring& directoryPath);
FENGZHUANG_API int32_t createDirectory(const std::string& directoryPath);
FENGZHUANG_API char* UnicodeToAnsi(const wchar_t* szStr);
FENGZHUANG_API wchar_t* AnsiToUnicode(const char* szStr);
FENGZHUANG_API std::string WString2String(const std::wstring& ws);