PaddleOCR2.7+Qt5

章节一:Windows 下的 PIP 安装

        官网安装教程地址

        按照里面的教程去安装

         如果使用cuda版本的还要安装tensorrt,不然后面运行demo程序的程序会报如下错。

        下载TensorRT 8版本,tensorrt下载地址

章节二:编译源码

        进入官网源码地址

        下载release2.7

        下载三个模型

        下载推理预测库

          官网下载地址,根据自己的情况下载CPU或对应的自己CUDA版本的GPU

用CMAK打开如下文件

    添加路径OpenCV路径和预测库路径。

图片

    然后Configers,再Generate,如果有报错不用管他,最后在你的构建目录生成了项目,然后开始编译。

        但是编译会报错

在utility.cpp中无法打开包括文件"dirent.h":No such file or directory

        <dirent.h>是个unix系统下常见的接口,但windows平台的MSVC编译器并没有提供这个接口,对于跨平台的项目开发就会带来一些麻烦,如果在MSVC下编译时可能因为windows平台缺少这个接口就要为windows平台另外写一些代码。

        不过大佬已经做了一个windows版本的<dirent.h>,放在了github上面,链接如下:

https://github.com/tronkko/dirent

        下载完后加入这个文件夹:

        然后重新编译,但是会报错找不到_stat,做如下修改就可以了。

//修改前struct stat s;_stat(dir_name, &s);
//修改后struct _stat64 s;_stat64(dir_name, &s);

        最后就可以生成成功,生成成功要将这几个dll复制到程序目录。

        onnxruntime和paddle2onnx在这里

        将这个文件复制到程序目录

        源码里面这个文件的路径也要改一下

        然后输入命令运行程序,下面的路径根据自己情况去修改

./ppocr.exe --det_model_dir=F:/Vision/PaddleOCR/2_7/model/ch_PP-OCRv4_det_infer --cls_model_dir=F:/Vision/PaddleOCR/2_7/model/ch_ppocr_mobile_v2.0_cls_infer --rec_model_dir=F:/Vision/PaddleOCR/2_7/model/ch_PP-OCRv4_rec_infer --image_dir=F:/Vision/PaddleOCR/2_7/PaddleOCR-release-2.7/deploy/cpp_infer/build/Release/aa.png

        运行结果如下

章节三:在Qt上编译运行

        pro文件构建

QT       += core gui widgetsgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++17DEFINES += QT_DEPRECATED_WARNINGS##################################################################
#指定生成的文件存放位置
##################################################################
MOC_DIR         = $$PWD/temp/moc
RCC_DIR         = $$PWD/temp/rcc
UI_DIR          = $$PWD/temp/ui
OBJECTS_DIR     = $$PWD/temp/obj
DESTDIR         = $$PWD/temp/binCONFIG(debug, debug|release) {QMAKE_CXXFLAGS_DEBUG += /MTd
}CONFIG(release, debug|release) {QMAKE_CXXFLAGS_RELEASE += /MT
}PaddleOCR_ROOT = F:/Vision/PaddleOCR/2_7/OCR_Demo/OCR_Demo/ocr
SOURCES += \
#    $$PaddleOCR_ROOT/src/args.cpp \$$PaddleOCR_ROOT/src/clipper.cpp \$$PaddleOCR_ROOT/src/ocr_cls.cpp \$$PaddleOCR_ROOT/src/ocr_det.cpp \$$PaddleOCR_ROOT/src/ocr_rec.cpp \
#    $$PaddleOCR_ROOT/src/paddleocr.cpp \
#    $$PaddleOCR_ROOT/src/paddlestructure.cpp \$$PaddleOCR_ROOT/src/postprocess_op.cpp \$$PaddleOCR_ROOT/src/preprocess_op.cpp \$$PaddleOCR_ROOT/src/structure_layout.cpp \$$PaddleOCR_ROOT/src/structure_table.cpp \$$PaddleOCR_ROOT/src/utility.cpp \ScreenWidget/screen.cpp \ScreenWidget/screenwidget.cpp \main.cpp \mainwindow.cpp \my_config.cpp \my_paddleocr.cppHEADERS += \$$PaddleOCR_ROOT/include/ocr_cls.h \$$PaddleOCR_ROOT/include/ocr_det.h \$$PaddleOCR_ROOT/include/ocr_rec.h \
#    $$PaddleOCR_ROOT/include/paddleocr.h \
#    $$PaddleOCR_ROOT/include/paddlestructure.h \$$PaddleOCR_ROOT/include/postprocess_op.h \$$PaddleOCR_ROOT/include/preprocess_op.h \$$PaddleOCR_ROOT/include/structure_layout.h \$$PaddleOCR_ROOT/include/structure_table.h \$$PaddleOCR_ROOT/include/utility.h \
#    $$PaddleOCR_ROOT/include/args.h \$$PaddleOCR_ROOT/include/clipper.h \$$PaddleOCR_ROOT/include/dirent.h \ScreenWidget/screen.h \ScreenWidget/screenwidget.h \mainwindow.h \my_config.h \my_paddleocr.hFORMS += \mainwindow.uiINCLUDEPATH += $$PaddleOCR_ROOT
INCLUDEPATH += $$PaddleOCR_ROOT/include
INCLUDEPATH += $$PWD\ScreenWidgetInference_ROOT = F:/Vision/PaddleOCR/2_7/prelib/cuda11_0
INCLUDEPATH += $$Inference_ROOT/paddle/include
INCLUDEPATH += $$Inference_ROOT/third_party/install/protobuf/include
INCLUDEPATH += $$Inference_ROOT/third_party/install/glog/include
#INCLUDEPATH += $$Inference_ROOT/third_party/install/gflags/include
INCLUDEPATH += $$Inference_ROOT/third_party/install/xxhash/include
INCLUDEPATH += $$Inference_ROOT/third_party/install/mklml/include
INCLUDEPATH += $$Inference_ROOT/third_party/install/mkldnn/includeLIBS += -L$$Inference_ROOT/paddle/lib -lpaddle_inference
LIBS += -L$$Inference_ROOT/third_party/install/mklml/lib -lmklml
LIBS += -L$$Inference_ROOT/third_party/install/mklml/lib -llibiomp5md
LIBS += -L$$Inference_ROOT/third_party/install/mkldnn/lib -lmkldnn
LIBS += -L$$Inference_ROOT/third_party/install/glog/lib -lglog
#LIBS += -L$$Inference_ROOT/third_party/install/gflags/lib -lgflags_static
LIBS += -L$$Inference_ROOT/third_party/install/protobuf/lib -llibprotobuf
LIBS += -L$$Inference_ROOT/third_party/install/xxhash/lib -lxxhashOpenCV_ROOT = E:/2021_software/OpenCv/OpenCv3_4_15/install/opencv/build
INCLUDEPATH += $$OpenCV_ROOT/include
INCLUDEPATH += $$OpenCV_ROOT/include/opencv
INCLUDEPATH += $$OpenCV_ROOT/include/opencv2
LIBS += -L$$OpenCV_ROOT/x64/vc15/lib -lopencv_world3415

        自定义一个config类

#pragma once#include <iomanip>
#include <iostream>
#include <map>
#include <ostream>
#include <string>
#include <vector>#include "include/utility.h"using namespace PaddleOCR;class MY_OCRConfig {
public:explicit MY_OCRConfig(const std::string &config_file);// common argsbool use_gpu = false;bool use_tensorrt = false;int gpu_id = 0;int gpu_mem = 4000;int cpu_threads = 10;bool enable_mkldnn = false;std::string precision = "fp32";bool benchmark = false;std::string output = "./output/";std::string image_dir = "";std::string type = "ocr";// detection relatedstd::string det_model_dir = "";std::string limit_type = "max";int limit_side_len = 960;double det_db_thresh = 0.3;double det_db_box_thresh = 0.6;double det_db_unclip_ratio = 1.5;bool use_dilation = false;std::string det_db_score_mode = "slow";bool visualize = true;// classification relatedbool use_angle_cls = false;std::string cls_model_dir = "";double cls_thresh = 0.9;int cls_batch_num = 1;// recognition relatedstd::string rec_model_dir = "";int rec_batch_num = 6;std::string rec_char_dict_path = "./ppocr_keys_v1.txt";int rec_img_h = 48;int rec_img_w = 320;// layout model relatedstd::string layout_model_dir = "";std::string layout_dict_path = "../../ppocr/utils/dict/layout_dict/layout_publaynet_dict.txt";double layout_score_threshold = 0.5;double layout_nms_threshold = 0.5;// structure model relatedstd::string table_model_dir = "";int table_max_len = 488;int table_batch_num = 1;bool merge_no_span_structure = true;std::string table_char_dict_path = "../../ppocr/utils/dict/table_structure_dict_ch.txt";// ocr forward relatedbool det = true;bool rec = true;bool cls = false;bool table = false;bool layout = false;private:// Load configurationstd::map<std::string, std::string> LoadConfig(const std::string &config_file);std::vector<std::string> split(const std::string &str,const std::string &delim);std::map<std::string, std::string> config_map_;
};#include "my_config.h"
#include <qdebug.h>std::vector<std::string> MY_OCRConfig::split(const std::string &str,const std::string &delim) {std::vector<std::string> res;if ("" == str)return res;int strlen = str.length() + 1;char *strs = new char[strlen];std::strcpy(strs, str.c_str());int delimlen = delim.length() + 1;char *d = new char[delimlen];std::strcpy(d, delim.c_str());char *p = std::strtok(strs, d);while (p) {std::string s = p;res.push_back(s);p = std::strtok(NULL, d);}delete[] strs;delete[] d;return res;
}std::map<std::string, std::string>
MY_OCRConfig::LoadConfig(const std::string &config_path) {auto config = Utility::ReadDict(config_path);std::map<std::string, std::string> dict;for (int i = 0; i < config.size(); i++) {// pass for empty line or commentif (config[i].size() <= 1 || config[i][0] == '#') {continue;}//std::vector<std::string> res = split(config[i], " ");if (res.size() < 2) {dict[res[0]] = "";}else{dict[res[0]] = res[1];}}return dict;
}MY_OCRConfig::MY_OCRConfig(const std::string &config_file)
{config_map_ = LoadConfig(config_file);// common argsthis->use_gpu        = (config_map_["use_gpu"] == "true");this->use_tensorrt   = (config_map_["use_tensorrt"] == "true");this->gpu_id         = stoi(config_map_["gpu_id"]);this->gpu_mem        = stoi(config_map_["gpu_mem"]);this->cpu_threads    = stoi(config_map_["cpu_threads"]);this->enable_mkldnn  = (config_map_["enable_mkldnn"] == "true");this->precision      = config_map_["precision"];this->benchmark      = (config_map_["benchmark"] == "true");this->output         = config_map_["output"];this->image_dir      = config_map_["image_dir"];this->type           = config_map_["type"];// detection relatedthis->det_model_dir       = config_map_["det_model_dir"];this->limit_type          = config_map_["limit_type"];this->limit_side_len      = stoi(config_map_["limit_side_len"]);this->det_db_thresh       = stod(config_map_["det_db_thresh"]);this->det_db_box_thresh   = stod(config_map_["det_db_box_thresh"]);this->det_db_unclip_ratio = stod(config_map_["det_db_unclip_ratio"]);this->use_dilation        = (config_map_["use_dilation"] == "true");this->det_db_score_mode   = config_map_["det_db_score_mode"];this->visualize           = (config_map_["visualize"] == "true");// classification relatedthis->use_angle_cls   = (config_map_["use_angle_cls"] == "true");this->cls_model_dir   = config_map_["cls_model_dir"];this->cls_thresh      = stod(config_map_["cls_thresh"]);this->cls_batch_num   = stoi(config_map_["cls_batch_num"]);// recognition relatedthis->rec_model_dir        = config_map_["rec_model_dir"];this->rec_batch_num        = stoi(config_map_["rec_batch_num"]);this->rec_char_dict_path   = config_map_["rec_char_dict_path"];this->rec_img_h            = stoi(config_map_["rec_img_h"]);this->rec_img_w            = stoi(config_map_["rec_img_w"]);// layout model relatedthis->layout_model_dir        = config_map_["layout_model_dir"];this->layout_dict_path        = config_map_["layout_dict_path"];this->layout_score_threshold  = stod(config_map_["layout_score_threshold"]);this->layout_nms_threshold    = stod(config_map_["layout_nms_threshold"]);// structure model relatedthis->table_model_dir           = config_map_["table_model_dir"];this->table_max_len             = stoi(config_map_["table_max_len"]);this->table_batch_num           = stoi(config_map_["table_batch_num"]);this->merge_no_span_structure   = (config_map_["merge_no_span_structure"] == "true");this->table_char_dict_path      = config_map_["table_char_dict_path"];// ocr forward relatedthis->det     = (config_map_["det"] == "true");this->rec     = (config_map_["rec"] == "true");this->cls     = (config_map_["cls"] == "true");this->table   = (config_map_["table"] == "true");this->layout  = (config_map_["layout"] == "true");qDebug()<<this->det<<config_map_["det"].c_str()<<QString(config_map_["det"].c_str())<<this->rec<<this->cls<<this->rec_model_dir.c_str();
}

        自定义一个ocr类

#pragma once#include <include/ocr_cls.h>
#include <include/ocr_det.h>
#include <include/ocr_rec.h>#include "my_config.h"using namespace PaddleOCR;
class MY_PPOCR {
public:explicit MY_PPOCR();~MY_PPOCR();std::vector<std::vector<OCRPredictResult>> ocr(std::vector<cv::Mat> img_list,bool det = true,bool rec = true,bool cls = true);std::vector<OCRPredictResult> ocr(cv::Mat img, bool det = true,bool rec = true, bool cls = true);void reset_timer();void benchmark_log(int img_num);MY_OCRConfig *p_config;
protected:std::vector<double> time_info_det = {0, 0, 0};std::vector<double> time_info_rec = {0, 0, 0};std::vector<double> time_info_cls = {0, 0, 0};void det(cv::Mat img, std::vector<OCRPredictResult> &ocr_results);void rec(std::vector<cv::Mat> img_list,std::vector<OCRPredictResult> &ocr_results);void cls(std::vector<cv::Mat> img_list,std::vector<OCRPredictResult> &ocr_results);private:std::unique_ptr<DBDetector> detector_;std::unique_ptr<Classifier> classifier_;std::unique_ptr<CRNNRecognizer> recognizer_;
};#include "my_paddleocr.h"
#include <qdebug.h>
//#include "auto_log/autolog.h"MY_PPOCR::MY_PPOCR()
{qDebug()<<"aaa1";p_config = new MY_OCRConfig("./ocrconfig.txt");qDebug()<<"aaa2";//if (p_config->det) {this->detector_.reset(new DBDetector(p_config->det_model_dir, p_config->use_gpu, p_config->gpu_id, p_config->gpu_mem,p_config->cpu_threads, p_config->enable_mkldnn, p_config->limit_type,p_config->limit_side_len, p_config->det_db_thresh, p_config->det_db_box_thresh,p_config->det_db_unclip_ratio, p_config->det_db_score_mode, p_config->use_dilation,p_config->use_tensorrt, p_config->precision));}qDebug()<<"aaa3";//if (p_config->cls && p_config->use_angle_cls) {this->classifier_.reset(new Classifier(p_config->cls_model_dir, p_config->use_gpu, p_config->gpu_id, p_config->gpu_mem,p_config->cpu_threads, p_config->enable_mkldnn, p_config->cls_thresh,p_config->use_tensorrt, p_config->precision, p_config->cls_batch_num));}qDebug()<<"aaa4";//if (p_config->rec) {this->recognizer_.reset(new CRNNRecognizer(p_config->rec_model_dir, p_config->use_gpu, p_config->gpu_id, p_config->gpu_mem,p_config->cpu_threads, p_config->enable_mkldnn, p_config->rec_char_dict_path,p_config->use_tensorrt, p_config->precision, p_config->rec_batch_num,p_config->rec_img_h, p_config->rec_img_w));}qDebug()<<"aaa5";
}MY_PPOCR::~MY_PPOCR()
{delete p_config;
}std::vector<std::vector<OCRPredictResult>>
MY_PPOCR::ocr(std::vector<cv::Mat> img_list, bool det, bool rec, bool cls)
{std::vector<std::vector<OCRPredictResult>> ocr_results;if (!det) {std::vector<OCRPredictResult> ocr_result;ocr_result.resize(img_list.size());if (cls && this->classifier_) {this->cls(img_list, ocr_result);for (int i = 0; i < img_list.size(); i++) {if (ocr_result[i].cls_label % 2 == 1 &&ocr_result[i].cls_score > this->classifier_->cls_thresh) {cv::rotate(img_list[i], img_list[i], 1);}}}if (rec) {this->rec(img_list, ocr_result);}for (int i = 0; i < ocr_result.size(); ++i) {std::vector<OCRPredictResult> ocr_result_tmp;ocr_result_tmp.push_back(ocr_result[i]);ocr_results.push_back(ocr_result_tmp);}} else {for (int i = 0; i < img_list.size(); ++i) {std::vector<OCRPredictResult> ocr_result =this->ocr(img_list[i], true, rec, cls);ocr_results.push_back(ocr_result);}}return ocr_results;
}std::vector<OCRPredictResult> MY_PPOCR::ocr(cv::Mat img, bool det, bool rec, bool cls)
{std::vector<OCRPredictResult> ocr_result;// detthis->det(img, ocr_result);// crop imagestd::vector<cv::Mat> img_list;for (int j = 0; j < ocr_result.size(); j++) {cv::Mat crop_img;crop_img = Utility::GetRotateCropImage(img, ocr_result[j].box);img_list.push_back(crop_img);}// clsif (cls && this->classifier_) {this->cls(img_list, ocr_result);for (int i = 0; i < img_list.size(); i++) {if (ocr_result[i].cls_label % 2 == 1 &&ocr_result[i].cls_score > this->classifier_->cls_thresh) {cv::rotate(img_list[i], img_list[i], 1);}}}// recif (rec) {this->rec(img_list, ocr_result);}return ocr_result;
}void MY_PPOCR::det(cv::Mat img, std::vector<OCRPredictResult> &ocr_results)
{std::vector<std::vector<std::vector<int>>> boxes;std::vector<double> det_times;this->detector_->Run(img, boxes, det_times);for (int i = 0; i < boxes.size(); i++) {OCRPredictResult res;res.box = boxes[i];ocr_results.push_back(res);}// sort boex from top to bottom, from left to rightUtility::sorted_boxes(ocr_results);this->time_info_det[0] += det_times[0];this->time_info_det[1] += det_times[1];this->time_info_det[2] += det_times[2];
}void MY_PPOCR::rec(std::vector<cv::Mat> img_list, std::vector<OCRPredictResult> &ocr_results)
{std::vector<std::string> rec_texts(img_list.size(), "");std::vector<float> rec_text_scores(img_list.size(), 0);std::vector<double> rec_times;this->recognizer_->Run(img_list, rec_texts, rec_text_scores, rec_times);// output rec resultsfor (int i = 0; i < rec_texts.size(); i++) {ocr_results[i].text = rec_texts[i];ocr_results[i].score = rec_text_scores[i];}this->time_info_rec[0] += rec_times[0];this->time_info_rec[1] += rec_times[1];this->time_info_rec[2] += rec_times[2];
}void MY_PPOCR::cls(std::vector<cv::Mat> img_list, std::vector<OCRPredictResult> &ocr_results)
{std::vector<int> cls_labels(img_list.size(), 0);std::vector<float> cls_scores(img_list.size(), 0);std::vector<double> cls_times;this->classifier_->Run(img_list, cls_labels, cls_scores, cls_times);// output cls resultsfor (int i = 0; i < cls_labels.size(); i++) {ocr_results[i].cls_label = cls_labels[i];ocr_results[i].cls_score = cls_scores[i];}this->time_info_cls[0] += cls_times[0];this->time_info_cls[1] += cls_times[1];this->time_info_cls[2] += cls_times[2];
}void MY_PPOCR::reset_timer()
{this->time_info_det = {0, 0, 0};this->time_info_rec = {0, 0, 0};this->time_info_cls = {0, 0, 0};
}

        核心调用代码

//std::vector<cv::Mat> img_list;cv::Mat srcimg = cv::imread(qstr2str(fileName).data(), cv::IMREAD_COLOR);img_list.push_back(srcimg);p_ocr->reset_timer();//QElapsedTimer  RunTimer;RunTimer.start();std::vector<std::vector<OCRPredictResult>> ocr_results = p_ocr->ocr(img_list, p_ocr->p_config->det, p_ocr->p_config->rec, p_ocr->p_config->cls);ui->textBrowser->append(QString("检测时间:%1ms ---------------------").arg(RunTimer.elapsed()));//for (int i = 0; i < img_list.size(); ++i) {std::vector<OCRPredictResult> &ocr_result = ocr_results[i];for (int i = 0; i < ocr_result.size(); i++) {QString oustr;oustr += QString::number(i) + " ";// det
//            std::vector<std::vector<int>> boxes = ocr_result[i].box;
//            if (boxes.size() > 0) {
//                oustr += "det boxes: [";
//                for (int n = 0; n < boxes.size(); n++) {
//                    oustr +=  "[" + QString::number(boxes[n][0]) + "," + QString::number(boxes[n][1]) + "]";
//                    if (n != boxes.size() - 1) {
//                        oustr +=  ",";
//                    }
//                }
//                oustr +=  "]";
//            }// recif (ocr_result[i].score != -1.0) {oustr += " score: " + QString::number(ocr_result[i].score,'f',2) + " text: " + QString::fromUtf8(ocr_result[i].text.c_str()) + " ";}// clsif (ocr_result[i].cls_label != -1) {oustr += "cls label: " + QString::number(ocr_result[i].cls_label) + " cls score: " + ocr_result[i].cls_score;}//
//            oustr += "\r\n";ui->textBrowser->append(oustr);}//for (int n = 0; n < ocr_result.size(); n++) {cv::Point rook_points[4];//for (int m = 0; m < ocr_result[n].box.size(); m++) {rook_points[m] = cv::Point(int(ocr_result[n].box[m][0]), int(ocr_result[n].box[m][1]));}//const cv::Point *ppt[1] = {rook_points};int npt[] = {4};cv::polylines(img_list[i], ppt, npt, 1, 1, CV_RGB(255, 0, 0), 2, 8, 0);}//QImage outimage;cvMat2QImage(img_list[i], outimage);ui->label_image->setPixmap(QPixmap::fromImage(outimage.scaled(ui->label_image->width(),ui->label_image->height(),Qt::KeepAspectRatio)));}

        程序目录包含这个几个文件,如果你没有,在源码路径和预测库路径去搜索

        ocrconfig.txt是自定义的配置

# common args
use_gpu false
use_tensorrt false
gpu_id 0
gpu_mem 4000
cpu_threads 10
enable_mkldnn false
precision fp32
benchmark false
output ./output/
image_dir 
type ocr# detection related
det_model_dir F:\Vision\PaddleOCR\2_7\model\ch_PP-OCRv4_det_infer
limit_type max
limit_side_len 960
det_db_thresh 0.3
det_db_box_thresh 0.6
det_db_unclip_ratio 1.5
use_dilation false
det_db_score_mode slow
visualize true# classification related
use_angle_cls false
cls_model_dir F:\Vision\PaddleOCR\2_7\model\ch_ppocr_mobile_v2.0_cls_infer
cls_thresh 0.9
cls_batch_num 1# recognition related
rec_model_dir F:\Vision\PaddleOCR\2_7\model\ch_PP-OCRv4_rec_infer
rec_batch_num 6
rec_char_dict_path ./ppocr_keys_v1.txt
rec_img_h 48
rec_img_w 320# layout model related
layout_model_dir 
layout_dict_path ./layout_publaynet_dict.txt
layout_score_threshold 0.5
layout_nms_threshold 0.5# structure model related
table_model_dir 
table_max_len 488
table_batch_num 1
merge_no_span_structure true
table_char_dict_path ./table_structure_dict_ch.txt# ocr forward related
det true
rec true
cls false
table false
layout false

        最后运行结果

       有需要源码测试的, 这是源码地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/18897.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通过AWR结合SQLHC对性能变低的SQL进行分析的过程

ESTDB数据库2020/4/29下午16点附近出现业务卡顿现象。 可以发现问题SQL为(SQL_ID fr0nhywcycrsa)。占问题时段数据库资源消耗的52.69%&#xff0c;通过对此SQL语句的执行效率进行分析&#xff0c;我们发现&#xff1a; 对SQL_ID fr0nhywcycrsa?进行分析&#xff0c;可以发现此…

kubernetes-PV与PVC

一、PV和PVC详解 当前&#xff0c;存储的方式和种类有很多&#xff0c;并且各种存储的参数也需要非常专业的技术人员才能够了解。在Kubernetes集群中&#xff0c;放了方便我们的使用和管理&#xff0c;Kubernetes提出了PV和PVC的概念&#xff0c;这样Kubernetes集群的管理人员就…

Java_认识String类

在 C 语言中已经涉及到字符串了&#xff0c;但是在 C 语言中要表示字符串只能使用字符数组或者字符指针&#xff0c; 可以使用标准库提 供的字符串系列函数完成大部分操作&#xff0c;但是这种将数据和操作数据方法分离开 的方式不符合面相对象的思想&#xff0c;而字符串应用又…

【C++】二维前缀和

1.题目 2.算法思路 和一维前缀和的方法类似&#xff0c;我们需要预处理一个求和矩阵&#xff0c;然后再求和。 下面是模板&#xff1a; 上面两张图片总结出来了两个公式&#xff0c;这是解决此类问题的关键。 3.代码 #include <iostream> using namespace std; #incl…

MSMG Toolkit深度Windows系统镜像文件个性定制!

MSMG Toolkit,这个听起来略显神秘的名字,在DIY电脑爱好者和系统管理员的圈子中却是大名鼎鼎。这是一款免费的系统定制工具,专为Windows操作系统量身定做,旨在帮助用户轻松移除不必要的系统组件、集成更新、添加驱动程序,以及实现无人值守安装等功能,让每一次系统安装都更…

第三方软件测试机构进行验收测试的好处分享,需多少时间和费用?

在软件开发过程中&#xff0c;软件验收测试是不可或缺的一环。那么&#xff0c;什么是软件验收测试呢?为什么建议选择第三方软件测试机构进行验收测试呢? 软件验收测试是指在软件开发完毕后&#xff0c;由测试人员基于软件需求规格说明书和软件设计文档等材料&#xff0c;对…

扩散模型--论文分享篇

定义&#xff1a;输入文本与图像&#xff0c;生成对图像的描述。 所采用的方法&#xff1a;对比学习、基于跨注意力机制的多模态融合 基于扩散模型的方法&#xff1a;主要介绍的扩散的原理 图像生成任务介绍 GAN VAE 扩散模型 基于GAN的图像生成&#xff0c;一个生成器与判别…

【重制版】Unity Meta Quest 一体机开发(一):前期准备,Meta XR SDK导入和环境配置,配置玩家物体

文章目录 &#x1f4d5;教程说明&#x1f4d5;Meta XR SDK 介绍&#x1f4d5;前期准备⭐开启开发者模式⚡在 Meta 官网申请开发者⚡在 Meta Quest 手机 APP 开启开发者 ⭐电脑需要下载的软件⚡Meta Quest Link&#xff08;以前叫做Oculus PC客户端&#xff09;⚡Oculus ADB Dri…

洗地机有哪些牌子比较好?洗地机排行榜十大品牌

随着洗地机市场竞争的日益激烈&#xff0c;市场上涌现出数百个品牌的产品&#xff0c;涵盖了从入门级到高端的各类价位和功能。这种多样化的选择一方面极大地满足了用户的不同需求&#xff0c;但另一方面也让消费者在挑选时面临一定的困扰。在众多种类的洗地机中&#xff0c;如…

MyBatisPlus学习笔记(二)

条件构造器&#xff1a; Wrapper的作用就是来封装我们当前的条件的 删除用的和查询用的一样&#xff1a;QueryWrapper 和 LambdaQueryWrapper MyBatis-Plus分页插件的配置和使用 Ctrl H 查看当前接口或者类的一个继承关系 Ctrl P 分页插件 乐观锁和悲观锁 通用枚举 代码…

LVGL移植到STM32 MCU平台详细经验笔记教程

1、前言 在之前的一篇文章LVGL在VSCode中安装模拟器&#xff0c;已经对LVGL进行了较为详细的介绍&#xff0c;本文将着重讲解如何移植适配LVGL&#xff0c;让这款图形化GUI库在STM32或其它类型的嵌入式MCU设备上运行起来。 LVGL在VScode中安装模拟器运行配置笔记教程_vscode …

利用Dify+Kimi免费使用Kimi的API接口的操作和使用方法

废话不多说&#xff0c;直接开整kimi-free-api项目。 1、kimi-free-api服务安装启动 支持高速流式输出、支持多轮对话、支持联网搜索、支持智能体对话、支持长文档解读、支持图像OCR&#xff0c;零配置部署&#xff0c;多路token支持&#xff0c;自动清理会话痕迹。 与ChatG…

一文了解知识中台:是什么、作用、如何搭建

在当今信息繁杂的时代&#xff0c;知识对于企业来说犹如宝藏般重要&#xff0c;而知识中台就是宝藏山的藏宝图。关于知识中台&#xff0c;你可能会感到好奇&#xff0c;它究竟是什么&#xff0c;有什么作用&#xff0c;又该如何搭建知识中台呢&#xff1f;接下来就让LookLook同…

MATLAB分类与判别模型算法:基于Fisher算法的分类程序【含Matlab源码 MX_002期】

算法思路介绍&#xff1a; 费舍尔线性判别分析&#xff08;Fishers Linear Discriminant Analysis&#xff0c;简称 LDA&#xff09;&#xff0c;用于将两个类别的数据点进行二分类。以下是代码的整体思路&#xff1a; 生成数据&#xff1a; 使用 randn 函数生成随机数&#x…

基于微信小程序开发的一款 高颜值在线答题刷题考试程序

大家好&#xff0c;我是兔兔。今天给大家分享的内容是&#xff0c;兔兔答题模板三的发布。 兔兔答题模板三是一款基于uniapp开发&#xff0c;后端使用PHP&#xff0c;前端使用图鸟UI的微信答题小程序应用程序。相必兔兔答题模板一和兔兔答题模板二&#xff0c;进行了系统架构的…

上位机图像处理和嵌入式模块部署(f103 mcu中main入口函数误解)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 学习stm32代码的时候&#xff0c;关于汇编文件&#xff0c;大家一般都会参考官方给出的汇编文件。通常情况下&#xff0c;不会自己去写汇编文件。特…

凡事有利有弊,如果生了一个自闭症的小孩,请说出有利的部分 :独特、专注力、诚实和直接,记忆力

生育一个自闭症小孩可能带来一些独特的优势和积极的方面&#xff0c;尽管也会面临许多挑战。以下是一些可能的有利方面&#xff1a; 独特的视角&#xff1a;自闭症儿童通常有独特的思维方式和视角&#xff0c;他们可能在某些方面比普通人更敏锐。这种独特性可以带来创新的解决方…

Nginx/阿里云/二级域名的配置和使用

阿里云域名解析配置如下&#xff1a; nginx配置如下&#xff1a; 访问地址&#xff1a; zhadmin.iotzzh.com image.png

20240529瑞芯微官方Toybrick TB-RK3588开发板的Debian11安装iperf并测试网速

20240529瑞芯微官方Toybrick TB-RK3588开发板的Debian11安装iperf并测试网速 2024/5/29 15:09 服务器端&#xff1a;瑞芯微官方Toybrick TB-RK3588开发板&#xff1a;Debian11 客户端&#xff1a;笔记本电脑&#xff1a;Ubuntu20.04 两者通过千兆交换机连接&#xff01; toybr…

小白跟做江科大32单片机之蜂鸣器

1.复制之前编写的工程库项目&#xff0c;详细工程库创建过程如下链接&#xff1a; 小白跟做江科大32单片机之LED闪烁-CSDN博客https://blog.csdn.net/weixin_58051657/article/details/139295351?spm1001.2014.3001.55022.按照江科大老师给的图片进行连接蜂鸣器 3.修改main.c…