日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > C# >内容正文

C#

60、在Visual Studio 2019 环境下,使用C#调用C++生成的dll实现yolov5的图片检测

發(fā)布時(shí)間:2023/12/14 C# 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 60、在Visual Studio 2019 环境下,使用C#调用C++生成的dll实现yolov5的图片检测 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

基本思想:寫了一個簡單的c#調(diào)用c++的dll庫圖形化界面程序,完成yolov5檢測圖片的分類,本項(xiàng)目問的人太多了。。。。附屬鏈接吧

鏈接:https://pan.baidu.com/s/1RVh1XtqvFuWuHyuZKxuzDw?pwd=vsxz?
提取碼:vsxz?
--來自百度網(wǎng)盤超級會員V1的分享

一、創(chuàng)建一個c++工程,詳細(xì)的構(gòu)建和配置環(huán)境就不詳細(xì)累述了,貼代碼吧,導(dǎo)入opencv和ncnn庫即可,因?yàn)樾枰紤]使用C#調(diào)用,所以改的代碼盡量迎合C#調(diào)用的風(fēng)格

main.cpp

#include "connect.h"int main(int argc, char** argv) {cv::Mat image = cv::imread("E:\\images\\test\\test1.jpg");unsigned char* src = image.data;cv::Mat result = cv::Mat(image.rows, image.cols, CV_8UC3, src);unsigned char* dest = result.data;const char* model_param = "G:\\ncnn-20210525-windows-vs2019\\ncnn-20210525-windows-vs2019\\x64\\bin\\best_sim211223.param";const char* model_bin = "G:\\ncnn-20210525-windows-vs2019\\ncnn-20210525-windows-vs2019\\x64\\bin\\best_sim211223.bin";ConnectCppWrapper::init_model(model_param, model_bin);ConnectCppWrapper::detect_image(src, dest, image.rows, image.cols);cv::imshow("demo", result);cv::waitKey(0);return 0; }

connect.h

#pragma once#include "yolov5.h"namespace ConnectCppWrapper {extern "C" __declspec(dllexport) int __stdcall init_model(const char* model_param, const char* bin_param);extern "C" __declspec(dllexport) int __stdcall detect_image(unsigned char* ImageBuffer, unsigned char* ImageResult, int height, int width);}

connect.cpp

#include "connect.h"namespace ConnectCppWrapper {Yolov5* yolov5Item = new Yolov5();int __stdcall init_model(const char* model_param, const char* bin_param){return yolov5Item->init_model(model_param, bin_param);}int __stdcall detect_image(unsigned char* ImageBuffer, unsigned char* ImageResult, int height, int width){cv::Mat result;cv::Mat image = cv::Mat(height, width, CV_8UC3, ImageBuffer);yolov5Item->detect_yolov5(image);int length = (int)(result.total() * result.elemSize());unsigned char* buffer = new unsigned char[length];memcpy(ImageResult, result.data, length * sizeof(unsigned char));return 0;} }

yolov5.h? 這部分代碼和模型來自ncnn的example

#pragma once#include "layer.h" #include "net.h"#if defined(USE_NCNN_SIMPLEOCV) #include "simpleocv.h" #else #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #endif #include <float.h> #include <stdio.h> #include <vector>#define YOLOV5_V60 1 //YOLOv5 v6.0 using namespace std; using namespace ncnn; struct Object {cv::Rect_<float> rect;int label;float prob; }; class Yolov5 { public:Yolov5();~Yolov5(); private:float intersection_area(const Object& a, const Object& b);void qsort_descent_inplace(std::vector<Object>& faceobjects, int left, int right);void qsort_descent_inplace(std::vector<Object>& faceobjects);void nms_sorted_bboxes(const std::vector<Object>& faceobjects, std::vector<int>& picked, float nms_threshold);void generate_proposals(const ncnn::Mat& anchors, int stride, const ncnn::Mat& in_pad, const ncnn::Mat& feat_blob, float prob_threshold, std::vector<Object>& objects);float sigmoid(float x); public:int detect_yolov5(cv::Mat image);void draw_objects(const cv::Mat& image, const std::vector<Object>& objects);int init_model(const char* param_file, const char* bin_file);private:ncnn::Net m_yolov5;const int m_target_size = 640;const float m_prob_threshold = 0.25f;const float m_nms_threshold = 0.45f;};

yolov5.cpp

#include "yolov5.h" #if YOLOV5_V60 #define MAX_STRIDE 64 #else #define MAX_STRIDE 32 class YoloV5Focus : public ncnn::Layer { public:YoloV5Focus(){one_blob_only = true;}virtual int forward(const ncnn::Mat& bottom_blob, ncnn::Mat& top_blob, const ncnn::Option& opt) const{int w = bottom_blob.w;int h = bottom_blob.h;int channels = bottom_blob.c;int outw = w / 2;int outh = h / 2;int outc = channels * 4;top_blob.create(outw, outh, outc, 4u, 1, opt.blob_allocator);if (top_blob.empty())return -100;#pragma omp parallel for num_threads(opt.num_threads)for (int p = 0; p < outc; p++){const float* ptr = bottom_blob.channel(p % channels).row((p / channels) % 2) + ((p / channels) / 2);float* outptr = top_blob.channel(p);for (int i = 0; i < outh; i++){for (int j = 0; j < outw; j++){*outptr = *ptr;outptr += 1;ptr += 2;}ptr += w;}}return 0;} };DEFINE_LAYER_CREATOR(YoloV5Focus) #endif //YOLOV5_V60Yolov5::Yolov5() { } Yolov5::~Yolov5() { }float Yolov5::intersection_area(const Object& a, const Object& b) {cv::Rect_<float> inter = a.rect & b.rect;return inter.area(); }void Yolov5::qsort_descent_inplace(std::vector<Object>& faceobjects, int left, int right) {int i = left;int j = right;float p = faceobjects[(left + right) / 2].prob;while (i <= j){while (faceobjects[i].prob > p)i++;while (faceobjects[j].prob < p)j--;if (i <= j){// swapstd::swap(faceobjects[i], faceobjects[j]);i++;j--;}}#pragma omp parallel sections{ #pragma omp section{if (left < j) qsort_descent_inplace(faceobjects, left, j);} #pragma omp section{if (i < right) qsort_descent_inplace(faceobjects, i, right);}} }void Yolov5::qsort_descent_inplace(std::vector<Object>& faceobjects) {if (faceobjects.empty())return;qsort_descent_inplace(faceobjects, 0, faceobjects.size() - 1); }void Yolov5::nms_sorted_bboxes(const std::vector<Object>& faceobjects, std::vector<int>& picked, float nms_threshold) {picked.clear();const int n = faceobjects.size();std::vector<float> areas(n);for (int i = 0; i < n; i++){areas[i] = faceobjects[i].rect.area();}for (int i = 0; i < n; i++){const Object& a = faceobjects[i];int keep = 1;for (int j = 0; j < (int)picked.size(); j++){const Object& b = faceobjects[picked[j]];// intersection over unionfloat inter_area = intersection_area(a, b);float union_area = areas[i] + areas[picked[j]] - inter_area;// float IoU = inter_area / union_areaif (inter_area / union_area > nms_threshold)keep = 0;}if (keep)picked.push_back(i);} }float Yolov5::sigmoid(float x) {return static_cast<float>(1.f / (1.f + exp(-x))); }void Yolov5::generate_proposals(const ncnn::Mat& anchors, int stride, const ncnn::Mat& in_pad, const ncnn::Mat& feat_blob, float prob_threshold, std::vector<Object>& objects) {const int num_grid = feat_blob.h;int num_grid_x;int num_grid_y;if (in_pad.w > in_pad.h){num_grid_x = in_pad.w / stride;num_grid_y = num_grid / num_grid_x;}else{num_grid_y = in_pad.h / stride;num_grid_x = num_grid / num_grid_y;}const int num_class = feat_blob.w - 5;const int num_anchors = anchors.w / 2;for (int q = 0; q < num_anchors; q++){const float anchor_w = anchors[q * 2];const float anchor_h = anchors[q * 2 + 1];const ncnn::Mat feat = feat_blob.channel(q);for (int i = 0; i < num_grid_y; i++){for (int j = 0; j < num_grid_x; j++){const float* featptr = feat.row(i * num_grid_x + j);// find class index with max class scoreint class_index = 0;float class_score = -FLT_MAX;for (int k = 0; k < num_class; k++){float score = featptr[5 + k];if (score > class_score){class_index = k;class_score = score;}}float box_score = featptr[4];float confidence = sigmoid(box_score) * sigmoid(class_score);if (confidence >= prob_threshold){// yolov5/models/yolo.py Detect forward// y = x[i].sigmoid()// y[..., 0:2] = (y[..., 0:2] * 2. - 0.5 + self.grid[i].to(x[i].device)) * self.stride[i] # xy// y[..., 2:4] = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i] # whfloat dx = sigmoid(featptr[0]);float dy = sigmoid(featptr[1]);float dw = sigmoid(featptr[2]);float dh = sigmoid(featptr[3]);float pb_cx = (dx * 2.f - 0.5f + j) * stride;float pb_cy = (dy * 2.f - 0.5f + i) * stride;float pb_w = pow(dw * 2.f, 2) * anchor_w;float pb_h = pow(dh * 2.f, 2) * anchor_h;float x0 = pb_cx - pb_w * 0.5f;float y0 = pb_cy - pb_h * 0.5f;float x1 = pb_cx + pb_w * 0.5f;float y1 = pb_cy + pb_h * 0.5f;Object obj;obj.rect.x = x0;obj.rect.y = y0;obj.rect.width = x1 - x0;obj.rect.height = y1 - y0;obj.label = class_index;obj.prob = confidence;objects.push_back(obj);}}}} }int Yolov5::init_model(const char* param_file, const char* bin_file) {m_yolov5.opt.use_vulkan_compute = true;// yolov5.opt.use_bf16_storage = true;// original pretrained model from https://github.com/ultralytics/yolov5// the ncnn model https://github.com/nihui/ncnn-assets/tree/master/models #if YOLOV5_V60int ok0= m_yolov5.load_param(param_file);int ok1 = m_yolov5.load_model(bin_file); #elseyolov5.register_custom_layer("YoloV5Focus", YoloV5Focus_layer_creator);yolov5.load_param("yolov5s.param");yolov5.load_model("yolov5s.bin"); #endifreturn ok0 + ok1;}int Yolov5::detect_yolov5(cv::Mat image) {std::vector<Object> objects;int img_w = image.cols;int img_h = image.rows;// letterbox pad to multiple of MAX_STRIDEint w = img_w;int h = img_h;float scale = 1.f;if (w > h){scale = (float)m_target_size / w;w = m_target_size;h = h * scale;}else{scale = (float)m_target_size / h;h = m_target_size;w = w * scale;}ncnn::Mat in = ncnn::Mat::from_pixels_resize(image.data, ncnn::Mat::PIXEL_BGR2RGB, img_w, img_h, w, h);// pad to target_size rectangle// yolov5/utils/datasets.py letterboxint wpad = (w + MAX_STRIDE - 1) / MAX_STRIDE * MAX_STRIDE - w;int hpad = (h + MAX_STRIDE - 1) / MAX_STRIDE * MAX_STRIDE - h;ncnn::Mat in_pad;ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, ncnn::BORDER_CONSTANT, 114.f);const float norm_vals[3] = { 1 / 255.f, 1 / 255.f, 1 / 255.f };in_pad.substract_mean_normalize(0, norm_vals);ncnn::Extractor ex = m_yolov5.create_extractor();ex.input("images", in_pad);std::vector<Object> proposals;// anchor setting from yolov5/models/yolov5s.yaml// stride 8{ncnn::Mat out;ex.extract("output", out);ncnn::Mat anchors(6);anchors[0] = 10.f;anchors[1] = 13.f;anchors[2] = 16.f;anchors[3] = 30.f;anchors[4] = 33.f;anchors[5] = 23.f;std::vector<Object> objects8;generate_proposals(anchors, 8, in_pad, out, m_prob_threshold, objects8);proposals.insert(proposals.end(), objects8.begin(), objects8.end());}// stride 16{ncnn::Mat out; #if YOLOV5_V60ex.extract("376", out); #elseex.extract("781", out); #endifncnn::Mat anchors(6);anchors[0] = 30.f;anchors[1] = 61.f;anchors[2] = 62.f;anchors[3] = 45.f;anchors[4] = 59.f;anchors[5] = 119.f;std::vector<Object> objects16;generate_proposals(anchors, 16, in_pad, out, m_prob_threshold, objects16);proposals.insert(proposals.end(), objects16.begin(), objects16.end());}// stride 32{ncnn::Mat out; #if YOLOV5_V60ex.extract("401", out); #elseex.extract("801", out); #endifncnn::Mat anchors(6);anchors[0] = 116.f;anchors[1] = 90.f;anchors[2] = 156.f;anchors[3] = 198.f;anchors[4] = 373.f;anchors[5] = 326.f;std::vector<Object> objects32;generate_proposals(anchors, 32, in_pad, out, m_prob_threshold, objects32);proposals.insert(proposals.end(), objects32.begin(), objects32.end());}// sort all proposals by score from highest to lowestqsort_descent_inplace(proposals);// apply nms with nms_thresholdstd::vector<int> picked;nms_sorted_bboxes(proposals, picked, m_nms_threshold);int count = picked.size();objects.resize(count);for (int i = 0; i < count; i++){objects[i] = proposals[picked[i]];// adjust offset to original unpaddedfloat x0 = (objects[i].rect.x - (wpad / 2)) / scale;float y0 = (objects[i].rect.y - (hpad / 2)) / scale;float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale;float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale;// clipx0 = std::max(std::min(x0, (float)(img_w - 1)), 0.f);y0 = std::max(std::min(y0, (float)(img_h - 1)), 0.f);x1 = std::max(std::min(x1, (float)(img_w - 1)), 0.f);y1 = std::max(std::min(y1, (float)(img_h - 1)), 0.f);objects[i].rect.x = x0;objects[i].rect.y = y0;objects[i].rect.width = x1 - x0;objects[i].rect.height = y1 - y0;}draw_objects(image, objects);return 0;}void Yolov5::draw_objects(const cv::Mat& image, const std::vector<Object>& objects) {static const char* class_names[] = {"person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light","fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow","elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee","skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard","tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple","sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch","potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone","microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear","hair drier", "toothbrush"};for (size_t i = 0; i < objects.size(); i++){const Object& obj = objects[i];fprintf(stderr, "%d = %.5f at %.2f %.2f %.2f x %.2f\n", obj.label, obj.prob,obj.rect.x, obj.rect.y, obj.rect.width, obj.rect.height);cv::rectangle(image, obj.rect, cv::Scalar(255, 0, 0));char text[256];sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100);int baseLine = 0;cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);int x = obj.rect.x;int y = obj.rect.y - label_size.height - baseLine;if (y < 0)y = 0;if (x + label_size.width > image.cols)x = image.cols - label_size.width;cv::rectangle(image, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)),cv::Scalar(255, 255, 255), -1);cv::putText(image, text, cv::Point(x, y + label_size.height),cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));}// cv::imshow("demo", image);//cv::waitKey(0);//return image; }

先使用vs測試一下

然后再生dll庫

??58、Visual studio 2019+C#傳遞Mat數(shù)據(jù)給C++動態(tài)包處理,并將處理結(jié)果Mat返回給C#顯示、保存_sxj731533730-CSDN博客

二、然后在創(chuàng)建.NET工程,拖拽三個按鈕和兩個pictureBox畫布

在已經(jīng)安裝的模板中選擇編程語言為 --->visualC#,

選擇 ---> "windows經(jīng)典桌面中的Windows窗體應(yīng)用"

Program.cs

using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; using System.IO; using System.Runtime.InteropServices; using OpenCvSharp; using System.Drawing; using OpenCvSharp.Extensions; using System.Text;namespace WindowsFormsApp1 {static class Program{[DllImport(@"F:\sxj\20211108\detectYolov5Ncnn\x64\Release\detectYolov5Ncnn.dll",CharSet = CharSet.Ansi,CallingConvention = CallingConvention.StdCall)]public static extern int init_model(StringBuilder model_param, StringBuilder model_bin);/// <summary>/// 應(yīng)用程序的主入口點(diǎn)。/// </summary>[STAThread]static void Main(){StringBuilder model_param = new StringBuilder("F:\\sxj\\20211201\\yolov5s_6.0.param");StringBuilder model_bin = new StringBuilder("F:\\sxj\\20211201\\yolov5s_6.0.bin");init_model(model_param, model_bin);Application.EnableVisualStyles();Application.SetCompatibleTextRenderingDefault(false);Application.Run(new Form1());}} }

Form1.cs

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;using OpenCvSharp; using System.Runtime.InteropServices; using OpenCvSharp.Extensions; using System.IO.Compression; using System.Drawing.Imaging;namespace WindowsFormsApp1 {public partial class Form1 : Form{[DllImport(@"F:\sxj\20211108\detectYolov5Ncnn\x64\Release\detectYolov5Ncnn.dll")]public static extern int detect_image(byte[] ImageBuffer, byte[] , int imageHeight, int imageWidth );public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){OpenFileDialog openFileDialog = new OpenFileDialog();openFileDialog.Filter = @"jpeg|*.jpg|bmp|*.bmp|gif|*.gif";if (openFileDialog.ShowDialog() == DialogResult.OK){string fullpath = openFileDialog.FileName;FileStream fs = new FileStream(fullpath, FileMode.Open);byte[] picturebytes = new byte[fs.Length];BinaryReader br = new BinaryReader(fs);picturebytes = br.ReadBytes(Convert.ToInt32(fs.Length));MemoryStream ms = new MemoryStream(picturebytes);Bitmap bmpt = new Bitmap(ms);pictureBox1.Image = bmpt;pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;}else{MessageBox.Show("圖片打開失敗");}}private void button2_Click(object sender, EventArgs e){SaveFileDialog saveImageDialog = new SaveFileDialog();saveImageDialog.Title = "圖片保存";saveImageDialog.Filter = @"jpeg|*.jpg|bmp|*.bmp";saveImageDialog.FileName = System.DateTime.Now.ToString("yyyyMMddHHmmss");//設(shè)置默認(rèn)文件名if (saveImageDialog.ShowDialog() == DialogResult.OK){string fileName = saveImageDialog.FileName.ToString();//Console.WriteLine("fileName" + fileName);if (fileName != "" && fileName != null){string fileExtName = fileName.Substring(fileName.LastIndexOf(".") + 1).ToString();//Console.WriteLine("fileExtName" + fileExtName);System.Drawing.Imaging.ImageFormat imgformat = null;if (fileExtName != ""){switch (fileExtName){case "jpg":imgformat = System.Drawing.Imaging.ImageFormat.Jpeg;break;case "bmp":imgformat = System.Drawing.Imaging.ImageFormat.Bmp;break;default:imgformat = System.Drawing.Imaging.ImageFormat.Jpeg;break;}try{Bitmap bit = new Bitmap(pictureBox2.Image);MessageBox.Show(fileName);pictureBox2.Image.Save(fileName, imgformat);}catch{}}}}}private void button3_Click(object sender, EventArgs e){Bitmap bmp = (Bitmap)pictureBox1.Image.Clone();byte[] source = GetBGRValues(bmp);byte[] dest = source;detect_image(source, dest, bmp.Height, bmp.Width);Bitmap bmpConvert = Byte2Bitmap(dest, bmp.Width, bmp.Height);Image images = bmpConvert;pictureBox2.Image = images;pictureBox2.SizeMode = PictureBoxSizeMode.StretchImage;}public static byte[] GetBGRValues(Bitmap bmp){var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);var bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);var rowBytes = bmpData.Width * Image.GetPixelFormatSize(bmp.PixelFormat) / 8;var imgBytes = bmp.Height * rowBytes;byte[] rgbValues = new byte[imgBytes];IntPtr ptr = bmpData.Scan0;for (var i = 0; i < bmp.Height; i++){Marshal.Copy(ptr, rgbValues, i * rowBytes, rowBytes);ptr += bmpData.Stride;}bmp.UnlockBits(bmpData);return rgbValues;}public static Bitmap Byte2Bitmap(Byte[] data, int width, int height){Bitmap image = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);Rectangle rect = new Rectangle(0, 0, image.Width, image.Height);BitmapData bmData = image.LockBits(rect, ImageLockMode.ReadWrite, image.PixelFormat);IntPtr ptr = bmData.Scan0;for (int i = 0; i < image.Height; i++){Marshal.Copy(data, i * image.Width * 3, ptr, image.Width * 3);ptr = (IntPtr)(ptr.ToInt64() + bmData.Stride);}image.UnlockBits(bmData);return image;}private void pictureBox1_Click(object sender, EventArgs e){}} }

測試效果圖

(1)初始化界面

(2)選擇一張圖

?

(3)檢測出結(jié)果

?

三、如果想把檢測的目標(biāo)坐標(biāo)和類別置信度返回給c# 可以這樣寫(目前只寫了一個支持單類檢測的,多類別信息需要變成數(shù)組即可)

main.cpp函數(shù)

#include "connect.h"int main(int argc, char** argv) {ConnectCppWrapper::DefectResult* data = new ConnectCppWrapper::DefectResult;printf("data.prob= %f\n", data->prob);printf("data.label= %d\n", data->label);printf("data.x= %d\n", data->x);printf("data.y= %d\n", data->y);printf("data.width= %d\n", data->width);printf("data.height= %d\n", data->height);cv::Mat image = cv::imread("F:\\sxj\\predictions.jpg");unsigned char* src = image.data;cv::Mat result = cv::Mat( image.rows,image.cols, CV_8UC3, src);unsigned char* dest = result.data;const char* model_param = "F:\\sxj\\20211201\\yolov5s_6.0.param";const char* model_bin = "F:\\sxj\\20211201\\yolov5s_6.0.bin";ConnectCppWrapper::init_model(model_param, model_bin);ConnectCppWrapper::detect_image(src, dest, image.rows,image.cols, data);printf("data.prob= %f\n", data->prob);printf("data.label= %d\n", data->label);printf("data.x= %d\n", data->x);printf("data.y= %d\n", data->y);printf("data.width= %d\n", data->width);printf("data.height= %d\n", data->height);cv::imshow("demo", result);cv::waitKey(0);return 0; }

connect.h頭文件

#pragma once#include "yolov5.h"namespace ConnectCppWrapper {struct DefectResult{int label = 0;float prob = 0;int x = 0;int y = 0;int width = 0;int height = 0;};extern "C" __declspec(dllexport) int __stdcall init_model(const char* model_param, const char* bin_param);extern "C" __declspec(dllexport) int __stdcall detect_image(unsigned char* ImageBuffer, unsigned char* ImageResult,int height, int width, DefectResult * data);}

connect.cpp文件

#include "connect.h"namespace ConnectCppWrapper {Yolov5* yolov5Item = new Yolov5();int __stdcall init_model(const char* model_param, const char* bin_param){return yolov5Item->init_model(model_param, bin_param);}int __stdcall detect_image(unsigned char* ImageBuffer, unsigned char* ImageResult, int height,int width, DefectResult* data){cv::Mat result;cv::Mat image = cv::Mat(height,width , CV_8UC3, ImageBuffer);std::vector<Object> objects;int ok = yolov5Item->detect_yolov5(image, objects);if (ok == 0){printf("detect image is successful\n");}for (int i = 0; i < objects.size(); i++){data->label = objects[i].label;data->prob = objects[i].prob;data->x = objects[i].rect.x;data->y = objects[i].rect.x;data->width = objects[i].rect.width;data->height = objects[i].rect.height;printf("%f %f %f %f %d %f\n", objects[i].rect.x, objects[i].rect.y, objects[i].rect.width, objects[i].rect.height, objects[i].label, objects[i].prob);}int length = (int)(result.total() * result.elemSize());unsigned char* buffer = new unsigned char[length];memcpy(ImageResult, result.data, length * sizeof(unsigned char));return 0;} }

yolov5.h頭文件

#pragma once#include "layer.h" #include "net.h"#if defined(USE_NCNN_SIMPLEOCV) #include "simpleocv.h" #else #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #endif #include <float.h> #include <stdio.h> #include <vector>#define YOLOV5_V60 1 //YOLOv5 v6.0 using namespace std; using namespace ncnn; struct Object {cv::Rect_<float> rect;int label;float prob; }; class Yolov5 { public:Yolov5();~Yolov5(); private:float intersection_area(const Object& a, const Object& b);void qsort_descent_inplace(std::vector<Object>& faceobjects, int left, int right);void qsort_descent_inplace(std::vector<Object>& faceobjects);void nms_sorted_bboxes(const std::vector<Object>& faceobjects, std::vector<int>& picked, float nms_threshold);void generate_proposals(const ncnn::Mat& anchors, int stride, const ncnn::Mat& in_pad, const ncnn::Mat& feat_blob, float prob_threshold, std::vector<Object>& objects);float sigmoid(float x); public:int detect_yolov5(cv::Mat image, std::vector<Object>& objects);void draw_objects(const cv::Mat& image, const std::vector<Object>& objects);int init_model(const char* param_file, const char* bin_file);private:ncnn::Net m_yolov5;const int m_target_size = 640;const float m_prob_threshold = 0.25f;const float m_nms_threshold = 0.45f;};

yolov5.cpp文件

#include "yolov5.h" #if YOLOV5_V60 #define MAX_STRIDE 64 #else #define MAX_STRIDE 32 class YoloV5Focus : public ncnn::Layer { public:YoloV5Focus(){one_blob_only = true;}virtual int forward(const ncnn::Mat& bottom_blob, ncnn::Mat& top_blob, const ncnn::Option& opt) const{int w = bottom_blob.w;int h = bottom_blob.h;int channels = bottom_blob.c;int outw = w / 2;int outh = h / 2;int outc = channels * 4;top_blob.create(outw, outh, outc, 4u, 1, opt.blob_allocator);if (top_blob.empty())return -100;#pragma omp parallel for num_threads(opt.num_threads)for (int p = 0; p < outc; p++){const float* ptr = bottom_blob.channel(p % channels).row((p / channels) % 2) + ((p / channels) / 2);float* outptr = top_blob.channel(p);for (int i = 0; i < outh; i++){for (int j = 0; j < outw; j++){*outptr = *ptr;outptr += 1;ptr += 2;}ptr += w;}}return 0;} };DEFINE_LAYER_CREATOR(YoloV5Focus) #endif //YOLOV5_V60Yolov5::Yolov5() { } Yolov5::~Yolov5() { }float Yolov5::intersection_area(const Object& a, const Object& b) {cv::Rect_<float> inter = a.rect & b.rect;return inter.area(); }void Yolov5::qsort_descent_inplace(std::vector<Object>& faceobjects, int left, int right) {int i = left;int j = right;float p = faceobjects[(left + right) / 2].prob;while (i <= j){while (faceobjects[i].prob > p)i++;while (faceobjects[j].prob < p)j--;if (i <= j){// swapstd::swap(faceobjects[i], faceobjects[j]);i++;j--;}}#pragma omp parallel sections{ #pragma omp section{if (left < j) qsort_descent_inplace(faceobjects, left, j);} #pragma omp section{if (i < right) qsort_descent_inplace(faceobjects, i, right);}} }void Yolov5::qsort_descent_inplace(std::vector<Object>& faceobjects) {if (faceobjects.empty())return;qsort_descent_inplace(faceobjects, 0, faceobjects.size() - 1); }void Yolov5::nms_sorted_bboxes(const std::vector<Object>& faceobjects, std::vector<int>& picked, float nms_threshold) {picked.clear();const int n = faceobjects.size();std::vector<float> areas(n);for (int i = 0; i < n; i++){areas[i] = faceobjects[i].rect.area();}for (int i = 0; i < n; i++){const Object& a = faceobjects[i];int keep = 1;for (int j = 0; j < (int)picked.size(); j++){const Object& b = faceobjects[picked[j]];// intersection over unionfloat inter_area = intersection_area(a, b);float union_area = areas[i] + areas[picked[j]] - inter_area;// float IoU = inter_area / union_areaif (inter_area / union_area > nms_threshold)keep = 0;}if (keep)picked.push_back(i);} }float Yolov5::sigmoid(float x) {return static_cast<float>(1.f / (1.f + exp(-x))); }void Yolov5::generate_proposals(const ncnn::Mat& anchors, int stride, const ncnn::Mat& in_pad, const ncnn::Mat& feat_blob, float prob_threshold, std::vector<Object>& objects) {const int num_grid = feat_blob.h;int num_grid_x;int num_grid_y;if (in_pad.w > in_pad.h){num_grid_x = in_pad.w / stride;num_grid_y = num_grid / num_grid_x;}else{num_grid_y = in_pad.h / stride;num_grid_x = num_grid / num_grid_y;}const int num_class = feat_blob.w - 5;const int num_anchors = anchors.w / 2;for (int q = 0; q < num_anchors; q++){const float anchor_w = anchors[q * 2];const float anchor_h = anchors[q * 2 + 1];const ncnn::Mat feat = feat_blob.channel(q);for (int i = 0; i < num_grid_y; i++){for (int j = 0; j < num_grid_x; j++){const float* featptr = feat.row(i * num_grid_x + j);// find class index with max class scoreint class_index = 0;float class_score = -FLT_MAX;for (int k = 0; k < num_class; k++){float score = featptr[5 + k];if (score > class_score){class_index = k;class_score = score;}}float box_score = featptr[4];float confidence = sigmoid(box_score) * sigmoid(class_score);if (confidence >= prob_threshold){// yolov5/models/yolo.py Detect forward// y = x[i].sigmoid()// y[..., 0:2] = (y[..., 0:2] * 2. - 0.5 + self.grid[i].to(x[i].device)) * self.stride[i] # xy// y[..., 2:4] = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i] # whfloat dx = sigmoid(featptr[0]);float dy = sigmoid(featptr[1]);float dw = sigmoid(featptr[2]);float dh = sigmoid(featptr[3]);float pb_cx = (dx * 2.f - 0.5f + j) * stride;float pb_cy = (dy * 2.f - 0.5f + i) * stride;float pb_w = pow(dw * 2.f, 2) * anchor_w;float pb_h = pow(dh * 2.f, 2) * anchor_h;float x0 = pb_cx - pb_w * 0.5f;float y0 = pb_cy - pb_h * 0.5f;float x1 = pb_cx + pb_w * 0.5f;float y1 = pb_cy + pb_h * 0.5f;Object obj;obj.rect.x = x0;obj.rect.y = y0;obj.rect.width = x1 - x0;obj.rect.height = y1 - y0;obj.label = class_index;obj.prob = confidence;objects.push_back(obj);}}}} }int Yolov5::init_model(const char* param_file, const char* bin_file) {m_yolov5.opt.use_vulkan_compute = true;// yolov5.opt.use_bf16_storage = true;// original pretrained model from https://github.com/ultralytics/yolov5// the ncnn model https://github.com/nihui/ncnn-assets/tree/master/models #if YOLOV5_V60int ok0 = m_yolov5.load_param(param_file);int ok1 = m_yolov5.load_model(bin_file); #elseyolov5.register_custom_layer("YoloV5Focus", YoloV5Focus_layer_creator);yolov5.load_param("yolov5s.param");yolov5.load_model("yolov5s.bin"); #endifreturn ok0 + ok1; } int Yolov5::detect_yolov5(cv::Mat image, std::vector<Object>& objects) {int img_w = image.cols;int img_h = image.rows;// letterbox pad to multiple of MAX_STRIDEint w = img_w;int h = img_h;float scale = 1.f;if (w > h){scale = (float)m_target_size / w;w = m_target_size;h = h * scale;}else{scale = (float)m_target_size / h;h = m_target_size;w = w * scale;}ncnn::Mat in = ncnn::Mat::from_pixels_resize(image.data, ncnn::Mat::PIXEL_BGR2RGB, img_w, img_h, w, h);// pad to target_size rectangle// yolov5/utils/datasets.py letterboxint wpad = (w + MAX_STRIDE - 1) / MAX_STRIDE * MAX_STRIDE - w;int hpad = (h + MAX_STRIDE - 1) / MAX_STRIDE * MAX_STRIDE - h;ncnn::Mat in_pad;ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, ncnn::BORDER_CONSTANT, 114.f);const float norm_vals[3] = { 1 / 255.f, 1 / 255.f, 1 / 255.f };in_pad.substract_mean_normalize(0, norm_vals);ncnn::Extractor ex = m_yolov5.create_extractor();ex.input("images", in_pad);std::vector<Object> proposals;// anchor setting from yolov5/models/yolov5s.yaml// stride 8{ncnn::Mat out;ex.extract("output", out);ncnn::Mat anchors(6);anchors[0] = 10.f;anchors[1] = 13.f;anchors[2] = 16.f;anchors[3] = 30.f;anchors[4] = 33.f;anchors[5] = 23.f;std::vector<Object> objects8;generate_proposals(anchors, 8, in_pad, out, m_prob_threshold, objects8);proposals.insert(proposals.end(), objects8.begin(), objects8.end());}// stride 16{ncnn::Mat out; #if YOLOV5_V60ex.extract("376", out); #elseex.extract("781", out); #endifncnn::Mat anchors(6);anchors[0] = 30.f;anchors[1] = 61.f;anchors[2] = 62.f;anchors[3] = 45.f;anchors[4] = 59.f;anchors[5] = 119.f;std::vector<Object> objects16;generate_proposals(anchors, 16, in_pad, out, m_prob_threshold, objects16);proposals.insert(proposals.end(), objects16.begin(), objects16.end());}// stride 32{ncnn::Mat out; #if YOLOV5_V60ex.extract("401", out); #elseex.extract("801", out); #endifncnn::Mat anchors(6);anchors[0] = 116.f;anchors[1] = 90.f;anchors[2] = 156.f;anchors[3] = 198.f;anchors[4] = 373.f;anchors[5] = 326.f;std::vector<Object> objects32;generate_proposals(anchors, 32, in_pad, out, m_prob_threshold, objects32);proposals.insert(proposals.end(), objects32.begin(), objects32.end());}// sort all proposals by score from highest to lowestqsort_descent_inplace(proposals);// apply nms with nms_thresholdstd::vector<int> picked;nms_sorted_bboxes(proposals, picked, m_nms_threshold);int count = picked.size();objects.resize(count);for (int i = 0; i < count; i++){objects[i] = proposals[picked[i]];// adjust offset to original unpaddedfloat x0 = (objects[i].rect.x - (wpad / 2)) / scale;float y0 = (objects[i].rect.y - (hpad / 2)) / scale;float x1 = (objects[i].rect.x + objects[i].rect.width - (wpad / 2)) / scale;float y1 = (objects[i].rect.y + objects[i].rect.height - (hpad / 2)) / scale;// clipx0 = std::max(std::min(x0, (float)(img_w - 1)), 0.f);y0 = std::max(std::min(y0, (float)(img_h - 1)), 0.f);x1 = std::max(std::min(x1, (float)(img_w - 1)), 0.f);y1 = std::max(std::min(y1, (float)(img_h - 1)), 0.f);objects[i].rect.x = x0;objects[i].rect.y = y0;objects[i].rect.width = x1 - x0;objects[i].rect.height = y1 - y0;}draw_objects(image, objects);return 0;}void Yolov5::draw_objects(const cv::Mat& image, const std::vector<Object>& objects) {static const char* class_names[] = {"person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light","fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow","elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee","skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard","tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple","sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch","potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone","microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear","hair drier", "toothbrush"};for (size_t i = 0; i < objects.size(); i++){const Object& obj = objects[i];fprintf(stderr, "%d = %.5f at %.2f %.2f %.2f x %.2f\n", obj.label, obj.prob,obj.rect.x, obj.rect.y, obj.rect.width, obj.rect.height);cv::rectangle(image, obj.rect, cv::Scalar(255, 0, 0));char text[256];sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100);int baseLine = 0;cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);int x = obj.rect.x;int y = obj.rect.y - label_size.height - baseLine;if (y < 0)y = 0;if (x + label_size.width > image.cols)x = image.cols - label_size.width;cv::rectangle(image, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)),cv::Scalar(255, 255, 255), -1);cv::putText(image, text, cv::Point(x, y + label_size.height),cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));}// cv::imshow("demo", image);//cv::waitKey(0);//return image; }

同時(shí)將構(gòu)建的工程設(shè)置一下

?先測試一下生成exe是沒有問題的,然后在生成dll動態(tài)庫,去修改一下c#的代碼,進(jìn)行聯(lián)調(diào)即可

c#的工程也需要設(shè)置一下

c# Program.cs文件內(nèi)容不變

using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; using System.IO; using System.Runtime.InteropServices; using OpenCvSharp; using System.Drawing; using OpenCvSharp.Extensions; using System.Text;namespace WindowsFormsApp1 {static class Program{[DllImport(@"F:\sxj\20211108\detectYolov5Ncnn\x64\Release\detectYolov5Ncnn.dll",CharSet = CharSet.Ansi,CallingConvention = CallingConvention.StdCall)]public static extern int init_model(StringBuilder model_param, StringBuilder model_bin);/// <summary>/// 應(yīng)用程序的主入口點(diǎn)。/// </summary>[STAThread]static void Main(){StringBuilder model_param = new StringBuilder("F:\\sxj\\20211201\\yolov5s_6.0.param");StringBuilder model_bin = new StringBuilder("F:\\sxj\\20211201\\yolov5s_6.0.bin");init_model(model_param, model_bin);Application.EnableVisualStyles();Application.SetCompatibleTextRenderingDefault(false);Application.Run(new Form1());}} }

Form1.cs文件修改一下,寫了個只支持單檢測類,好像很復(fù)雜 c#和c++ 進(jìn)行托管內(nèi)存和非托管內(nèi)存?zhèn)鬟f,看的msdn有點(diǎn)復(fù)雜

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;using OpenCvSharp; using System.Runtime.InteropServices; using OpenCvSharp.Extensions; using System.IO.Compression; using System.Drawing.Imaging;namespace WindowsFormsApp1 {public partial class Form1 : Form{[DllImport(@"F:\sxj\20211108\detectYolov5Ncnn\x64\Release\detectYolov5Ncnn.dll", CallingConvention = CallingConvention.StdCall)]public static extern int detect_image(byte[] ImageBuffer, byte[] ImageResult, int imageHeight, int imageWidth , IntPtr ptrItem);[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]public struct DefectResult{public int label;public float prob;public int x;public int y;public int width;public int height;}public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){OpenFileDialog openFileDialog = new OpenFileDialog();openFileDialog.Filter = @"jpeg|*.jpg|bmp|*.bmp|gif|*.gif";if (openFileDialog.ShowDialog() == DialogResult.OK){string fullpath = openFileDialog.FileName;FileStream fs = new FileStream(fullpath, FileMode.Open);byte[] picturebytes = new byte[fs.Length];BinaryReader br = new BinaryReader(fs);picturebytes = br.ReadBytes(Convert.ToInt32(fs.Length));MemoryStream ms = new MemoryStream(picturebytes);Bitmap bmpt = new Bitmap(ms);pictureBox1.Image = bmpt;pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;}else{MessageBox.Show("圖片打開失敗");}}private void button2_Click(object sender, EventArgs e){SaveFileDialog saveImageDialog = new SaveFileDialog();saveImageDialog.Title = "圖片保存";saveImageDialog.Filter = @"jpeg|*.jpg|bmp|*.bmp";saveImageDialog.FileName = System.DateTime.Now.ToString("yyyyMMddHHmmss");//設(shè)置默認(rèn)文件名if (saveImageDialog.ShowDialog() == DialogResult.OK){string fileName = saveImageDialog.FileName.ToString();//Console.WriteLine("fileName" + fileName);if (fileName != "" && fileName != null){string fileExtName = fileName.Substring(fileName.LastIndexOf(".") + 1).ToString();//Console.WriteLine("fileExtName" + fileExtName);System.Drawing.Imaging.ImageFormat imgformat = null;if (fileExtName != ""){switch (fileExtName){case "jpg":imgformat = System.Drawing.Imaging.ImageFormat.Jpeg;break;case "bmp":imgformat = System.Drawing.Imaging.ImageFormat.Bmp;break;default:imgformat = System.Drawing.Imaging.ImageFormat.Jpeg;break;}try{Bitmap bit = new Bitmap(pictureBox2.Image);MessageBox.Show(fileName);pictureBox2.Image.Save(fileName, imgformat);}catch{}}}}}private void button3_Click(object sender, EventArgs e){int workStationCount = 1;int size = Marshal.SizeOf(typeof(DefectResult)) * workStationCount;byte[] bytes = new byte[size];IntPtr infosIntptr = Marshal.AllocHGlobal(size);DefectResult[] pClass = new DefectResult[workStationCount];Bitmap bmp = (Bitmap)pictureBox1.Image.Clone();byte[] source = GetBGRValues(bmp);byte[] dest = source;detect_image(source, dest, bmp.Height, bmp.Width, infosIntptr);string[] class_names = new string[]{"person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light","fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow","elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee","skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard","tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple","sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch","potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone","microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear","hair drier", "toothbrush"};for (int inkIndex = 0; inkIndex < workStationCount; inkIndex++){IntPtr pPonitor = new IntPtr(infosIntptr.ToInt64() + Marshal.SizeOf(typeof(DefectResult)) * inkIndex);pClass[inkIndex] = (DefectResult)Marshal.PtrToStructure(pPonitor, typeof(DefectResult));Console.WriteLine("{0} ", pClass[inkIndex].prob);Console.WriteLine("{0} ", class_names[pClass[inkIndex].label]);Console.WriteLine("{0} ", pClass[inkIndex].x);Console.WriteLine("{0} ", pClass[inkIndex].y);Console.WriteLine("{0} ", pClass[inkIndex].width);Console.WriteLine("{0} ", pClass[inkIndex].height);}Marshal.FreeHGlobal(infosIntptr);Bitmap bmpConvert = Byte2Bitmap(dest, bmp.Width, bmp.Height);Image images = bmpConvert;pictureBox2.Image = images;pictureBox2.SizeMode = PictureBoxSizeMode.StretchImage;}public static byte[] GetBGRValues(Bitmap bmp){var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);var bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);var rowBytes = bmpData.Width * Image.GetPixelFormatSize(bmp.PixelFormat) / 8;var imgBytes = bmp.Height * rowBytes;byte[] rgbValues = new byte[imgBytes];IntPtr ptr = bmpData.Scan0;for (var i = 0; i < bmp.Height; i++){Marshal.Copy(ptr, rgbValues, i * rowBytes, rowBytes);ptr += bmpData.Stride;}bmp.UnlockBits(bmpData);return rgbValues;}public static Bitmap Byte2Bitmap(Byte[] data, int width, int height){Bitmap image = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);Rectangle rect = new Rectangle(0, 0, image.Width, image.Height);BitmapData bmData = image.LockBits(rect, ImageLockMode.ReadWrite, image.PixelFormat);IntPtr ptr = bmData.Scan0;for (int i = 0; i < image.Height; i++){Marshal.Copy(data, i * image.Width * 3, ptr, image.Width * 3);ptr = (IntPtr)(ptr.ToInt64() + bmData.Stride);}image.UnlockBits(bmData);return image;}private void pictureBox1_Click(object sender, EventArgs e){}} }

然后使用debug模式或者直接release模式輸出一下 就可看到 在c++ 中完成了繪圖功能,也可以把類別信息返回了

附錄一下debug調(diào)試結(jié)果

還是那位可愛的小姐姐

注意 c#中的圖片高 寬的參數(shù)與 c++的高寬 對應(yīng)一致~~~

如果需要從c++的dll傳遞變長的數(shù)據(jù)結(jié)構(gòu)給c#,可以使用在c++ 使用rapidjson組成字符串,然后賦值給char 數(shù)組,然后在c#序列化成json就可以完成多目標(biāo)數(shù)據(jù)遞送

48、OAK通過共享內(nèi)存?zhèn)鬟f變長結(jié)構(gòu)體(Rapidjson)進(jìn)行數(shù)據(jù)和圖片交互_天晝AI實(shí)驗(yàn)室的博客-CSDN博客

總結(jié)

以上是生活随笔為你收集整理的60、在Visual Studio 2019 环境下,使用C#调用C++生成的dll实现yolov5的图片检测的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

国产99久久久久久免费看 | 福利视频精品 | 九九电影在线 | 亚洲黄色av一区 | 亚洲一区二区精品 | 欧美性色黄 | 亚洲一区欧美激情 | 精品国产一区二区三区久久 | 久草资源免费 | 亚洲精品乱码久久久久久写真 | 伊人资源视频在线 | 超碰免费在线公开 | www.久久爱.cn | 777久久久| 久久tv视频 | 中文字幕在线观看完整 | 欧美在线1| 最新精品视频在线 | 91亚洲影院 | 国产精品1区 | 国产一级在线 | 亚洲天天综合 | 精品 一区 在线 | 日韩精品一区二区在线观看 | www日日夜夜 | 亚洲在线成人精品 | 亚洲国产中文字幕 | 久久久精品久久 | 韩国视频一区二区三区 | 国内精品久久久久影院男同志 | 国产精品mv | 在线免费黄色 | 亚洲欧洲国产视频 | 99九九免费视频 | 91麻豆精品国产91久久久久久久久 | 欧美日韩成人一区 | 欧美精品免费一区二区 | 日免费视频 | 国产日韩欧美精品在线观看 | 一级大片在线观看 | 久草香蕉在线 | 懂色av懂色av粉嫩av分享吧 | 国内精品视频免费 | 国产中文字幕视频在线观看 | 国产成人香蕉 | 一区三区在线欧 | 狠狠狠色丁香综合久久天下网 | 91九色蝌蚪国产 | 久久久www成人免费精品张筱雨 | 在线一区观看 | 天天色天天色 | 午夜视频亚洲 | 天天干天天弄 | 国产一区视频在线观看免费 | 久久美女视频 | 免费国产在线精品 | 九九热久久久 | 久久久久亚洲精品成人网小说 | 日韩网站视频 | 国产一卡久久电影永久 | 人人草人人草 | 日韩a级黄色 | 四虎影视av | 国产成人综合精品 | 国产视频丨精品|在线观看 国产精品久久久久久久久久久久午夜 | 国产亚洲视频在线 | 91精品国产一区二区在线观看 | 久久躁日日躁aaaaxxxx | 久草视频99 | 国产午夜精品福利视频 | av一区二区三区在线 | 精品国产精品国产偷麻豆 | 免费三及片 | 精品美女在线观看 | 欧美日韩一级在线 | 日韩视频免费看 | 国产黄色电影 | 操操操干干干 | 综合久久久久久 | 成人免费在线视频观看 | 日日操狠狠干 | 国产一级电影在线 | 亚洲精品www. | 国内免费久久久久久久久久久 | 不卡的av在线播放 | 久久国产精品系列 | 高潮毛片无遮挡高清免费 | 超碰在线成人 | 伊人天天操 | 啪嗒啪嗒免费观看完整版 | 最近中文字幕免费 | 色姑娘综合 | 成人免费在线视频观看 | 在线观看的a站 | www.国产高清 | 午夜精品福利在线 | 精品超碰| 久久久久久国产精品 | 丰满少妇在线观看 | 国产日韩视频在线 | av超碰在线 | 99热国内精品 | 中字幕视频在线永久在线观看免费 | 天天操福利视频 | 波多野结依在线观看 | 在线观看日韩 | 视频三区在线 | 亚洲精品乱码久久久久久写真 | www.五月天 | 黄色精品一区 | 天堂av色婷婷一区二区三区 | 亚洲黄色免费电影 | 亚洲热视频 | 色婷婷狠 | 亚洲理论在线观看 | 午夜91视频 | 美女黄网站视频免费 | 91视频在线免费下载 | 色综合国产| 国产一区二区中文字幕 | 欧洲一区二区在线观看 | 久久精品中文字幕一区二区三区 | 奇米网777| 韩日电影在线观看 | 伊人久久影视 | 国产录像在线观看 | 国产日韩视频在线 | av解说在线观看 | 丁香六月激情婷婷 | 国产成人三级在线观看 | 中文av不卡 | 毛片一级免费一级 | 日韩欧美在线第一页 | 在线精品视频在线观看高清 | 精品视频在线观看 | 手机在线看片日韩 | 青青河边草手机免费 | 一本色道久久综合亚洲二区三区 | 波多野结衣电影久久 | 国产裸体bbb视频 | 国产男女无遮挡猛进猛出在线观看 | 国产黄色片免费观看 | 日日操操操 | 黄色中文字幕 | 亚欧洲精品视频在线观看 | 97在线视频免费看 | 国产探花| 免费男女网站 | 九色自拍视频 | 久久国产精品免费看 | 一本色道久久综合亚洲二区三区 | 亚洲精品视频在线播放 | 日韩精品一二三 | 成人久久18免费网站图片 | 操操操人人人 | 日韩精品欧美视频 | 久久久精品国产一区二区电影四季 | 免费观看性生交大片3 | 天天射天天射 | 欧美一区二区三区特黄 | 国产精品久免费的黄网站 | 日批视频在线播放 | av在线在线 | 日韩精品免费一区二区在线观看 | 日本91在线| 91自拍视频在线观看 | 国产不卡在线 | 亚洲成年片 | 成人免费影院 | 日韩在线电影观看 | 在线视频欧美日韩 | 九九天堂 | 欧美日韩调教 | 狠狠色噜噜狠狠狠狠 | 国产精品麻豆99久久久久久 | 狠狠干狠狠插 | 日韩中文幕 | 中文字幕一区二区三区久久蜜桃 | 狠狠操狠狠操 | 亚洲欧美日韩国产精品一区午夜 | 九九九热精品免费视频观看 | 国产欧美日韩一区 | 亚洲国产精久久久久久久 | 亚洲精品日韩一区二区电影 | 91一区啪爱嗯打偷拍欧美 | 国产精品激情 | 996久久国产精品线观看 | 中文字幕色网站 | 色婷婷激情综合 | 国产中文在线播放 | 四虎在线视频免费观看 | 色婷在线 | 国产91免费在线观看 | 日本黄网站 | 天堂av高清 | 91精品欧美一区二区三区 | 岛国大片免费视频 | 成人91在线观看 | 在线观看亚洲成人 | 99中文字幕视频 | 激情五月播播久久久精品 | 天天操天天射天天添 | 18国产精品白浆在线观看免费 | 18性欧美xxxⅹ性满足 | 国产精品av久久久久久无 | 久久久国产精品免费 | 欧美日本国产在线观看 | 久久人人爽av | 粉嫩av一区二区三区四区五区 | 亚洲高清久久久 | 四虎www com| 成年人免费在线播放 | 国产二区视频在线观看 | 久久一区91| www91在线观看 | 国产在线毛片 | 日韩特级毛片 | 五月激情久久久 | 日本aaa在线观看 | 天天草天天干天天射 | 天天综合视频在线观看 | a级国产乱理论片在线观看 伊人宗合网 | 欧美日韩不卡在线观看 | 久久视频网 | 天天搞天天 | 在线观看免费高清视频大全追剧 | 色网站免费在线观看 | 欧美精品免费在线观看 | 国产精品久久久久久久久久久不卡 | 美女视频黄的免费的 | 亚洲精品女人久久久 | 久久影院午夜论 | 国产黄色精品 | 国产精品一区二区免费在线观看 | 免费高清国产 | 日韩电影精品 | 字幕网在线观看 | 天天操狠狠操夜夜操 | 国产一区在线观看免费 | 久久国产免| 99精品一区 | 91香蕉视频在线下载 | av黄免费看 | 午夜电影中文字幕 | 99久久99久久精品国产片果冰 | 成人av一区二区兰花在线播放 | 久精品在线 | 少妇bbw搡bbbb搡bbbb | 69久久夜色精品国产69 | 99在线国产 | av电影在线免费 | 91自拍91| 亚州国产精品视频 | 国产黄色大片 | 97成人精品区在线播放 | 麻豆免费视频网站 | 欧美色图亚洲图片 | 蜜臀av在线一区二区三区 | 欧美精品v国产精品v日韩精品 | 色婷五月 | 亚洲一区二区精品3399 | 欧美精品成人在线 | 久久黄色网页 | 久久综合久久综合这里只有精品 | 超碰97人人在线 | 99精品视频一区 | 天天射天 | 9ⅰ精品久久久久久久久中文字幕 | 久久视了 | 黄污污网站 | 狠狠色丁香婷婷综合久久片 | 349k.cc看片app| 日韩女同一区二区三区在线观看 | 中文字幕在线精品 | 2019天天干夜夜操 | 在线观看黄色大片 | 91麻豆精品国产91久久久久久久久 | 欧美另类交人妖 | 国内精品视频免费 | 激情五月播播久久久精品 | 免费高清男女打扑克视频 | 一区二区三区在线免费观看视频 | www.久久91| 久草五月| 黄色电影在线免费观看 | 亚洲精品视频网站在线观看 | 九九99靖品 | 午夜久久久久 | 色网站在线观看 | 久久久高清 | 欧美色久 | 成年人电影免费在线观看 | 日韩偷拍精品 | 99久久久国产精品免费99 | 999色视频| 欧美成人影音 | 福利视频网址 | 亚洲免费视频观看 | 三级免费黄 | 一本一本久久a久久精品牛牛影视 | 国产精品午夜久久久久久99热 | 日日弄天天弄美女bbbb | 亚洲视频免费视频 | 日韩大片在线观看 | 国产视频一区在线播放 | 中文字幕一区2区3区 | 成人免费xyz网站 | 玖玖爱国产在线 | 久99久精品视频免费观看 | 在线看欧美 | 97在线观看视频 | 国产精品免费人成网站 | 美女精品久久 | www国产亚洲 | 国产群p| 人人干97 | 久久久国产精品网站 | 中文字幕在线观看不卡 | 久草在线观 | 精品视频在线免费观看 | 国产高h视频 | 亚洲国产一区av | 99综合电影在线视频 | 久久久免费看视频 | www.神马久久 | 久久免费精品国产 | aaa日本高清在线播放免费观看 | 精品国模一区二区三区 | 国产精品99久久久久久有的能看 | 久久精品日产第一区二区三区乱码 | 狠狠干婷婷 | 日韩理论在线视频 | 高清av在线免费观看 | 国产成人精品一二三区 | 久久黄色免费观看 | 久久久久久久久影院 | 午夜av一区二区三区 | 久久久国产精品久久久 | 毛片基地黄久久久久久天堂 | 日韩欧美国产精品 | 国产在线免费观看 | 永久免费观看视频 | 五月天婷婷狠狠 | av中文天堂在线 | 国产一级电影网 | 日本在线观看一区二区三区 | 久久久www成人免费精品张筱雨 | 99视频免费看| 亚洲色图色| 久久在草 | 美女福利视频一区二区 | 97精品在线观看 | 欧美一级片在线观看视频 | 日韩精品一区二区三区高清免费 | 在线播放国产精品 | 色婷婷视频| 国产剧情av在线播放 | 亚洲日本韩国一区二区 | 国产精品白浆视频 | 欧美作爱视频 | 天无日天天操天天干 | 不卡av电影在线 | 99产精品成人啪免费网站 | 久草精品在线播放 | 人人澡澡人人 | 在线电影中文字幕 | 婷婷在线不卡 | 四虎影视精品成人 | 92av视频| 色偷偷人人澡久久超碰69 | av片子在线观看 | 中文在线中文资源 | av黄在线播放| 日韩网站在线 | 国产又粗又长又硬免费视频 | 在线国产黄色 | 又色又爽又黄 | 91九色在线观看视频 | 国产精品美女毛片真酒店 | 久久国产精品99久久久久久进口 | 久草在线一免费新视频 | www黄色软件 | 国内精品久久久久影院一蜜桃 | 亚洲国产99 | 美女网站视频免费都是黄 | 人人狠 | 天天综合入口 | 午夜.dj高清免费观看视频 | 色综合久久久久综合体桃花网 | 在线观看91久久久久久 | 欧美成年人在线观看 | 久久成人综合 | 在线观看91精品视频 | 99在线视频免费观看 | 色吊丝在线永久观看最新版本 | 国产特级毛片aaaaaaa高清 | 国产不卡在线观看 | 激情五月在线观看 | 国产原创在线观看 | 97精品国产91久久久久久 | 中文字幕在线播放日韩 | 最新国产精品久久精品 | 91麻豆精品久久久久久 | 97超碰在线久草超碰在线观看 | 九九九在线 | 国产精品18久久久久久vr | 麻豆精品国产传媒 | 999久久a精品合区久久久 | 午夜电影久久久 | 最新av网址大全 | 激情导航| 欧美久久久久久久久久久久久 | 天天人人综合 | 久久成年人网站 | 久久精品99 | 久久久久女人精品毛片九一 | 菠萝菠萝在线精品视频 | 四虎影视av | 国产群p视频 | 黄色的视频 | 精品国产乱码久久久久久1区二区 | 波多野结衣电影一区二区 | 黄色免费在线视频 | 免费黄色在线网址 | 日韩欧美网址 | 亚洲理论视频 | 九九在线国产视频 | 一本到在线 | 日本性生活一级片 | 久久99热久久99精品 | 九九热免费在线观看 | 欧美日在线观看 | 国产精品嫩草在线 | 狠狠躁夜夜躁人人爽视频 | 成人av一区二区兰花在线播放 | 日韩av片免费在线观看 | 免费a网 | 日本视频精品 | 91探花在线视频 | 欧美大片第1页 | 亚洲激情在线播放 | 亚洲免费观看在线视频 | 国产精品第一 | 欧美精品九九99久久 | 色多视频在线观看 | 国内精品一区二区 | 视频成人| 国产精品黄色在线观看 | 免费三级大片 | 久久综合9988久久爱 | 国产精品成人一区二区 | 欧美精品一二 | 国产传媒中文字幕 | 欧美日韩高清一区二区 国产亚洲免费看 | 一区二区三区高清在线 | www.天天干.com| 精品一区电影 | 日韩视频免费 | 国产 日韩 欧美 自拍 | 涩五月婷婷 | 国产一区二区三区免费视频 | 日韩免费在线一区 | 国产精品日韩久久久久 | 久久免费视频这里只有精品 | 91在线视频播放 | 午夜精品一区二区三区在线视频 | 亚洲一区二区视频在线播放 | 天天色天天草天天射 | 香蕉国产91 | 国产h在线观看 | 亚洲精品国产精品久久99热 | 日韩一级成人av | 97超碰人人澡 | 丰满少妇在线观看资源站 | 国产美女网站在线观看 | 亚洲免费在线视频 | 国产精品欧美一区二区三区不卡 | 精品国产一区二区三区日日嗨 | 亚洲欧美激情插 | 亚洲精品美女在线 | 国产一区二区视频在线 | 天天干天天干天天色 | 开心激情婷婷 | 久久99偷拍视频 | 国产视频久久久久 | 黄色免费网站下载 | 中文字幕在线播放一区 | 91视频在线国产 | 玖玖精品在线 | 精品成人免费 | 国产粉嫩在线观看 | 久久精品一| 久久99在线视频 | 99久久精品国产观看 | 欧美激情综合五月色丁香 | 婷婷色影院 | 亚洲精品视频在线免费播放 | 日韩最新av在线 | 久草在线久草在线2 | 日韩网站在线 | 日韩高清免费在线观看 | 精品字幕 | 日韩中文字幕第一页 | 欧美日韩视频在线观看一区二区 | 91免费高清观看 | 国产1级视频 | 午夜视频在线观看一区二区三区 | 中文字幕精品一区久久久久 | 日韩无在线| 精品一区二区免费在线观看 | 成人国产精品久久久久久亚洲 | 成人va视频| 亚洲欧洲中文日韩久久av乱码 | 不卡视频一区二区三区 | 首页av在线| 欧美日韩在线精品 | 99热在线看 | 久草在线久草在线2 | 国产精品久久久久久久午夜片 | 亚洲精品影视在线观看 | 黄色毛片网站在线观看 | 香蕉蜜桃视频 | 91视频高清完整版 | 精品产品国产在线不卡 | 九九久久久| 在线免费视频 你懂得 | 成人久久精品 | 射射色 | 国产手机视频在线观看 | 黄色国产高清 | 国产福利av | 在线免费视频a | 97手机电影网 | 91精品91 | 国产美女在线观看 | 在线观看视频黄 | 久久久久免费精品国产小说色大师 | 精品国产一区二区三区在线观看 | 亚洲国产成人久久综合 | 日韩色视频在线观看 | 久久精品综合视频 | 精品一二三区 | 亚洲精品在线观看免费 | 亚洲国产精品电影在线观看 | 99超碰在线播放 | 黄色91在线观看 | 国产一区二区综合 | 亚洲高清色综合 | 亚洲一区久久久 | 狠狠色综合网站久久久久久久 | 午夜av免费观看 | 久久超碰免费 | 天天草网站| 最近日本韩国中文字幕 | 日韩一二区在线观看 | 久久嗨 | 97超视频免费观看 | av一区二区三区在线 | 日韩精品一区二区三区第95 | 欧美日韩精品在线视频 | 国产精品久久一区二区无卡 | 在线色视频小说 | 午夜成人影视 | 天天弄天天操 | 人人干狠狠操 | 欧美另类xxx | 特级西西444www高清大视频 | 一区中文字幕在线观看 | 久久精品国产亚洲精品2020 | 91精品入口| 久久精品99久久久久久 | 国产精品免费久久久久久 | 国产精品亚洲综合久久 | 亚洲理论影院 | 99草视频在线观看 | 日韩精品免费一区二区三区 | 欧美日韩一区二区三区不卡 | 久久久久久久久久久久久久av | 色av网站| 久久综合电影 | 青青草在久久免费久久免费 | 婷婷在线视频 | 在线播放精品一区二区三区 | 精品一区二区三区久久 | 国产精品久久久久久久久免费看 | 亚洲精品免费在线视频 | 欧美另类xxxx | 日本中文字幕在线视频 | 国产精品久久久久久久久久了 | 成年人av在线播放 | 一级淫片在线观看 | 亚洲h在线播放在线观看h | 91福利视频免费 | 日韩草比 | 成人精品久久 | 国产精品久久久久久吹潮天美传媒 | 美女网站视频免费都是黄 | 欧美污污网站 | 国产高清在线a视频大全 | 蜜臀久久99静品久久久久久 | 狠狠狠色丁香婷婷综合激情 | 欧美日韩一区二区三区在线观看视频 | 亚洲成人精品久久 | 在线а√天堂中文官网 | 中文字幕 欧美性 | 玖玖在线免费视频 | 99精品视频在线观看播放 | 韩国av电影在线观看 | 91网站在线视频 | 玖玖精品视频 | 中文字幕一区二区三区久久蜜桃 | 香蕉久久久久久久 | 亚洲精品国偷拍自产在线观看蜜桃 | 91精品影视 | 黄色精品视频 | 色久天 | 天天操天天艹 | 国产精品免费在线播放 | 丰满少妇麻豆av | 久久99国产精品自在自在app | 天天曰视频| 日韩精品一区在线观看 | 视频一区二区在线观看 | 久久黄色免费视频 | 国产一区二区在线看 | 久久成年人视频 | 日韩电影在线观看中文字幕 | 国产中文字幕久久 | 日韩色在线 | 91欧美国产 | 日韩在线播放视频 | 久久字幕精品一区 | 国产精品二区在线观看 | 在线观看视频精品 | 天天摸天天操天天爽 | 中国一级特黄毛片大片久久 | 成人午夜电影久久影院 | 91成年人在线观看 | 24小时日本在线www免费的 | 日韩美女高潮 | 黄网站色视频 | 黄色av电影一级片 | 久久艹人人 | 91av视频观看 | 激情婷婷av | 日韩欧美69 | 成人国产精品入口 | 成人一区二区三区在线 | 香蕉视频久久 | 2021国产视频 | 国产1区在线观看 | 精品在线观看免费 | 久久精品看片 | 婷婷日| 日韩精品在线免费观看 | 97超碰人人 | 在线观看成人网 | 黄色www免费| 国产日产亚洲精华av | 在线亚洲小视频 | 丁香婷婷综合激情五月色 | 五月激情电影 | 蜜臀一区二区三区精品免费视频 | 国产亚洲精品美女 | 丁香婷婷激情啪啪 | 久久五月激情 | 免费在线观看一级片 | 日本久久99 | 日韩免费在线网站 | 国产精品美女毛片真酒店 | 天天综合网久久 | 日韩视频中文字幕 | 久久久精品国产免费观看一区二区 | 黄色a级片在线观看 | 久久黄网站 | 成人精品亚洲 | 欧美国产91 | 深夜免费福利视频 | 91热视频在线观看 | 手机av电影在线 | 欧美性一级观看 | 国产免费亚洲高清 | 午夜视频在线观看一区二区三区 | 五月婷婷婷婷婷 | 亚洲三级性片 | 伊人婷婷网| 四虎8848免费高清在线观看 | 99精品国产99久久久久久97 | 天天干,夜夜操 | 亚洲色图27p | 亚洲免费婷婷 | 国产成人精品久久 | 精品在线看 | 91人人视频在线观看 | 天天天色| 手机看片久久 | 国产精品一区二区av麻豆 | 欧美一区在线观看视频 | 又黄又刺激又爽的视频 | 久草a在线 | 国产伦精品一区二区三区… | 中文字幕影视 | 三级av在线 | 亚洲国产黄色片 | 亚洲视频大全 | 91精品国产91p65 | 91在线永久| 亚洲精品女人久久久 | 麻豆传媒视频观看 | 色婷婷国产 | 丁香花中文在线免费观看 | 视频一区二区国产 | 天天操人| 最近中文字幕完整视频高清1 | 香蕉视频在线看 | 一本一道久久a久久综合蜜桃 | 亚洲精品视频在线观看网站 | 国产成人久久久久 | 丰满少妇对白在线偷拍 | 久草在| 欧美日韩国产一区二区三区 | 天天干天天爽 | 国产99久久精品一区二区永久免费 | 国产精品久久久av | 亚洲精品成人av在线 | 久久免费毛片 | 91精品视频免费在线观看 | 国产中文字幕久久 | 91欧美日韩国产 | 国产亚洲精品美女 | 精品国产亚洲一区二区麻豆 | 欧美精品在线观看免费 | 欧美性生活大片 | 69精品人人人人 | 97人人澡人人爽人人模亚洲 | 亚洲精品成人 | 国产精品成人在线观看 | 中文日韩在线视频 | 在线播放日韩 | 中文字幕在线观看完整版 | 亚洲黄污 | 91精选在线 | 久久久免费av | 激情在线免费视频 | 亚洲一区精品二人人爽久久 | 久久久久久国产精品免费 | 久久伊人精品天天 | av成人资源| 亚洲国产影院 | 日韩av在线看 | 国产精品国内免费一区二区三区 | 在线日本v二区不卡 | 中文字幕有码在线 | 日韩美av在线 | 欧美成天堂网地址 | 人人插人人 | 国产午夜精品一区二区三区在线观看 | 欧美二区三区91 | 欧美日韩精品在线一区二区 | 九九九九热精品免费视频点播观看 | www.日日操.com| 夜色.com| 国产九九九九九 | 丁香综合激情 | www.伊人网| 国产黄网在线 | 婷婷丁香自拍 | 精品一区二区亚洲 | 国产精品国产三级国产不产一地 | 国产粉嫩在线 | 久久精品视频免费 | 在线观看黄色的网站 | 91精品久久久久久 | 久久精品看 | 午夜在线免费观看视频 | 精品女同一区二区三区在线观看 | 国产精品久久久久久久免费观看 | 激情视频在线高清看 | 日韩精品中文字幕在线播放 | 国产第一页在线观看 | 国产亚洲欧美一区 | 天天色天天草天天射 | 九九色在线观看 | 久久免费视频在线观看6 | av电影在线免费 | 欧美精品久久久久久久免费 | 国产精品免费麻豆入口 | 中文字幕亚洲在线观看 | 99热播精品 | 狠狠色丁香婷婷 | av在线永久免费观看 | 精品a视频 | 国产在线无 | 九九视频在线 | 亚洲视频2 | 日韩中文字| 亚洲黄色在线观看 | 日本护士三级少妇三级999 | 中文字幕二区 | 友田真希av | 黄色一级影院 | 一区 二区电影免费在线观看 | 国产一级黄 | 日韩理论在线播放 | 久久不卡国产精品一区二区 | 欧美最爽乱淫视频播放 | 国产精品日韩在线观看 | 福利网址在线观看 | 久久a视频| 久久综合狠狠综合 | 黄色av一区二区 | 久久久国产精品网站 | 91九色porny在线| 在线观看精品一区 | 国产精品igao视频网网址 | 精品国产一区二区三区蜜臀 | 中文字幕在线观看第三页 | 精品一区二区免费 | 国产一级二级在线播放 | 激情在线五月天 | 一区二区丝袜 | 特级免费毛片 | 日本久久片 | 亚洲精品高清在线观看 | 久久午夜免费视频 | 久久免费99精品久久久久久 | 天天舔天天搞 | 免费午夜av | a在线一区 | 成人高清在线 | 日韩视频一区二区在线观看 | 99色人| 一 级 黄 色 片免费看的 | 亚洲精品国产视频 | 91在线免费公开视频 | 国产精品系列在线播放 | 国产精品久久久久久久99 | 色网站免费在线看 | 国产精品福利久久久 | 国内精品视频久久 | 久久综合激情 | 日韩精品视频在线免费观看 | 国产免费av一区二区三区 | 日韩精品欧美精品 | 在线欧美a | 亚洲国产精品一区二区久久,亚洲午夜 | 久久69精品久久久久久久电影好 | 一级黄网 | 国产中的精品av小宝探花 | 亚洲高清免费在线 | av日韩av | 亚洲成人精品av | 久久精品亚洲精品国产欧美 | 美女网站在线观看 | 国产99re| av亚洲产国偷v产偷v自拍小说 | 就要干b | 人人爽人人澡 | 色欧美综合 | 国产在线国偷精品产拍 | 久久免费片 | 国产成人综 | 国产精品成人一区二区三区吃奶 | www.com操 | 黄色www在线观看 | 免费视频黄| 99九九免费视频 | 亚洲女在线| 91视频 - v11av | 亚洲激情校园春色 | 4p变态网欧美系列 | 久久伊人精品一区二区三区 | 中文字幕在线视频网站 | 福利久久| 中文字幕中文字幕在线中文字幕三区 | 国产精品乱码一区二三区 | 黄色福利网站 | 激情视频在线观看网址 | 亚洲成熟女人毛片在线 | 国产精品va | 精品国产一区二区三区在线观看 | 91在线入口| 国产黄色片久久 | 日本久久中文 | 日本精品视频在线观看 | 亚洲伊人网在线观看 | 六月激情婷婷 | 欧美国产日韩在线视频 | 免费99视频 | 日本不卡久久 | 91麻豆精品久久久久久 | 国产视频久久 | 色婷婷狠狠操 | avcom在线| 免费在线h| 国产特级毛片aaaaaaa高清 | 国产高清不卡 | 国产日韩欧美在线播放 | 国产精品久久嫩一区二区免费 | 日韩在线免费电影 | 精品视频www| 亚洲精品乱码久久久久久9色 | 色婷婷精品 | 97精产国品一二三产区在线 | 国产一二三区在线观看 | 国产高清在线永久 | 国产大陆亚洲精品国产 | 午夜久草 | 国产一级黄色免费看 | 午夜精品一区二区三区在线观看 | 少妇性色午夜淫片aaaze | 四虎影视4hu4虎成人 | 最新成人av| 国产精品午夜久久 | 中文在线a∨在线 | 美女在线免费观看视频 | 亚洲激情久久 | 在线视频你懂 | 久草在线欧美 | 亚洲国产精品成人综合 | 日日添夜夜添 | 亚洲人成在线观看 | 午夜av电影院 | 欧美日韩国产在线一区 | 色网站视频 | 色婷婷亚洲综合 | 91精品视频在线 | 亚洲精品自在在线观看 | 久久国产精品一区二区三区 | 麻豆国产精品一区二区三区 | 日韩欧美精选 | 最近更新好看的中文字幕 | 亚洲jizzjizz日本少妇 | 成人一级片在线观看 | 免费高清影视 | 最新精品视频在线 | 亚洲精品福利在线观看 | 欧美视频在线二区 | 永久免费av在线播放 | 国内外激情视频 | 夜夜操天天操 | 玖玖999| 日韩视频区 | 91爱爱电影 | 怡红院久久 | 国产伦理久久精品久久久久_ | 91视频com| 特黄特色特刺激视频免费播放 | 手机在线看a | 色综合国产 | 亚洲天天在线日亚洲洲精 | 日韩理论在线视频 | 一区二区精品视频 | 国产精品国产三级国产aⅴ9色 | 亚洲男人天堂a | 国产精品热 | 亚洲视频一 | 成人av免费电影 | av福利超碰网站 | 69av在线播放 | 99久久er热在这里只有精品15 | 国产污视频在线观看 | 国偷自产视频一区二区久 | 天天超碰| 国产精品视频永久免费播放 | 黄色三级免费看 | 欧美一区二区伦理片 | 青青久草在线 | 国产精品18久久久 | 国产一区二区三区免费观看视频 | 国产又粗又硬又爽视频 | 亚洲黄色在线观看 | 国产一区二区不卡视频 | 免费观看www视频 | 久久国产成人午夜av影院宅 | 欧美日韩国产精品一区二区亚洲 | 2024av| 美女网站免费福利视频 | 97国产在线 | 不卡国产在线 | 天天天天色综合 | 探花视频在线观看免费版 | 国内毛片毛片 | 欧美一区二区在线刺激视频 | 视频二区在线 | 亚洲国产欧美在线人成大黄瓜 | 精品国产视频在线观看 | 天天色天天干天天色 | 久久1区 | 国产一区二区电影在线观看 | 天天色天天色天天色 | 国产资源精品在线观看 | 九九久久久 | 91九色精品女同系列 | 欧美一区中文字幕 | 免费观看午夜视频 | 国产午夜三级一区二区三 | 亚洲最新av在线网站 |