日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

Yolov5身份证检测——C++ OpenCV DNN推理

發布時間:2025/3/21 c/c++ 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Yolov5身份证检测——C++ OpenCV DNN推理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.由于OpenCV DNN中的slice層不支持step為2,所以在轉換模型時需要修改代碼,修改的地方在models/common.py中Focus類

  • 修改前:
class Focus(nn.Module):# Focus wh information into c-spacedef __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True): # ch_in, ch_out, kernel, stride, padding, groupssuper(Focus, self).__init__()self.conv = Conv(c1 * 4, c2, k, s, p, g, act)def forward(self, x): # x(b,c,w,h) -> y(b,4c,w/2,h/2)return self.conv(torch.cat([x[..., ::2, ::2], x[..., 1::2, ::2], x[..., ::2, 1::2], x[..., 1::2, 1::2]], 1))
  • 修改后
class Focus(nn.Module):# Focus wh information into c-spacedef __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True): # ch_in, ch_out, kernel, stride, padding, groupssuper(Focus, self).__init__()self.conv = Conv(c1 * 4, c2, k, s, p, g, act)def forward(self, x): # x(b,c,w,h) -> y(b,4c,w/2,h/2)#return self.conv(torch.cat([x[..., ::2, ::2], x[..., 1::2, ::2], x[..., ::2, 1::2], x[..., 1::2, 1::2]], 1))return self.conv(x)

2.轉換模型

python models/export.py --weights runs/exp/weights/best.pt # --weights: 訓練得到的模型

運行后,onnx模型保存為了runs/exp/weights/best.onnx,這個模型就可以用OpenCV DNN進行推理。

3.DNN C++推理

#include <iostream> #include <string> #include <vector> #include <fstream> #include <sstream> #include <opencv2/opencv.hpp> #include <opencv2/dnn.hpp>void imshow(std::string name, const cv::Mat& cv_src) {cv::namedWindow(name, 0);int max_rows = 800;int max_cols = 800;if (cv_src.rows >= cv_src.cols && cv_src.rows > max_rows){cv::resizeWindow(name, cv::Size(cv_src.cols * max_rows / cv_src.rows, max_rows));}else if (cv_src.cols >= cv_src.rows && cv_src.cols > max_cols){cv::resizeWindow(name, cv::Size(max_cols, cv_src.rows * max_cols / cv_src.cols));}cv::imshow(name, cv_src); }inline float sigmoid(float x) {return 1.f / (1.f + exp(-x)); }void sliceAndConcat(cv::Mat& img, cv::Mat* input) {const float* srcData = img.ptr<float>();float* dstData = input->ptr<float>();using Vec12f = cv::Vec<float, 12>;for (int i = 0; i < input->size[2]; i++){for (int j = 0; j < input->size[3]; j++){for (int k = 0; k < 3; ++k){dstData[k * input->size[2] * input->size[3] + i * input->size[3] + j] =srcData[k * img.size[2] * img.size[3] + 2 * i * img.size[3] + 2 * j];}for (int k = 0; k < 3; ++k){dstData[(3 + k) * input->size[2] * input->size[3] + i * input->size[3] + j] =srcData[k * img.size[2] * img.size[3] + (2 * i + 1) * img.size[3] + 2 * j];}for (int k = 0; k < 3; ++k) {dstData[(6 + k) * input->size[2] * input->size[3] + i * input->size[3] + j] =srcData[k * img.size[2] * img.size[3] + 2 * i * img.size[3] + 2 * j + 1];}for (int k = 0; k < 3; ++k){dstData[(9 + k) * input->size[2] * input->size[3] + i * input->size[3] + j] =srcData[k * img.size[2] * img.size[3] + (2 * i + 1) * img.size[3] + 2 * j + 1];}}} }std::vector<cv::String> getOutputNames(const cv::dnn::Net& net) {static std::vector<cv::String> names;if (names.empty()){std::vector<int> outLayers = net.getUnconnectedOutLayers();std::vector<cv::String> layersNames = net.getLayerNames();names.resize(outLayers.size());for (size_t i = 0; i < outLayers.size(); i++){names[i] = layersNames[outLayers[i] - 1];}}return names; }void drawPred(int classId, float conf, int left, int top, int right, int bottom, cv::Mat& frame,const std::vector<std::string> &classes) {cv::rectangle(frame, cv::Point(left, top), cv::Point(right, bottom), cv::Scalar(0, 255, 0), 3);std::string label = cv::format("%.2f", conf);if (!classes.empty()) {CV_Assert(classId < (int)classes.size());label = classes[classId] + ": " + label;}int baseLine;cv::Size labelSize = cv::getTextSize(label, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);top = std::max(top, labelSize.height);cv::rectangle(frame, cv::Point(left, top - round(1.5 * labelSize.height)), cv::Point(left + round(1.5 * labelSize.width), top + baseLine), cv::Scalar(0, 255, 0), cv::FILLED);cv::putText(frame, label, cv::Point(left, top), cv::FONT_HERSHEY_SIMPLEX, 0.75, cv::Scalar(), 2); }void postprocess(cv::Mat& cv_src, std::vector<cv::Mat>& outs, const std::vector<std::string>& classes, int net_size) {float confThreshold = 0.4f;float nmsThreshold = 0.5f;std::vector<int> classIds;std::vector<float> confidences;std::vector<cv::Rect> boxes;int strides[] = { 8, 16, 32 };std::vector<std::vector<int> > anchors = {{ 10,13, 16,30, 33,23 },{ 30,61, 62,45, 59,119 },{ 116,90, 156,198, 373,326 }};for (size_t k = 0; k < outs.size(); k++){float* data = outs[k].ptr<float>();int stride = strides[k];int num_classes = outs[k].size[4] - 5;for (int i = 0; i < outs[k].size[2]; i++){for (int j = 0; j < outs[k].size[3]; j++){for (int a = 0; a < outs[k].size[1]; ++a){float* record = data + a * outs[k].size[2] * outs[k].size[3] * outs[k].size[4] +i * outs[k].size[3] * outs[k].size[4] + j * outs[k].size[4];float* cls_ptr = record + 5;for (int cls = 0; cls < num_classes; cls++) {float score = sigmoid(cls_ptr[cls]) * sigmoid(record[4]);if (score > confThreshold){float cx = (sigmoid(record[0]) * 2.f - 0.5f + (float)j) * (float)stride;float cy = (sigmoid(record[1]) * 2.f - 0.5f + (float)i) * (float)stride;float w = pow(sigmoid(record[2]) * 2.f, 2) * anchors[k][2 * a];float h = pow(sigmoid(record[3]) * 2.f, 2) * anchors[k][2 * a + 1];float x1 = std::max(0, std::min(cv_src.cols, int((cx - w / 2.f) * (float)cv_src.cols / (float)net_size)));float y1 = std::max(0, std::min(cv_src.rows, int((cy - h / 2.f) * (float)cv_src.rows / (float)net_size)));float x2 = std::max(0, std::min(cv_src.cols, int((cx + w / 2.f) * (float)cv_src.cols / (float)net_size)));float y2 = std::max(0, std::min(cv_src.rows, int((cy + h / 2.f) * (float)cv_src.rows / (float)net_size)));classIds.push_back(cls);confidences.push_back(score);boxes.push_back(cv::Rect(cv::Point(x1, y1), cv::Point(x2, y2)));}}}}}}std::vector<int> indices;cv::dnn::NMSBoxes(boxes, confidences, confThreshold, nmsThreshold, indices);for (size_t i = 0; i < indices.size(); i++) {int idx = indices[i];cv::Rect box = boxes[idx];drawPred(classIds[idx], confidences[idx], box.x, box.y,box.x + box.width, box.y + box.height, cv_src, classes);} }int main(int argc, char* argv[]) {std::string path = "images";std::vector<std::string> filenames;cv::glob(path, filenames, false);for (auto name : filenames){cv::Mat cv_src = cv::imread(name);if (cv_src.empty()){continue;}std::vector<std::string> class_names{ "ida","idb" };int net_size = 640;cv::Mat blob = cv::dnn::blobFromImage(cv_src, 1.0 / 255, cv::Size(net_size, net_size),cv::Scalar(0, 0, 0), true, false);cv::dnn::Net net = cv::dnn::readNet("model/ODID_DNN.onnx");const int sz[] = { 1, 12, net_size / 2, net_size / 2 };cv::Mat input = cv::Mat(4, sz, blob.type());sliceAndConcat(blob, &input);net.setInput(input);auto t0 = cv::getTickCount();std::vector<cv::Mat> outs;net.forward(outs, getOutputNames(net));postprocess(cv_src, outs, class_names, net_size);auto t1 = cv::getTickCount();std::cout << "elapsed time: " << (t1 - t0) * 1000.0 / cv::getTickFrequency() << "ms" << std::endl;imshow("img", cv_src);cv::waitKey();}return 0; }

檢測一張圖像大概要0.1秒左右。

4.模型和源碼以上傳CSDN。地址:https://download.csdn.net/download/matt45m/46982918

總結

以上是生活随笔為你收集整理的Yolov5身份证检测——C++ OpenCV DNN推理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 波多野吉衣中文字幕 | 国产精品久久久久桃色tv | 午夜免费剧场 | 男人天堂2014 | 激情91| 亚洲乱子伦 | 正在播放91 | 精品人妻一区二区三区久久嗨 | 懂色av成人一区二区三区 | 日本三级久久久 | 久久婷婷国产 | 色猫咪av | 黄色片久久久 | 日韩91视频 | 亚洲av无码精品色午夜果冻不卡 | 嫩草影院在线观看视频 | 欧美一区二区三区视频在线 | 国产福利免费视频 | 国产精品视频一区二区三区在3 | 男人把女人捅爽 | 亚洲一区二区中文字幕 | 极品白嫩丰满少妇无套 | 国产精品二区一区二区aⅴ污介绍 | 一区二区日韩av | 中文字幕欧美人妻精品 | 亚洲一个色 | 久艹在线观看 | 香蕉国产999 | 免费在线国产精品 | 起碰在线 | 中国少妇初尝黑人巨大 | 成人高清免费 | 色午夜视频 | 国产精品不卡一区二区三区 | 亚洲逼图 | 91成人精品 | 久久青青草视频 | 国产精品九一 | 国产在线播 | 偷拍女澡堂一区二区三区 | 日韩欧美视频在线免费观看 | 91丨porny| 免费看片亚洲 | 国产在线aaa | 成年人免费在线 | 加勒比一区在线 | 国产日韩不卡 | 欧美xxxxbbbb| 免费色片| 毛片黄色片 | 91嫩草入口 | 日本波多野结衣在线 | 午夜一级大片 | 少妇人妻偷人精品视频蜜桃 | 国产一区二区三区免费在线观看 | 91婷婷在线 | 中文字幕不卡在线 | 亚洲第一视频网站 | 亚洲国产精品自拍视频 | www一区二区三区 | 黄色日b片 | 男人天堂综合网 | 两性动态视频 | 娇小tube性极品娇小 | 亚洲第一在线播放 | 91亚洲精品久久久久久久久久久久 | 精品久久影视 | 免费网站观看www在线观看 | 午夜视频在线观看免费视频 | 永久免费av在线 | 理论片久久 | 黄色欧美一级片 | 亚洲视频综合 | 99这里只有精品 | 国产黄色片子 | 亚洲成人自拍偷拍 | 网址在线观看你懂的 | 91在线视频在线观看 | 亚洲一区二区精品在线 | 17c精品麻豆一区二区免费 | 夜夜导航 | 日本黄色片视频 | 国产欧美久久久精品免费 | 人妻一区二区三区在线 | xxx老太太 | 丁香花免费高清完整在线播放 | 毛片视屏 | 人妻大战黑人白浆狂泄 | 欧美黄色一级网站 | 日韩亚洲欧美一区二区三区 | 国产欧美一区二区在线观看 | 国产伦精品一区二区三区在线 | 800av在线播放| 中文字幕一区av | 视频一区二区欧美 | 污视频在线观看网址 | 国产免费高清视频 | 国产在线视频导航 | 欧美成人xxx |