☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜

每一年,中国都因交通事故而造成数万人的死亡,造成了严重的损失。而其中司机疲劳驾驶,是导致事故发生的重要原因之一。但是当司机们陷入疲劳驾驶状态时,往往司机本人对此状态并不在意,甚至会陷入睡眠状态!整治疲劳驾驶行为成为了交通运输行业的首要任务。随着信息技术的日新月异,如今,我们有机会使用信息技术,消除疲劳驾驶的隐患。利用移动端设备的摄像头,我们可以实现实时的监测司机的状态。使用PaddleDetection+PaddleLite部署及Paddle2onnx转IR的OpenVINO部署,实现了通过驾驶员的眼部、嘴部动作实时推断疲劳状态,使得驾驶员能及时的被本地语音方式提醒,避免疲劳驾驶,同时后台管理人员能接收到司机疲劳报警信息。
GitHub链接: FatigueDriving
# 解压数据集!unzip /home/aistudio/data/data106856/fatigue.zip
# 调整数据集的反斜杠问题f = open('/home/aistudio/fatigue/val_list.txt')
data = f.read()
data2 = data.replace('\', '/')f1 = open('/home/aistudio/fatigue/val_list.txt','w')
f1.write(data2)# 解压PaddleDetection!unzip /home/aistudio/data/data122193/PaddleDetection.zip
# 安装PaddleDetection依赖环境!pip install -r PaddleDetection/requirements.txt
# 模型训练# 修改ssdlite_mobilenet_v3_small_320_coco.yml中数据集格式为'../datasets/voc.yml', 并将'../datasets/voc.yml'里的数据路径改为当前数据集目录,以适配疲劳驾驶数据集!python PaddleDetection/tools/train.py -c PaddleDetection/configs/ssd/ssdlite_mobilenet_v3_small_320_coco.yml --use_vdl=True --eval
!python PaddleDetection/tools/infer.py -c PaddleDetection/configs/ssd/ssdlite_mobilenet_v3_small_320_coco.yml
-o weights=output/ssdlite_mobilenet_v3_small_320_coco/best_model.pdparams
--infer_img= ./0.jpg #(需要检测的图片)# 导出ssd模型python PaddleDetection/tools/export_model.py -c PaddleDetection/configs/ssd/ssdlite_mobilenet_v3_small_320_coco.yml
--output_dir=./ssd_inference_model
-o weights=output/ssdlite_mobilenet_v3_small_320_coco/best_models.pdparams# 安装PaddleLite!pip install paddlelite
# 转换为PaddleLite部署需要的nb模型!paddle_lite_opt
--model_file=ssd_inference_model/ssdlite_mobilenet_v3_small_320_coco/model.pdmodel
--param_file=ssd_inference_model/ssdlite_mobilenet_v3_small_320_coco/model.pdiparams
--optimize_out=ssd_inference_model/ssdlite_mobilenet_v3_small_320_coco/model
--optimize_out_type=naive_buffer
--valid_targets=arm// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at//// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.#include "paddle_api.h"#include <arm_neon.h>#include <opencv2/opencv.hpp>#include <opencv2/highgui.hpp>#include <opencv2/core/core.hpp>#include <stdio.h>#include <sys/time.h>#include <unistd.h>#include <vector>#include <limits>#include <fstream>//#include <wiringPi.h>int WARMUP_COUNT = 0;int REPEAT_COUNT = 1;const int CPU_THREAD_NUM = 2;const paddle::lite_api::PowerMode CPU_POWER_MODE =
paddle::lite_api::PowerMode::LITE_POWER_HIGH;const std::vector<int64_t> INPUT_SHAPE = {1, 3, 320, 320}; //输入形状const std::vector<float> INPUT_MEAN = {0.5f, 0.5f, 0.5f}; //输入平均值const std::vector<float> INPUT_STD = {0.5f, 0.5f, 0.5f}; //输入标准const float SCORE_THRESHOLD = 0.5f; //分数阈值const std::string file_number = "434343434343"; //用户编号struct RESULT {
std::string class_name; float score; float left; float top; float right; float bottom;
};// 获取时间inline int64_t get_current_us() { struct timeval time;
gettimeofday(&time, NULL); return 1000000LL * (int64_t)time.tv_sec + (int64_t)time.tv_usec;
}// 年月日时分秒static std::string getCurrentTimeStr(){ time_t t = time(NULL); char ch[64] = {0}; strftime(ch, sizeof(ch) - 1, "%Y%m%d%H%M", localtime(&t)); //年-月-日-时-分
return ch;
}// 加载标签std::vector<std::string> load_labels(const std::string &path) {
std::ifstream file;
std::vector<std::string> labels;
file.open(path); while (file) {
std::string line;
std::getline(file, line);
labels.push_back(line);
}
file.clear();
file.close(); return labels;
}// 预处理void preprocess(cv::Mat &input_image, const std::vector<float> &input_mean, const std::vector<float> &input_std, int input_width, int input_height, float *input_data) {
cv::Mat resize_image;
cv::resize(input_image, resize_image, cv::Size(input_width, input_height), 0, 0); if (resize_image.channels() == 4) {
cv::cvtColor(resize_image, resize_image, 3);
}
cv::Mat norm_image;
resize_image.convertTo(norm_image, CV_32FC3, 1 / 255.f); // NHWC->NCHW
int image_size = input_height * input_width; const float *image_data = reinterpret_cast<const float *>(norm_image.data); float32x4_t vmean0 = vdupq_n_f32(input_mean[0]); float32x4_t vmean1 = vdupq_n_f32(input_mean[1]); float32x4_t vmean2 = vdupq_n_f32(input_mean[2]); float32x4_t vscale0 = vdupq_n_f32(1.0f / input_std[0]); float32x4_t vscale1 = vdupq_n_f32(1.0f / input_std[1]); float32x4_t vscale2 = vdupq_n_f32(1.0f / input_std[2]); float *input_data_c0 = input_data; float *input_data_c1 = input_data + image_size; float *input_data_c2 = input_data + image_size * 2; int i = 0; for (; i < image_size - 3; i += 4) { float32x4x3_t vin3 = vld3q_f32(image_data); float32x4_t vsub0 = vsubq_f32(vin3.val[0], vmean0); float32x4_t vsub1 = vsubq_f32(vin3.val[1], vmean1); float32x4_t vsub2 = vsubq_f32(vin3.val[2], vmean2); float32x4_t vs0 = vmulq_f32(vsub0, vscale0); float32x4_t vs1 = vmulq_f32(vsub1, vscale1); float32x4_t vs2 = vmulq_f32(vsub2, vscale2); vst1q_f32(input_data_c0, vs0); vst1q_f32(input_data_c1, vs1); vst1q_f32(input_data_c2, vs2);
image_data += 12;
input_data_c0 += 4;
input_data_c1 += 4;
input_data_c2 += 4;
} for (; i < image_size; i++) {
*(input_data_c0++) = (*(image_data++) - input_mean[0]) / input_std[0];
*(input_data_c0++) = (*(image_data++) - input_mean[1]) / input_std[1];
*(input_data_c0++) = (*(image_data++) - input_mean[2]) / input_std[2];
}
}// 后处理std::vector<RESULT> postprocess(const float *output_data, int64_t output_size, const std::vector<std::string> &word_labels, const float score_threshold,
cv::Mat &output_image, double time) {
std::vector<RESULT> results;
std::vector<cv::Scalar> colors = {
cv::Scalar(237, 189, 101), cv::Scalar(0, 0, 255), cv::Scalar(102, 153, 153),
cv::Scalar(255, 0, 0), cv::Scalar(9, 255, 0), cv::Scalar(0, 0, 0),
cv::Scalar(51, 153, 51)}; for (int64_t i = 0; i < output_size; i += 6) { if (output_data[i + 1] < score_threshold) { continue;
} int class_id = static_cast<int>(output_data[i]); float score = output_data[i + 1];
RESULT result;
std::string class_name = "Unknown"; if (word_labels.size() > 0 && class_id >= 0 &&
class_id < word_labels.size()) {
class_name = word_labels[class_id];
}
result.class_name = class_name;
result.score = score;
result.left = output_data[i + 2];
result.top = output_data[i + 3];
result.right = output_data[i + 4];
result.bottom = output_data[i + 5]; int lx = static_cast<int>(result.left * output_image.cols); int ly = static_cast<int>(result.top * output_image.rows); int w = static_cast<int>(result.right * output_image.cols) - lx; int h = static_cast<int>(result.bottom * output_image.rows) - ly;
cv::Rect bounding_box = cv::Rect(lx, ly, w, h) &
cv::Rect(0, 0, output_image.cols, output_image.rows); if (w > 0 && h > 0 && score <= 1) {
cv::Scalar color = colors[results.size() % colors.size()];
cv::rectangle(output_image, bounding_box, color);
cv::rectangle(output_image, cv::Point2d(lx, ly), cv::Point2d(lx + w, ly - 10),
color, -1);
cv::putText(output_image,
std::to_string(results.size()) + "." + class_name + ":" +
std::to_string(score),
cv::Point2d(lx, ly), cv::FONT_HERSHEY_PLAIN, 1, cv::Scalar(255, 255, 255));
results.push_back(result);
}
} return results;
}//识别处理cv::Mat process(cv::Mat &input_image,
std::vector<std::string> &word_labels,
std::shared_ptr<paddle::lite_api::PaddlePredictor> &predictor) { // 对图像进行预处理,填充输入张量数据
std::unique_ptr<paddle::lite_api::Tensor> input_tensor(
std::move(predictor->GetInput(0)));
input_tensor->Resize(INPUT_SHAPE); int input_width = INPUT_SHAPE[3]; int input_height = INPUT_SHAPE[2]; auto *input_data = input_tensor->mutable_data<float>(); double preprocess_start_time = get_current_us(); preprocess(input_image, INPUT_MEAN, INPUT_STD, input_width, input_height,
input_data); double preprocess_end_time = get_current_us(); double preprocess_time = (preprocess_end_time - preprocess_start_time) / 1000.0f; double prediction_time; // 运行预测
for (int i = 0; i < WARMUP_COUNT; i++) {
predictor->Run();
} double max_time_cost = 0.0f; double min_time_cost = std::numeric_limits<float>::max(); double total_time_cost = 0.0f; for (int i = 0; i < REPEAT_COUNT; i++) { auto start = get_current_us();
predictor->Run(); auto end = get_current_us(); double cur_time_cost = (end - start) / 1000.0f; if (cur_time_cost > max_time_cost) {
max_time_cost = cur_time_cost;
} if (cur_time_cost < min_time_cost) {
min_time_cost = cur_time_cost;
}
total_time_cost += cur_time_cost;
prediction_time = total_time_cost / REPEAT_COUNT; printf("iter %d cost: %f ms
", i, cur_time_cost);
} printf("warmup: %d repeat: %d, average: %f ms, max: %f ms, min: %f ms
",
WARMUP_COUNT, REPEAT_COUNT, prediction_time,
max_time_cost, min_time_cost); // 获取输出张量数据,进行后处理,输出检测对象
std::unique_ptr<const paddle::lite_api::Tensor> output_tensor(
std::move(predictor->GetOutput(0))); const float *output_data = output_tensor->mutable_data<float>(); int64_t output_size = 1; for (auto dim : output_tensor->shape()) {
output_size *= dim;
}
cv::Mat output_image = input_image.clone(); double postprocess_start_time = get_current_us();
std::vector<RESULT> results = postprocess(
output_data, output_size, word_labels, SCORE_THRESHOLD, output_image, prediction_time); double postprocess_end_time = get_current_us(); double postprocess_time = (postprocess_end_time - postprocess_start_time) / 1000.0f;
// wiringPi
//wiringPiSetup();
std::string warning_content_0 = "closed_eye";
std::string warning_content_1 = "open_mouth";
std::string time_ymdhms = getCurrentTimeStr();
// 结果输出
printf("results: %d
", results.size()); for (int i = 0; i < results.size(); i++) { // GPIO 0 高电平输出触发蜂鸣器
// pinMode(0,OUTPUT);
// 存储图像
if (results[i].class_name.c_str()==warning_content_0)
{
std::string output_path = "./fatigueDriving/screenshots/Q" + file_number + time_ymdhms + warning_content_0 + ".jpg";
cv::imwrite(output_path,output_image);
} if (results[i].class_name.c_str()==warning_content_1){
std::string output_path = "./fatigueDriving/screenshots/Q" + file_number + time_ymdhms + warning_content_1 + ".jpg";
cv::imwrite(output_path,output_image);
} // if (results[i].class_name.c_str()==warning_content){digitalWrite(0,HIGH);delay(20);digitalWrite(0,LOW);delay(1);cv::imwrite(output_path,output_image);delay(1);}
// else{digitalWrite(0,LOW);delay(1);}
printf("[%d] %s - %f %f,%f,%f,%f
", i, results[i].class_name.c_str(),
results[i].score, results[i].left, results[i].top, results[i].right,
results[i].bottom);
} printf("Preprocess time: %f ms
", preprocess_time); printf("Prediction time: %f ms
", prediction_time); printf("Postprocess time: %f ms
", postprocess_time); return output_image;
}int main(int argc, char **argv) { // 加载模型地址
std::string model_path = argv[1]; // 加载标签地址
std::string label_path = argv[2]; // 加载标签
std::vector<std::string> word_labels = load_labels(label_path); // 加载模型
paddle::lite_api::MobileConfig config;
config.set_model_from_file(model_path);
config.set_threads(CPU_THREAD_NUM);
config.set_power_mode(CPU_POWER_MODE);
std::shared_ptr<paddle::lite_api::PaddlePredictor> predictor =
paddle::lite_api::CreatePaddlePredictor<paddle::lite_api::MobileConfig>(config); // 视频流预测
cv::VideoCapture cap(-1);
cap.set(cv::CAP_PROP_FRAME_WIDTH, 640);
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 480); // 判断是否开启摄像头
if (!cap.isOpened()) { return -1;
} // 执行
while (1) {
cv::Mat input_image;
cap >> input_image;
cv::Mat output_image = process(input_image, word_labels, predictor);
cv::imshow("Real-Time", output_image); if (cv::waitKey(1) == char('q')) { break;
}
}
cap.release();
cv::destroyAllWindows(); return 0;
}# 模型训练!python PaddleDetection/tools/train.py -c PaddleDetection/configs/yolov3/yolov3_mobilenet_v3_large_270e_voc.yml --use_vdl=True --eval
!python PaddleDetection/tools/infer.py -c PaddleDetection/configs/yolov3/yolov3_mobilenet_v3_large_270e_voc.yml
-o weights=output/yolov3_mobilenet_v3_large_270e_voc/best_model.pdparams
--infer_img= ./0.jpg #(需要检测的图片)# 安装paddle2onnx%cd /home/aistudio/# !git clone https://github.com/PaddlePaddle/Paddle2ONNX.git!unzip Paddle2ONNX-develop.zip%cd Paddle2ONNX-develop# !git checkout release/0.9!python setup.py install %cd experimental
!pip install onnx
import paddle2onnximport paddlefrom openvino_ppdet import nms_mapper# 通过上面的`nms_mapper`的import来启用插件,替换了paddle2onnx原始的nms_mappermodel_prefix = "/home/aistudio/yolov3-output/yolov3_mobilenet_v3_large_270e_voc/" # 一直写到模型文件名model = paddle.jit.load(model_prefix)
input_shape_dict = { "image": [1, 3, 608, 608], "scale_factor": [1, 2], "im_shape": [1, 2]
}
onnx_model = paddle2onnx.run_convert(model, input_shape_dict=input_shape_dict, opset_version=11)with open("./yolov3.onnx", "wb") as f:
f.write(onnx_model.SerializeToString())到此步骤后我们可以得到XXX.onnx模型文件,再使用OpenVINO的mo命令转换为IR模型文件。具体操作请参照OpenVINO使用文档
#include "fatigueDriving.h"fatigueDriving::fatigueDriving() {};
fatigueDriving::~fatigueDriving() {};int fatigueDriving::Init(std::string modelPath, bool useIntelgpu){
std::string xmlPath, binPath; // 加载模型
std::cout << "Loading model ... " << std::endl;
xmlPath = modelPath + "/yolov3.xml";
binPath = modelPath + "/yolov3.bin";
network = ie.ReadNetwork(xmlPath, binPath); // 载至cpu/gpu
try {
executableNetwork = ie.LoadNetwork(network, useIntelgpu ? "GPU" : "CPU");
std::cout << "Loading model succeeded!" << std::endl;
} catch (...) { return -2;
} // 构建预测
inferRequest = executableNetwork.CreateInferRequest(); // 获取输入输出的Blob
inputImage = inferRequest.GetBlob("image");
inputImShape = inferRequest.GetBlob("im_shape");
inputScaleFactor = inferRequest.GetBlob("scale_factor");
outputInfo = inferRequest.GetBlob("translated_layer/scale_0.tmp_0"); // 输入尺寸
inputChannelsNumber = inputImage->getTensorDesc().getDims()[1];
inputHeight = inputImage->getTensorDesc().getDims()[2];
inputWidth = inputImage->getTensorDesc().getDims()[3]; // 输出尺寸
outputBboxesNumber = outputInfo->getTensorDesc().getDims()[0];
outputSingleInfo = outputInfo->getTensorDesc().getDims()[1]; return 1;
}int fatigueDriving::Process(const cv::Mat img, std::vector<std::vector<float>> &outputs, float scoreThreshold){ if (!img.data)return -1;//判断是否有数据
std::vector<float> mean;
mean.push_back(0.485f);
mean.push_back(0.456f);
mean.push_back(0.406f);
std::vector<float> std;
std.push_back(0.229f);
std.push_back(0.224f);
std.push_back(0.225f);
cv::Mat image;
cv::cvtColor(img, image, cv::COLOR_BGR2RGB);
cv::resize(image, image, cv::Size(inputWidth, inputHeight)); // HWC =》NCHW
float* data = static_cast<float*>(inputImage->buffer()); size_t image_size = inputHeight * inputWidth; for (size_t row = 0; row < inputHeight; ++row) { for (size_t col = 0; col < inputWidth; ++col) { for (size_t ch = 0; ch < inputChannelsNumber; ++ch) {
data[image_size * ch + row * inputWidth + col] = ((image.at<cv::Vec3b>(row, col)[ch]) / 255.0f) - float(mean[ch]) / std[ch];
}
}
} // 输入尺寸
float* im_shape = static_cast<float*>(inputImShape->buffer());
im_shape[0] = image.rows;
im_shape[1] = image.cols; // 缩放因子
float* scale_factor = static_cast<float*>(inputScaleFactor->buffer());
scale_factor[0] = inputHeight / float(img.rows);
scale_factor[1] = inputWidth / float(img.cols); // 预测
clock_t time_start = clock();
inferRequest.Infer(); clock_t time_temp = clock(); // 获取输出
std::vector<float> output; auto output_data = outputInfo->buffer().as<InferenceEngine::PrecisionTrait<InferenceEngine::Precision::FP32>::value_type*>(); for (int i = 0; i < outputBboxesNumber; i++) { for (int j = 0; j < outputSingleInfo; j++) {
output.push_back(output_data[i * outputSingleInfo + j]);
} if (output[1] > scoreThreshold) {
outputs.push_back(output);
}
output.clear();
} return 1;
}#include <pybind11/stl.h>#include <pybind11/cast.h>#include <pybind11/stl_bind.h>#include <pybind11/numpy.h>#include "fatigueDriving.h"namespace py = pybind11;py::array ConvertMatToNDArray(cv::Mat& m);
PYBIND11_MODULE(pyFatigueDriving, m)
{
m.attr("__doc__") = "paddle interface";
m.attr("__version__") = "v0.1.0";
m.def("ConvertNDArrayToMat", [](py::array_t<uchar>& input_data)
{ cv::Mat dst = ConvertNDArrayToMat(input_data);
return dst;
}, py::arg("input_data")); py::class_<cv::Mat>(m, "cvMat"); py::class_<fatigueDriving>(m, "fatigueDriving")
.def(py::init<>())
.def("Init", &fatigueDriving::Init)
.def("Process", [](fatigueDriving& vc, const cv::Mat& img, float scoreThreshold)
{ std::vector<std::vector<float>> outputs;
int ret = vc.Process(img, outputs, scoreThreshold);
return py::make_tuple(ret, outputs);
}, py::arg("img"), py::arg("scoreThreshold"));
}通过检测部分的存储违规图像动作,触发语音提示及信息记录功能
import osimport _threadimport sysimport timeimport threadingimport cv2import numpy as npimport pygamefrom PyQt5 import QtWidgetsfrom PyQt5.QtWidgets import QApplication, QDialog, QMainWindowfrom watchdog.events import *from watchdog.observers import Observerfrom MySQL_Connect import MySQL_Connect# 加载openvino部署封装的dll及pydos.add_dll_directory(os.path.join(os.getcwd(), "./OpenVINO/dlls/"))
sys.path.append(os.path.join(os.getcwd(), "./OpenVINO/libs/"))import pyFatigueDriving# 播放警示音频class Play_Audio():
def __init__(self, audio):
self.audio = audio def run(self):
pygame.mixer.init()
pygame.mixer.music.load(self.audio) # './audio/warning.mp3'
pygame.mixer.music.play()
time.sleep(7)
pygame.mixer.music.stop()class MyDirEventHandler(FileSystemEventHandler):
def __init__(self):
FileSystemEventHandler.__init__(self)
self.audio = './audio/warning.mp3'
self.warning = Play_Audio(self.audio) def on_created(self, event):
print("file created:{0}".format(event.src_path))
a = str(event.src_path)
self.warning.run()# 转换为可存储到数据库的格式def save_received_info(user_info, iolations_time, new_filename):
user_all_info = {}
user_all_info['编号'] = user_info[0]
user_all_info['姓名'] = user_info[1]
user_all_info['性别'] = user_info[2]
user_all_info['年龄'] = user_info[3]
user_all_info['身份证号'] = user_info[4]
user_all_info['联系电话'] = user_info[5]
user_all_info['省份'] = user_info[6]
user_all_info['城市'] = user_info[7]
user_all_info['区/县'] = user_info[8]
user_all_info['车型'] = user_info[9]
user_all_info['行驶证编号'] = user_info[10]
user_all_info['车牌号'] = user_info[11]
user_all_info['违规时间'] = iolations_time
user_all_info['违规证据图像位置'] = new_filename print(user_all_info) return user_all_info# 信息记录至SQLdef ToSQL(a, module_name):
# 初始化SQL
MySQL = MySQL_Connect() # 拉取用户数据
number = module_name[1:13]
iolations_time = module_name[13:17]+'-'+module_name[17:19] + '-'+module_name[19:21]+' '+module_name[21:23]+':'+module_name[23:25]
user_info = MySQL.MC_SELECT_User_Info(local_info=number)[0] # 生成数据列表
user_list_violation_info = save_received_info(
user_info, iolations_time, a)
MySQL.MC_Save_Violation_Info(user_list_violation_info)# 执行预测def run_detection_win_py(savepath):
file_number = "434343434343"
cap =cv2.VideoCapture(0) while(True):
nowtime = time.strftime("%Y%m%d%H%M%S")
ret , frame =cap.read()
ret, output = fd.Process(pyFatigueDriving.ConvertNDArrayToMat(frame), 0.1) for single_info in output:
cv2.rectangle(frame, (int(single_info[2]), int(single_info[3])), (int(single_info[4]), int(single_info[5])), (0, 0, 255), 1, 4)
label = str(int(single_info[0])) + ': ' + str(single_info[1])
cv2.putText(frame, label, (int(single_info[2]), int(single_info[3])), cv2.FONT_HERSHEY_COMPLEX, 2, (0, 0, 255), 1, 4) if int(single_info[0]) == 0:
module_name = 'Q' + file_number + nowtime + str(single_info[0]) + '.jpg'
savefile = savepath + module_name
cv2.imwrite(savefile, frame)
ToSQL(savefile, module_name) break
if int(single_info[0]) == 3: if ((single_info[5]-single_info[3])/(single_info[4]-single_info[2])>=0.9):
module_name = 'Q' + file_number + nowtime + str(single_info[0]) + '.jpg'
savefile = savepath + module_name
cv2.imwrite(savefile, frame)
ToSQL(savefile, module_name) break
cv2.imshow("real-time", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break
cap.release()
cv2.destroyAllWindows()# 监控文件的变化def run_scan_file(file_name):
# 创建观察者对象
observer = Observer() # 创建事件处理对象
fileHandler = MyDirEventHandler() # 为观察者设置观察对象与处理事件对象
observer.schedule(
fileHandler, file_name, True)
observer.start() try: while True:
time.sleep(2) except KeyboardInterrupt:
observer.stop()
observer.join()if __name__ == '__main__':
fd = pyFatigueDriving.fatigueDriving()
modelPath = "./models/yolov3_ir"
useIntelGPU = False
ret = fd.Init(modelPath, useIntelGPU) try: # 识别线程
savepath="./screenshots/"
getDetect = threading.Thread(target=run_detection_win_py, args=(savepath, ))
getDetect.start() # 警示线程
file_name="C:/project/FatigueDriving/screenshots"
getWarning = threading.Thread(target=run_scan_file, args=(file_name, ))
getWarning.start() except Exception as e: print("多线程异常,异常信息:{}".format(e))import osimport _threadimport sysimport timeimport threadingimport cv2import numpy as npimport pygamefrom PyQt5 import QtWidgetsfrom PyQt5.QtWidgets import QApplication, QDialog, QMainWindowfrom watchdog.events import *from watchdog.observers import Observerfrom MySQL_Connect import MySQL_Connect# 执行预测-raspi端def run_detection_raspi(sh_name):
subprocess.run(sh_name, shell=True)# 转换为可存储到数据库的格式def save_received_info(user_info, iolations_time, new_filename):
user_all_info = {}
user_all_info['编号'] = user_info[0]
user_all_info['姓名'] = user_info[1]
user_all_info['性别'] = user_info[2]
user_all_info['年龄'] = user_info[3]
user_all_info['身份证号'] = user_info[4]
user_all_info['联系电话'] = user_info[5]
user_all_info['省份'] = user_info[6]
user_all_info['城市'] = user_info[7]
user_all_info['区/县'] = user_info[8]
user_all_info['车型'] = user_info[9]
user_all_info['行驶证编号'] = user_info[10]
user_all_info['车牌号'] = user_info[11]
user_all_info['违规时间'] = iolations_time
user_all_info['违规证据图像位置'] = new_filename print(user_all_info) return user_all_info# 信息记录至SQLdef ToSQL(a, module_name):
# 初始化SQL
MySQL = MySQL_Connect() # 拉取用户数据
number = module_name[1:13]
iolations_time = module_name[13:17]+'-'+module_name[17:19] + '-'+module_name[19:21]+' '+module_name[21:23]+':'+module_name[23:25]
user_info = MySQL.MC_SELECT_User_Info(local_info=number)[0] # 生成数据列表
user_list_violation_info = save_received_info(
user_info, iolations_time, a)
MySQL.MC_Save_Violation_Info(user_list_violation_info)# 播放警示音频class Play_Audio():
def __init__(self, audio):
self.audio = audio def run(self):
pygame.mixer.init()
pygame.mixer.music.load(self.audio) # './audio/warning.mp3'
pygame.mixer.music.play()
time.sleep(3)
pygame.mixer.music.stop()class MyDirEventHandler(FileSystemEventHandler):
def __init__(self):
FileSystemEventHandler.__init__(self)
self.audio = './audio/warning.mp3'
self.warning = Play_Audio(self.audio) def on_created(self, event):
print("file created:{0}".format(event.src_path))
a = str(event.src_path) #
self.warning.run(self.audio)
directory, module_name = os.path.split(a)
module_name = os.path.splitext(module_name)[0]
ToSQL(a, module_name)# 监控文件的变化def run_scan_file(file_name):
# 创建观察者对象
observer = Observer() # 创建事件处理对象
fileHandler = MyDirEventHandler() # 为观察者设置观察对象与处理事件对象
observer.schedule(
fileHandler, file_name, True)
observer.start() try: while True:
time.sleep(2) except KeyboardInterrupt:
observer.stop()
observer.join()"""
多线程
run_detection 执行预测程序
run_scan_file 监控文件的变化
"""if __name__ == '__main__': try: # 识别线程
command='./real_time.sh'
getDetect = threading.Thread(target=run_detection_raspi, args=(command, ))
getDetect.start() # 警示线程
file_name="C:/project/FatigueDriving/screenshots"
getWarning = threading.Thread(target=run_scan_file, args=(file_name, ))
getWarning.start() except Exception as e: print("多线程异常,异常信息:{}".format(e))class MySQL_Connect():
def __init__(self):
self.write_jud_user_info = 1
self.write_user_info = "insert into `user_info` values("
self.write_jud_violation_info = 1
self.write_violation_info = "insert into `violation_info` values("
# 加载数据库
try:
self._con = sql.Connect(
host="localhost",
user="root",
password="yours",
database="yours",
port=<yoursport>,
charset='utf8'
) except Exception as e: print("ERROR: " + e)
self._con.close() #pass
# 编号判断
def MC_Number_Judge(self, number):
if len(number) != 12: return False
else: return True
# 性别判断
def MC_Sex_Judge(self, sex):
if sex != '男' and sex != '女': return False
else: return True
# 身份证判断
def MC_Id_Card_Judge(self, id):
if len(id) != 18: return False
else: return True
# 电话号判断
def MC_Phone_Judge(self, tel):
if len(tel) != 11: return False
else: return True
# 行驶证编号判断
def MC_Driver_Licenise_Number_Judge(self, num):
if len(num) != 12: return False
else: return True
# 车牌号判断
def MC_Licenise_Number_Judge(self, num):
if len(num) != 7: return False
else: return True
'''----------------------- 用户信息 -----------------------'''
# 写入用户信息
def MC_Save_User_Info(self, list_user_info):
self.list_user_info = list_user_info
cursor = self._con.cursor() if self.MC_Number_Judge(self.list_user_info['编号']):
self.MC_Insert_User_Info(self.list_user_info['编号'])
self.MC_Insert_User_Info(self.list_user_info['姓名']) if self.MC_Sex_Judge(self.list_user_info['性别']):
self.MC_Insert_User_Info(self.list_user_info['性别'])
self.MC_Insert_User_Info(self.list_user_info['年龄']) if self.MC_Id_Card_Judge(self.list_user_info['身份证号']):
self.MC_Insert_User_Info(self.list_user_info['身份证号']) if self.MC_Phone_Judge(self.list_user_info['联系电话']):
self.MC_Insert_User_Info(self.list_user_info['联系电话'])
self.MC_Insert_User_Info(self.list_user_info['省份'])
self.MC_Insert_User_Info(self.list_user_info['城市'])
self.MC_Insert_User_Info(self.list_user_info['区/县'])
self.MC_Insert_User_Info(self.list_user_info['车型']) if self.MC_Driver_Licenise_Number_Judge(self.list_user_info['行驶证编号']):
self.MC_Insert_User_Info(self.list_user_info['行驶证编号']) if self.MC_Licenise_Number_Judge(self.list_user_info['车牌号']):
self.MC_Insert_User_Info(self.list_user_info['车牌号'])
self.write_user_info += ")"
print(self.write_user_info)
cursor.execute(self.write_user_info)
self._con.commit()
cursor.close()
self.list_user_info.clear() # 读取数据库信息
def MC_Read_User_Info(self):
try: # 创建游标对象
cursor = self._con.cursor()
sql = 'SELECT * FROM `user_info`'
cursor.execute(sql)
result = cursor.fetchall()
cursor.close() except Exception as e: print("ERROR: " + e)
self._con.rollback()
cursor.close() return result # 数据库语言 数据插入
def MC_Insert_User_Info(self, new):
if self.write_jud_user_info != 1:
self.write_user_info += ", "
self.write_user_info += "'" + new + "'"
self.write_jud_user_info += 1
# 根据单个变量查询
def MC_SELECT_User_Info(self, local_info):
#self.local_info = '434343434343'
self.local_info = local_info try: # 创建游标对象
cursor = self._con.cursor()
sql = "SELECT * FROM `user_info` WHERE number=%s" % self.local_info
cursor.execute(sql)
result = cursor.fetchall()
cursor.close() except Exception as e: print("ERROR: " + e)
self._con.rollback()
cursor.close() return result '''----------------------- 违规记录 -----------------------'''
# 写入违规记录
def MC_Save_Violation_Info(self, list_violation_info):
self.list_violation_info = list_violation_info
cursor = self._con.cursor() if self.MC_Number_Judge(self.list_violation_info['编号']):
self.MC_Insert_Violation_Info(self.list_violation_info['编号'])
self.MC_Insert_Violation_Info(self.list_violation_info['姓名']) if self.MC_Sex_Judge(self.list_violation_info['性别']):
self.MC_Insert_Violation_Info(self.list_violation_info['性别'])
self.MC_Insert_Violation_Info(self.list_violation_info['年龄']) if self.MC_Id_Card_Judge(self.list_violation_info['身份证号']):
self.MC_Insert_Violation_Info(self.list_violation_info['身份证号']) if self.MC_Phone_Judge(self.list_violation_info['联系电话']):
self.MC_Insert_Violation_Info(self.list_violation_info['联系电话'])
self.MC_Insert_Violation_Info(self.list_violation_info['省份'])
self.MC_Insert_Violation_Info(self.list_violation_info['城市'])
self.MC_Insert_Violation_Info(self.list_violation_info['区/县'])
self.MC_Insert_Violation_Info(self.list_violation_info['车型']) if self.MC_Driver_Licenise_Number_Judge(self.list_violation_info['行驶证编号']):
self.MC_Insert_Violation_Info(self.list_violation_info['行驶证编号']) if self.MC_Licenise_Number_Judge(self.list_violation_info['车牌号']):
self.MC_Insert_Violation_Info(self.list_violation_info['车牌号'])
self.MC_Insert_Violation_Info(self.list_violation_info['违规时间'])
self.MC_Insert_Violation_Info(self.list_violation_info['违规证据图像位置'])
self.write_violation_info += ")"
print(self.write_violation_info)
cursor.execute(self.write_violation_info)
self._con.commit()
cursor.close()
self.list_violation_info.clear() # 读取数据库信息
def MC_Read_Violation_Info(self):
try: # 创建游标对象
cursor = self._con.cursor()
sql = 'SELECT * FROM `violation_info`'
cursor.execute(sql)
result = cursor.fetchall()
cursor.close() except Exception as e: print("ERROR: " + e)
self._con.rollback()
cursor.close() return result # 数据库语言 信息插入
def MC_Insert_Violation_Info(self, new):
if self.write_jud_violation_info != 1:
self.write_violation_info += ", "
self.write_violation_info += "'" + new + "'"
self.write_jud_violation_info += 1# 子窗口 -- 信息录入class Ui_Info_Entry_Child(Ui_Info_Entry):
"""docstring for Ui_Info_Entry_Child"""
def __init__(self):
super(Ui_Info_Entry_Child, self).__init__()
self.setupUi(self)# 子窗口 -- 违规信息可视化class Ui_EvidenceIm_Child(Ui_EvidenceIm):
"""docstring for Ui_EvidenceIm_Child"""
def __init__(self, impath, oneinfo):
super(Ui_EvidenceIm_Child, self).__init__(impath,oneinfo)
self.setupUi(self)
self.impath = impath
self.oneinfo = oneinfo# 主窗口 -- 数据库信息可视化class Ui_MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(Ui_MainWindow, self).__init__() #self.line = 5
self.row_num = 1
self.MainWindow = QtWidgets.QMainWindow()
self.Info_Entry_Windows = Ui_Info_Entry_Child()
self.setupUi(self.MainWindow) def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1455, 969)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget") # 省份
self.server_label_province = QtWidgets.QLabel(self.centralwidget)
self.server_label_province.setGeometry(QtCore.QRect(0, 10, 51, 21))
self.server_label_province.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.server_label_province.setObjectName("server_label_province")
self.server_province = QtWidgets.QComboBox(self.centralwidget)
self.server_province.setGeometry(QtCore.QRect(60, 10, 111, 22))
self.server_province.setObjectName("server_province") # 市/州
self.server_label_city = QtWidgets.QLabel(self.centralwidget)
self.server_label_city.setGeometry(QtCore.QRect(190, 10, 51, 21))
self.server_label_city.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.server_label_city.setObjectName("server_label_city")
self.server_city = QtWidgets.QComboBox(self.centralwidget)
self.server_city.setGeometry(QtCore.QRect(250, 10, 111, 22))
self.server_city.setObjectName("server_city") # 区县
self.server_label_borough = QtWidgets.QLabel(self.centralwidget)
self.server_label_borough.setGeometry(QtCore.QRect(380, 10, 51, 21))
self.server_label_borough.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.server_label_borough.setObjectName("server_label_borough")
self.server_borough = QtWidgets.QComboBox(self.centralwidget)
self.server_borough.setGeometry(QtCore.QRect(440, 10, 111, 22))
self.server_borough.setObjectName("server_borough") # 导入
self.pushButton_import = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_import.setGeometry(QtCore.QRect(590, 10, 111, 23))
self.pushButton_import.setObjectName("pushButton_import") # 更新
self.pushButton_update = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_update.setGeometry(QtCore.QRect(740, 10, 111, 23))
self.pushButton_update.setObjectName("pushButton_update") # 信息录入
self.pushButton_info_entry = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_info_entry.setGeometry(QtCore.QRect(1300, 10, 111, 23))
self.pushButton_info_entry.setObjectName("pushButton_info_entry") # 数据表格
self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
self.tableWidget.setEditTriggers(
QtWidgets.QAbstractItemView.NoEditTriggers) # self.tableWidget.setSelectionBehavior(
# QtWidgets.QAbstractItemView.SelectRows)
self.tableWidget.setGeometry(QtCore.QRect(10, 50, 1435, 901))
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(14)
self.tableWidget.setRowCount(self.row_num)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setVerticalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(1, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(2, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(3, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(4, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(5, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(6, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(7, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(8, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(9, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(10, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(11, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(12, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(13, item)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow) # 初始化省份数据
self.server_province.clear()
self.server_province.addItem('请选择') for key, value in dictPorovince.items():
self.server_province.addItem(value, QVariant(key)) # 按扭框被点击事件信号
self.server_province.activated.connect(self.add_city)
self.server_city.activated.connect(self.add_borough)
self.server_borough.activated.connect(self.just_btn_enable)
self.pushButton_import.clicked.connect(self.import_ok)
self.pushButton_update.clicked.connect(self.import_ok)
self.pushButton_info_entry.clicked.connect(self.show_info_entry_windows)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "疲劳驾驶监测数据终端平台"))
self.server_label_province.setText(_translate("MainWindow", "省份"))
self.server_label_city.setText(_translate("MainWindow", "市/州"))
self.server_label_borough.setText(_translate("MainWindow", "区/县"))
self.pushButton_import.setText(_translate("MainWindow", "导出"))
self.pushButton_update.setText(_translate("MainWindow", "刷新"))
self.pushButton_info_entry.setText(_translate("MainWindow", "信息录入"))
item = self.tableWidget.verticalHeaderItem(0)
item.setText(_translate("MainWindow", "1"))
item = self.tableWidget.horizontalHeaderItem(0)
item.setText(_translate("MainWindow", "编号"))
item = self.tableWidget.horizontalHeaderItem(1)
item.setText(_translate("MainWindow", "姓名"))
item = self.tableWidget.horizontalHeaderItem(2)
item.setText(_translate("MainWindow", "性别"))
item = self.tableWidget.horizontalHeaderItem(3)
item.setText(_translate("MainWindow", "年龄"))
item = self.tableWidget.horizontalHeaderItem(4)
item.setText(_translate("MainWindow", "身份证号"))
item = self.tableWidget.horizontalHeaderItem(5)
item.setText(_translate("MainWindow", "联系电话"))
item = self.tableWidget.horizontalHeaderItem(6)
item.setText(_translate("MainWindow", "省份"))
item = self.tableWidget.horizontalHeaderItem(7)
item.setText(_translate("MainWindow", "市/州"))
item = self.tableWidget.horizontalHeaderItem(8)
item.setText(_translate("MainWindow", "区/县"))
item = self.tableWidget.horizontalHeaderItem(9)
item.setText(_translate("MainWindow", "车型"))
item = self.tableWidget.horizontalHeaderItem(10)
item.setText(_translate("MainWindow", "行驶证编号"))
item = self.tableWidget.horizontalHeaderItem(11)
item.setText(_translate("MainWindow", "车牌号"))
item = self.tableWidget.horizontalHeaderItem(12)
item.setText(_translate("MainWindow", "违规时间"))
item = self.tableWidget.horizontalHeaderItem(13)
item.setText(_translate("MainWindow", "操作")) # 当省份按钮被选择后添加对应的城市数据
def add_city(self, index):
pro_code = self.server_province.itemData(index)
city_data = dictCity.get(pro_code, dict())
self.server_city.clear()
self.server_city.addItem('请选择')
self.server_borough.clear()
self.server_borough.addItem('请选择') if self.server_province.currentText() != '请选择': for key, value in city_data.items():
self.server_city.addItem(value, QVariant(key))
self.pushButton_import.setDisabled(True) # 当城市按钮被选择后添加对应的区县数据
def add_borough(self, index):
city_code = self.server_city.itemData(index)
borough_data = dicBorough.get(city_code, dict())
self.server_borough.clear()
self.server_borough.addItem('请选择') if self.server_city.currentText() != '请选择': for key, value in borough_data.items():
self.server_borough.addItem(value, QVariant(key))
self.pushButton_import.setDisabled(True) # 导出按钮是否可用
def just_btn_enable(self, txt):
if self.server_borough.currentText() != '请选择':
self.pushButton_import.setDisabled(False) else:
self.pushButton_import.setDisabled(True) # 根据省市县筛选信息导出
def import_ok(self):
if self.server_province.currentText() == '请选择':
QtWidgets.QMessageBox.warning(self, "警告", "请选择省/市/县信息", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) else:
self.MySQL_Read = MySQL_Connect()
self.info_all = self.MySQL_Read.MC_Read_Violation_Info() # 根据省市县筛选得到的信息存放
self.info_realdata = [] # 提取筛选后的各数据对应图片地址
self.info_realimpath = [] # 按钮名称
self.btn_realname = [] # 遍历提取相应数据
for i in range(len(self.info_all)): if self.info_all[i][6] == self.server_province.currentText() and self.info_all[i][7] == self.server_city.currentText() and self.info_all[i][8] == self.server_borough.currentText():
self.info_realdata.append(list(self.info_all[i]))
self.info_realimpath.append(str(self.info_all[i][-1]))
self.btn_realname.append(str('详情:'+self.info_all[i][1]+' - '+self.info_all[i][-2]))
self.pushbutton_list() for m in range(len(self.info_realdata)): # m行 n列
for n in range(14):
item = QtWidgets.QTableWidgetItem(str(self.info_realdata[m][n]))
self.tableWidget.setItem(m, n, item) # 创建详情按钮
def pushbutton_list(self):
self.tableWidget.setRowCount(len(self.info_realdata)) for n in range(len(self.info_realdata)):
self.btn = QtWidgets.QPushButton()
self.btn.setDown(True)
self.btn.setStyleSheet('QPushButton{margin:3px}'
'QPushButton{padding:1px 1px}')
self.tableWidget.setCellWidget(n, 13, self.btn) #此处将字传入按钮
self.btn.setText(self.btn_realname[n]) #传达参数,这里sender将接收你点击的字并传入函数
self.btn.clicked.connect( lambda: self.btn_clicked(self.btn_realname.index(self.sender().text()))) # 显示子页面 -- 信息录入
def show_info_entry_windows(self):
self.Info_Entry_Windows.show() # 显示子页面 -- 证据图像
def btn_clicked(self,n):
#self.nn = list.index(self.line[self.n])
self.impath = self.info_realimpath[n]
self.oneinfo = self.btn_realname[n]
self.EvidenceIm_Windows = Ui_EvidenceIm_Child(
self.impath, self.oneinfo)
self.EvidenceIm_Windows.show()# 重写QtWidgets.QMainWindow类关闭事件class MainWindow(QtWidgets.QMainWindow):
def closeEvent(self, event): # 关闭窗口触发以下事件
reply = QtWidgets.QMessageBox.question(
self, '本程序', '你确定要退出吗?', QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) if reply == QtWidgets.QMessageBox.Yes:
event.accept() # 接受关闭事件
else:
event.ignore() # 忽略关闭事件class Ui_Info_Entry(QtWidgets.QMainWindow):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(432, 532)
Form.setFixedSize(432, 532) # 分隔线0
self.line_0 = QtWidgets.QLabel(Form)
self.line_0.setGeometry(QtCore.QRect(30, 40, 371, 16))
self.line_0.setObjectName("line_0") # 分隔线1
self.line_1 = QtWidgets.QLabel(Form)
self.line_1.setGeometry(QtCore.QRect(30, 210, 371, 16))
self.line_1.setObjectName("line_1") # 分隔线2
self.line_2 = QtWidgets.QLabel(Form)
self.line_2.setGeometry(QtCore.QRect(30, 340, 371, 16))
self.line_2.setObjectName("line_2") # 基本信息
self.essential_information = QtWidgets.QLabel(Form)
self.essential_information.setGeometry(QtCore.QRect(30, 20, 61, 16))
self.essential_information.setObjectName("essential_information") # 地址信息
self.address_information = QtWidgets.QLabel(Form)
self.address_information.setGeometry(QtCore.QRect(30, 190, 54, 12))
self.address_information.setObjectName("address_information") # 车辆信息
self.vehicle_information = QtWidgets.QLabel(Form)
self.vehicle_information.setGeometry(QtCore.QRect(30, 320, 54, 12))
self.vehicle_information.setObjectName("vehicle_information") # 省份
self.label_province = QtWidgets.QLabel(Form)
self.label_province.setGeometry(QtCore.QRect(40, 230, 51, 21))
self.label_province.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.label_province.setObjectName("label_province")
self.province = QtWidgets.QComboBox(Form)
self.province.setGeometry(QtCore.QRect(90, 230, 111, 22))
self.province.setObjectName("province")
self.province.addItem("") # 市/州
self.label_city = QtWidgets.QLabel(Form)
self.label_city.setGeometry(QtCore.QRect(230, 230, 51, 21))
self.label_city.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.label_city.setObjectName("label_city")
self.city = QtWidgets.QComboBox(Form)
self.city.setGeometry(QtCore.QRect(280, 230, 111, 22))
self.city.setObjectName("city")
self.city.addItem("") # 区/县
self.label_borough = QtWidgets.QLabel(Form)
self.label_borough.setGeometry(QtCore.QRect(40, 280, 51, 21))
self.label_borough.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.label_borough.setObjectName("label_borough")
self.borough = QtWidgets.QComboBox(Form)
self.borough.setGeometry(QtCore.QRect(90, 280, 111, 22))
self.borough.setObjectName("borough")
self.borough.addItem("") # 编号
self.number = QtWidgets.QLabel(Form)
self.number.setGeometry(QtCore.QRect(40, 60, 51, 21))
self.number.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.number.setObjectName("number")
self.lineEdit_00 = QtWidgets.QLineEdit(Form)
self.lineEdit_00.setGeometry(QtCore.QRect(90, 60, 111, 20))
self.lineEdit_00.setText("")
self.lineEdit_00.setObjectName("lineEdit_00") # 姓名
self.name = QtWidgets.QLabel(Form)
self.name.setGeometry(QtCore.QRect(230, 60, 51, 21))
self.name.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.name.setObjectName("name")
self.lineEdit_01 = QtWidgets.QLineEdit(Form)
self.lineEdit_01.setGeometry(QtCore.QRect(280, 60, 111, 20))
self.lineEdit_01.setText("")
self.lineEdit_01.setObjectName("lineEdit_01") # 性别
self.sex = QtWidgets.QLabel(Form)
self.sex.setGeometry(QtCore.QRect(40, 110, 51, 21))
self.sex.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.sex.setObjectName("sex")
self.lineEdit_10 = QtWidgets.QLineEdit(Form)
self.lineEdit_10.setGeometry(QtCore.QRect(90, 110, 111, 20))
self.lineEdit_10.setText("")
self.lineEdit_10.setObjectName("lineEdit_10") # 年龄
self.age = QtWidgets.QLabel(Form)
self.age.setGeometry(QtCore.QRect(230, 110, 51, 21))
self.age.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.age.setObjectName("age")
self.lineEdit_11 = QtWidgets.QLineEdit(Form)
self.lineEdit_11.setGeometry(QtCore.QRect(280, 110, 111, 20))
self.lineEdit_11.setText("")
self.lineEdit_11.setObjectName("lineEdit_11") # 身份证号
self.id_number = QtWidgets.QLabel(Form)
self.id_number.setGeometry(QtCore.QRect(30, 150, 61, 21))
self.id_number.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.id_number.setObjectName("id_number")
self.lineEdit_20 = QtWidgets.QLineEdit(Form)
self.lineEdit_20.setGeometry(QtCore.QRect(90, 150, 111, 20))
self.lineEdit_20.setText("")
self.lineEdit_20.setObjectName("lineEdit_20") # 联系电话
self.contact_number = QtWidgets.QLabel(Form)
self.contact_number.setGeometry(QtCore.QRect(220, 150, 61, 21))
self.contact_number.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.contact_number.setObjectName("contact_number")
self.lineEdit_21 = QtWidgets.QLineEdit(Form)
self.lineEdit_21.setGeometry(QtCore.QRect(280, 150, 111, 20))
self.lineEdit_21.setText("")
self.lineEdit_21.setObjectName("lineEdit_21") # 车型
self.model = QtWidgets.QLabel(Form)
self.model.setGeometry(QtCore.QRect(40, 360, 51, 21))
self.model.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.model.setObjectName("model")
self.lineEdit_30 = QtWidgets.QLineEdit(Form)
self.lineEdit_30.setGeometry(QtCore.QRect(90, 360, 111, 20))
self.lineEdit_30.setText("")
self.lineEdit_30.setObjectName("lineEdit_30") # 驾驶证编号
self.driver_license_number = QtWidgets.QLabel(Form)
self.driver_license_number.setGeometry(QtCore.QRect(200, 360, 81, 21))
self.driver_license_number.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.driver_license_number.setObjectName("driver_license_number")
self.lineEdit_31 = QtWidgets.QLineEdit(Form)
self.lineEdit_31.setGeometry(QtCore.QRect(280, 360, 111, 20))
self.lineEdit_31.setText("")
self.lineEdit_31.setObjectName("lineEdit_31") # 车牌号
self.license_number = QtWidgets.QLabel(Form)
self.license_number.setGeometry(QtCore.QRect(40, 400, 51, 21))
self.license_number.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.license_number.setObjectName("license_number")
self.lineEdit_40 = QtWidgets.QLineEdit(Form)
self.lineEdit_40.setGeometry(QtCore.QRect(90, 400, 111, 20))
self.lineEdit_40.setText("")
self.lineEdit_40.setObjectName("lineEdit_40") # 保存
self.info_entry = QtWidgets.QPushButton(Form)
self.info_entry.setGeometry(QtCore.QRect(90, 450, 75, 23))
self.info_entry.setObjectName("info_entry") # 取消
self.cancel = QtWidgets.QPushButton(Form)
self.cancel.setGeometry(QtCore.QRect(260, 450, 75, 23))
self.cancel.setObjectName("cancel") # 中心窗口
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form) # 初始化省份数据
self.province.clear()
self.province.addItem('请选择') for key, value in dictPorovince.items():
self.province.addItem(value, QVariant(key)) # 按扭框被点击事件信号
self.province.activated.connect(self.add_city)
self.city.activated.connect(self.add_borough)
self.borough.activated.connect(self.just_btn_enable)
self.info_entry.clicked.connect(self.save_sql_ok)
self.cancel.clicked.connect(self.close) def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "个人信息登记")) # 基本信息
self.essential_information.setText(_translate("Form", "<html><head/><body><p>基本信息<span style=" color:#ff0000;">*</span></p></body></html>"))
self.line_0.setText(_translate("Form", "--------------------------------------------------------------------"))
self.number.setText(_translate("Form", "编号:"))
self.name.setText(_translate("Form", "姓名:"))
self.sex.setText(_translate("Form", "性别:"))
self.age.setText(_translate("Form", "年龄:"))
self.id_number.setText(_translate("Form", "身份证号:"))
self.contact_number.setText(_translate("Form", "联系电话:")) # 地址信息
self.address_information.setText(_translate("Form", "<html><head/><body><p>地址信息<span style=" color:#ff0000;">*</span></p></body></html>"))
self.line_1.setText(_translate("Form", "--------------------------------------------------------------------"))
self.label_province.setText(_translate("Form", "省份:"))
self.province.setItemText(0, _translate("Form", "请选择"))
self.label_city.setText(_translate("Form", "城市:"))
self.city.setItemText(0, _translate("Form", "请选择"))
self.label_borough.setText(_translate("Form", "区/县:"))
self.borough.setItemText(0, _translate("Form", "请选择")) # 车辆信息
self.vehicle_information.setText(_translate("Form", "<html><head/><body><p>车辆信息<span style=" color:#ff0000;">*</span></p></body></html>"))
self.line_2.setText(_translate("Form", "--------------------------------------------------------------------"))
self.model.setText(_translate("Form", "车型:"))
self.driver_license_number.setText(_translate("Form", "行驶证编号:"))
self.license_number.setText(_translate("Form", "车牌号:")) # 按钮
self.cancel.setText(_translate("Form", "取消"))
self.info_entry.setText(_translate("Form", "录入")) # 当省份按钮被选择后添加对应的城市数据
def add_city(self, index):
pro_code = self.province.itemData(index)
city_data = dictCity.get(pro_code, dict())
self.city.clear()
self.city.addItem('请选择')
self.borough.clear()
self.borough.addItem('请选择') if self.province.currentText() != '请选择': for key, value in city_data.items():
self.city.addItem(value, QVariant(key))
self.info_entry.setDisabled(True) # 当城市按钮被选择后添加对应的区县数据
def add_borough(self, index):
city_code = self.city.itemData(index)
borough_data = dicBorough.get(city_code, dict())
self.borough.clear()
self.borough.addItem('请选择') if self.city.currentText() != '请选择': for key, value in borough_data.items():
self.borough.addItem(value, QVariant(key))
self.info_entry.setDisabled(True) # 导出按钮是否可用
def just_btn_enable(self, txt):
if self.borough.currentText() != '请选择':
self.info_entry.setDisabled(False) else:
self.info_entry.setDisabled(True) # 清空信息
def clear(self):
self.lineEdit_00.clear()
self.lineEdit_01.clear()
self.lineEdit_10.clear()
self.lineEdit_11.clear()
self.lineEdit_20.clear()
self.lineEdit_21.clear()
self.province.clear()
self.province.addItem('请选择')
self.city.clear()
self.city.addItem('请选择')
self.borough.clear()
self.borough.addItem('请选择')
self.lineEdit_30.clear()
self.lineEdit_31.clear()
self.lineEdit_40.clear() # 初始化省按钮信息
for key, value in dictPorovince.items():
self.province.addItem(value, QVariant(key)) # 点击保存后,信息确认
def save_sql_ok(self):
self.all_info = {}
self.all_info['编号'] = self.lineEdit_00.text()
self.all_info['姓名'] = self.lineEdit_01.text()
self.all_info['性别'] = self.lineEdit_10.text()
self.all_info['年龄'] = self.lineEdit_11.text()
self.all_info['身份证号'] = self.lineEdit_20.text()
self.all_info['联系电话'] = self.lineEdit_21.text()
self.all_info['省份'] = self.province.currentText()
self.all_info['城市'] = self.city.currentText()
self.all_info['区/县'] = self.borough.currentText()
self.all_info['车型'] = self.lineEdit_30.text()
self.all_info['行驶证编号'] = self.lineEdit_31.text()
self.all_info['车牌号'] = self.lineEdit_40.text() print(self.all_info)
self.MySQL_Save = MySQL_Connect()
self.MySQL_Save.MC_Save_User_Info(list_user_info=self.all_info)
QMessageBox.information(self, "请确认信息", '''您的编号:{}
姓名:{}
性别:{}
年龄:{}
身份证号:{}
联系电话:{}
省份:{}
城市:{}
区县:{}
车型:{}
行驶证编号:{}
车牌号:{}'''.format(self.lineEdit_00.text(),
self.lineEdit_01.text(),
self.lineEdit_10.text(),
self.lineEdit_11.text(),
self.lineEdit_20.text(),
self.lineEdit_21.text(),
self.province.currentText(),
self.city.currentText(),
self.borough.currentText(),
self.lineEdit_30.text(),
self.lineEdit_31.text(),
self.lineEdit_40.text()),
QMessageBox.Yes | QMessageBox.No)
self.clear()class Ui_EvidenceIm(QtWidgets.QMainWindow):
def __init__(self,impath,oneinfo):
super(Ui_EvidenceIm, self).__init__()
self.impath = impath
self.oneinfo = oneinfo def setupUi(self, Form):
Form.setObjectName(self.oneinfo)
Form.resize(979, 584)
Form.setFixedSize(979, 584)
self.evidence_im_view = GraphicsView(Form)
self.evidence_im_view.setGeometry(QtCore.QRect(10, 40, 960, 540))
self.evidence_im_view.setObjectName("evidence_im_view")
self.evidence_im_label = QtWidgets.QLabel(Form)
self.evidence_im_label.setGeometry(QtCore.QRect(10, 10, 971, 21))
self.evidence_im_label.setObjectName("evidence_im_label")
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form) try: # 显示图片
#img = cv_imread()
img = cv2.imdecode(np.fromfile(self.impath, dtype=np.uint8), -1)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB, img)
x = img.shape[1] # 获取图像宽度
y = img.shape[0] # 获取图像高度
frame = QtGui.QImage(img.data, x, y, x*3, QtGui.QImage.Format_RGB888)
pix = QtGui.QPixmap.fromImage(frame)
self.item = QtWidgets.QGraphicsPixmapItem(pix) # 创建像素图元
self.scene = QtWidgets.QGraphicsScene() # 创建场景
self.scene.clear()
self.scene.addItem(self.item)
self.scene.update()
self.evidence_im_view.setScene(self.scene) # 将场景添加至视图
except: pass
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", self.oneinfo))
self.evidence_im_label.setText(_translate( "Form", "<html><head/><body><p>-------------------------------------------------- <span style=" font-size:12pt; font-weight:600; color:#000000;">图像证据</span> --------------------------------------------------</p></body></html>"))# 重写GraphicsView类 可拖动、放大、缩小图像class GraphicsView(QGraphicsView):
# 背景区域颜色
backgroundColor = QColor(255, 255, 255) def __init__(self, *args, **kwargs):
super(GraphicsView, self).__init__(*args, **kwargs)
self.resize(800, 600) # 设置背景颜色
self.setBackgroundBrush(self.backgroundColor)
self.setCacheMode(self.CacheBackground)
self.setDragMode(self.ScrollHandDrag)
self.setOptimizationFlag(self.DontSavePainterState)
self.setRenderHints(QPainter.Antialiasing | QPainter.TextAntialiasing |
QPainter.SmoothPixmapTransform) if QGLFormat.hasOpenGL():
self.setRenderHint(QPainter.HighQualityAntialiasing)
self.setResizeAnchor(self.AnchorUnderMouse)
self.setRubberBandSelectionMode(Qt.IntersectsItemShape)
self.setTransformationAnchor(self.AnchorUnderMouse)
self.setViewportUpdateMode(self.SmartViewportUpdate) # 设置场景(显示在屏幕中间)
self._scene = QGraphicsScene(-180, -90, 360, 180, self)
self.setScene(self._scene) def wheelEvent(self, event):
# 滑轮事件
if event.modifiers() & Qt.ControlModifier:
self.scaleView(math.pow(2.0, -event.angleDelta().y() / 240.0)) return event.accept() super(GraphicsView, self).wheelEvent(event) def scaleView(self, scaleFactor):
factor = self.transform().scale(
scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width() if factor < 0.07 or factor > 100: return
self.scale(scaleFactor, scaleFactor)以上就是基于PaddleDetection的疲劳驾驶检测系统的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号