You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Cigarette/Cigarette/Thread/syncworkthread.cpp

349 lines
16 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "SyncWorkThread.h"
#include "alg_jd.h"
#include "common.h"
#include "balluffcamera.h"
#include "baslercamera.h"
#include "threadSend.h"
#include <PLCDevice.h>
#include "exportData.h"
#include <QMap>
extern AlgJd alg_jd[NumberOfSupportedCameras]; //检测胶点的AI算法
extern ConfPath g_conf_path;
extern SysConf g_sys_conf; //系统配置参数
extern DisplayLabelConf g_display_label_conf[NumberOfSupportedCameras];
extern int rotationAngle[NumberOfSupportedCameras]; //图片旋转角度
extern bool isNeedRotate[NumberOfSupportedCameras];
extern int work_camera_nums;
extern SingleCamInfoStruct SingleCamInfo[NumberOfSupportedCameras];
extern SyncQueue<std::pair<std::string, cv::Mat> >* g_save_queue; //图片保存队列
extern SyncQueue<std::pair<int, cv::Mat>>* g_image_queue[NumberOfSupportedCameras]; //int表示一个目标拍了几张
#ifdef __UDPSend
extern SyncQueue<_UDPSendInfo>* UDP_Info_queue;
#endif
#ifdef __TCPSend
extern SyncQueue<_TCPSendInfo>* TCP_Info_queue;
#endif
#ifdef __ExportData
extern ExportDataThread exportDataThread;
#endif
extern PLCDevice* m_PLCDevice;
extern bool g_debug_mode;
SyncWorkThread::~SyncWorkThread()
{
stop();
std::vector<std::pair<int, cv::Mat>> queue;
local_g_image_sync_queue->put(queue);
quit();
wait();
}
void SyncWorkThread::init(SyncQueue<std::vector<std::pair<int, cv::Mat>>>* image_ptr, ASyncQueue<bool>* result_ptr)
{
local_g_image_sync_queue = image_ptr;
local_g_result_queue = result_ptr;
b_quit = false;
for (int i = 0; i < NumberOfSupportedCameras; i++) {
frame_total[i] = 0;
}
}
void SyncWorkThread::start_work()
{
start(HighestPriority);
}
void SyncWorkThread::stop()
{
b_quit = true;
}
void SyncWorkThread::run()
{
try {
uint32_t result_index[NumberOfSupportedCameras] = { 0 };
while (!b_quit) {
QDateTime now_ts = QDateTime::currentDateTime();
std::vector<std::pair<int, cv::Mat>> element_vec;
local_g_image_sync_queue->take(element_vec);
bool IsNGForAll = false;
int merge_index;
cv::Mat merge_image = cv::Mat::zeros(512 * work_camera_nums, 640 * g_sys_conf.shoot[0], CV_8UC3);
cv::Rect roi;
int j = 0; // 实际工作的相机标识element_vec中可能有相机没在工作
for (int i = 0; i < element_vec.size(); i++)//每个相机的图轮流遍历
{
if (!SingleCamInfo[i].Detect || !SingleCamInfo[i].IsOpen || SingleCamInfo[i].OffLine)
continue;
local_camera_number = i;
std::pair<int, cv::Mat> element;
element = element_vec[i];
int unit_count = element.first;
cv::Mat image = element.second;
{//不要删掉这个括号,用来定义锁的作用域
std::lock_guard<std::mutex> locker(g_sys_conf.lock);
local_SysConf.save = g_sys_conf.save;
local_SysConf.shoot[local_camera_number] = g_sys_conf.shoot[local_camera_number];
local_SysConf.MisMatchAct = g_sys_conf.MisMatchAct;
local_SysConf.ConfThreshold = g_sys_conf.ConfThreshold;//
for (int i = 0; i < 3; i++)local_SysConf.no[local_camera_number][i] = g_sys_conf.no[local_camera_number][i];
#ifdef DRAW_RECT
std::lock_guard<std::mutex> locker2(g_display_label_conf[local_camera_number].lock);
local_DisplayLabelConf.leftButtonDownFlag = g_display_label_conf[local_camera_number].leftButtonDownFlag;
local_DisplayLabelConf.Flag[0] = g_display_label_conf[local_camera_number].Flag[0];
local_DisplayLabelConf.Flag[1] = g_display_label_conf[local_camera_number].Flag[1];
local_DisplayLabelConf.originalPoint = g_display_label_conf[local_camera_number].originalPoint;
local_DisplayLabelConf.processPoint = g_display_label_conf[local_camera_number].processPoint;
local_DisplayLabelConf.RectVet[0] = g_display_label_conf[local_camera_number].RectVet[0];
local_DisplayLabelConf.RectVet[1] = g_display_label_conf[local_camera_number].RectVet[1];
#endif
}
#ifdef __UDPSend
_UDPSendInfo UDPSendInfo;
UDPSendInfo.FrameID = info_frame;
UDPSendInfo.index = local_camera_number;
#endif
#ifdef __TCPSend
_TCPSendInfo TCPSendInfo;
#endif
if (!image.data)
{
continue; //图像为空,跳过
}
if (image.channels() == 1)
{
cv::cvtColor(image, image, CV_BGR2RGB); //灰度图像转为彩色图像
}
cv::resize(image, image, cv::Size(640, 512 * unit_count));
if (local_SysConf.shoot[local_camera_number] == unit_count)
{
std::vector<cv::Mat> vec_in;
int w = image.cols;
int h = image.rows / unit_count;
for (int index = 0; index < unit_count; index++) {
cv::Rect temp_Rect(0, h * index, w, h);
cv::Mat temp_image = image(temp_Rect).clone();
if (isNeedRotate[local_camera_number]) {
if (rotationAngle[local_camera_number] != (cv::ROTATE_90_COUNTERCLOCKWISE + 1))
{
cv::rotate(temp_image, temp_image, rotationAngle[local_camera_number]);
}
}
vec_in.push_back(temp_image.clone());
}
std::vector<cv::Mat> vec_out;
std::vector<std::vector<std::pair<int, cv::Rect>>> vec_results;
QDateTime ts_start = QDateTime::currentDateTime();
if (unit_count == 1) {
std::vector<std::pair<int, cv::Rect>> results;
cv::Mat imagein, imageout;
imagein = vec_in[0];
alg_jd[local_camera_number].detect(imagein, imageout, results);
vec_out.push_back(imageout.clone());
vec_results.push_back(results);
}
else {
alg_jd[local_camera_number].detect_batch(vec_in, vec_out, vec_results);
}
QDateTime ts_jd = QDateTime::currentDateTime();
int time_process = ts_start.msecsTo(ts_jd);
#ifdef SYNC_CAMERA
emit display_timecost(local_camera_number, time_process);
#endif
#ifdef __UDPSend
UDPSendInfo.timecost = QString::number(time_process);
#endif
cv::Mat image1;
cv::Mat image2;
QString jd_no;
for (int index = 0; index < unit_count; index++) {
jd_no += QString::number(vec_results[index].size()) + ",";
}
jd_no.chop(1);
#ifdef SYNC_CAMERA
emit display_jd_no(local_camera_number, jd_no);
#endif
#ifdef __UDPSend
UDPSendInfo.JD = jd_no;
#endif
bool IsNG = false;
int ngReason = 0;
QMap<int, QString> ng_reason_maps;
ng_reason_maps[0] = "unknow";
ng_reason_maps[1] = "less_than_setting";
ng_reason_maps[2] = "too_diff_from_model";
ng_reason_maps[3] = "out_of_setting_range";
for (int index = 0; index < unit_count; index++) {
if (vec_results[index].size() < local_SysConf.no[local_camera_number][index])
{
IsNG |= true;
ngReason = 1;
}
//if (vec_results[index].size() != 1)IsNG |= true;//反向训练
if (local_SysConf.ConfThreshold == 0)
{
IsNG = false;
ngReason = 0;
}
if (local_SysConf.save == 2)//三张照片分别存储
{
/// 合成work_camera_nums * unit_count 宫格图像
cv::Mat m = vec_in[index].clone();
QString file_name;
merge_index = j * unit_count + index + 1;
roi = cv::Rect(index * m.cols, j * m.rows, m.cols, m.rows);
m.copyTo(merge_image(roi));
if (merge_index == work_camera_nums * unit_count) {
file_name = g_conf_path.save_pics_path + "/"
+ now_ts.toString("yyyy-MM-dd") + "/"
+ now_ts.toString("yyyy-MM-dd_HH-mm-ss_zzz_") + ".jpg";
g_save_queue->put(std::make_pair(file_name.toLocal8Bit().constData(), merge_image));
#ifdef __TCPSend
QString sendName = now_ts.toString("yyyy-MM-dd_HH-mm-ss_zzz_") + ".jpg";
TCPSendInfo.pics_name = sendName.toLocal8Bit().constData();
TCP_Info_queue->put(TCPSendInfo);
#endif
}
}
}
if (unit_count >= 2) {
image1 = vec_out[(result_index[i]) % 2].clone();
#ifdef DRAW_RECT
IsNG |= CheckSelectRects(image1, vec_results, (result_index[i]) % 2, local_DisplayLabelConf, 0);
if (IsNG) {
ngReason = 2;
}
#endif
}
else {
image1 = vec_out[0].clone();
#ifdef DRAW_RECT
IsNG |= CheckSelectRects(image1, vec_results, 0, local_DisplayLabelConf, 0);
if (IsNG) {
ngReason = 2;
}
#endif
}
#ifdef DRAW_RECT
DrawSelectRects(image1, local_DisplayLabelConf, 0);
#endif
if (unit_count >= 3) {
image2 = vec_out[2].clone();
#ifdef DRAW_RECT
DrawSelectRects(image2, local_DisplayLabelConf, 1);
IsNG |= CheckSelectRects(image1, vec_results, 2, local_DisplayLabelConf, 1);
if (IsNG) {
ngReason = 3;
}
#endif
}
result_index[i]++;
if (!IsNG)
{
if (!g_debug_mode)
{
#ifdef SYNC_CAMERA
emit event_ok(local_camera_number);
#endif
local_g_result_queue->put(true);
}
}
else
{
if (!g_debug_mode)
{
#ifdef SYNC_CAMERA
emit event_ng(local_camera_number);
#endif
local_g_result_queue->put(false);
IsNGForAll = TRUE;
}
if ((local_SysConf.save == 2) || (local_SysConf.save == 1))
{
for (int index = 0; index < unit_count; index++)
{
cv::Mat m = vec_in[index].clone();
QString file_name = g_conf_path.save_pics_path + "/ng/" +
now_ts.toString("yyyy-MM-dd") + "/"
+ QString::number(local_camera_number + 1) + "/" + QString::number(index + 1) + "/" +
now_ts.toString("yyyy-MM-dd_HH-mm-ss_zzz_") + QString::number(local_camera_number + 1) +
"#" + "_" + QString::number(index + 1) + "_" + ng_reason_maps[ngReason] +
".jpg";
QString remotePath = "/image/ng/" +
now_ts.toString("yyyy-MM-dd_HH-mm-ss_zzz_") + QString::number(local_camera_number + 1) +
"#" + "_" + QString::number(index + 1) + "_" + ng_reason_maps[ngReason] +
".jpg";
g_save_queue->put(std::make_pair(file_name.toLocal8Bit().constData(), m));
m = vec_out[index].clone();
file_name = g_conf_path.save_pics_path + "/ng_result/" +
now_ts.toString("yyyy-MM-dd") + "/"
+ QString::number(local_camera_number + 1) + "/" + QString::number(index + 1) + "/" +
now_ts.toString("yyyy-MM-dd_HH-mm-ss_zzz_") + QString::number(local_camera_number + 1) +
"#" + "_" + QString::number(index + 1) + "_" + ng_reason_maps[ngReason] +
".jpg";
remotePath = "/image/ng_result/" +
now_ts.toString("yyyy-MM-dd_HH-mm-ss_zzz_") + QString::number(local_camera_number + 1) +
"#" + "_" + QString::number(index + 1) + "_" + ng_reason_maps[ngReason] +
".jpg";
//g_save_queue->put(std::make_pair(file_name.toStdString(), m));
g_save_queue->put(std::make_pair(file_name.toLocal8Bit().constData(), m));
}
}
}
#ifdef SYNC_CAMERA
if (!g_debug_mode)
{
emit display_check_total(local_camera_number, ++frame_total[local_camera_number]);
//exportDataInfo.cameraTotal = frame_total;
emit notify(local_camera_number, 0, image1);
if (unit_count >= 3)
emit notify(local_camera_number, 1, image2);
}
#endif
}
else
{
#ifdef SYNC_CAMERA
//保证不错位
if (!g_debug_mode)
{
if (local_SysConf.MisMatchAct == 1)//as ng
emit event_ng(local_camera_number);
else if (local_SysConf.MisMatchAct == 0)//as ok
emit event_ok(local_camera_number);
emit display_check_total(local_camera_number, ++(frame_total[local_camera_number]));
qDebug() << local_camera_number << "#camera# " << now_ts.toString("yyyy-MM-dd_HH-mm-ss_zzz_") << "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx " << unit_count;
}
#endif
}
#ifdef __UDPSend
UDP_Info_queue->put(UDPSendInfo);
#endif
j++;
}
if (IsNGForAll)
{
/*to do something*/
}
}
}
catch (cv::Exception& e)
{
const char* err_msg = e.what();
std::cout << "exception caught: " << err_msg << std::endl;
}
}