效果

项目

代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OpenCvSharp;
using System.IO;
using OpenCvSharp.Dnn;
using System.Diagnostics;
using OpenCvSharp.Extensions; namespace OpenCvSharp_YoloV3
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
} //random assign color to each label
private static readonly Scalar[] Colors = Enumerable.Repeat(false, 80).Select(x => Scalar.RandomColor()).ToArray(); //get labels from coco.names
private static readonly string[] Labels = File.ReadAllLines("coco.names").ToArray(); string cfg = "yolov3.cfg";
string model = "yolov3.weights";
const float threshold = 0.5f; //for confidence
const float nmsThreshold = 0.3f; //threshold for nms Net net; private void frmMain_Load(object sender, EventArgs e)
{
//load model and config, if you got error: "separator_index < line.size()", check your cfg file, must be something wrong.
net = CvDnn.ReadNetFromDarknet(cfg, model); #region set preferable
net.SetPreferableBackend(3);
/*
0:DNN_BACKEND_DEFAULT
1:DNN_BACKEND_HALIDE
2:DNN_BACKEND_INFERENCE_ENGINE
3:DNN_BACKEND_OPENCV
*/
net.SetPreferableTarget(0);
/*
0:DNN_TARGET_CPU
1:DNN_TARGET_OPENCL
2:DNN_TARGET_OPENCL_FP16
3:DNN_TARGET_MYRIAD
4:DNN_TARGET_FPGA
*/
#endregion
} private void button1_Click(object sender, EventArgs e)
{
if (bmp == null) return; //get image
var org = OpenCvSharp.Extensions.BitmapConverter.ToMat(bmp);//bitmap转mat
Cv2.CvtColor(org, org, ColorConversionCodes.RGBA2RGB);//mat转三通道mat //setting blob, size can be:320/416/608
//opencv blob setting can check here https://github.com/opencv/opencv/tree/master/samples/dnn#object-detection
var blob = CvDnn.BlobFromImage(org, 1.0 / 255, new OpenCvSharp.Size(416, 416), new Scalar(), true, false); //input data
net.SetInput(blob); //get output layer name
var outNames = net.GetUnconnectedOutLayersNames();
//create mats for output layer
var outs = outNames.Select(_ => new Mat()).ToArray(); #region forward model
Stopwatch sw = new Stopwatch();
sw.Start(); net.Forward(outs, outNames); sw.Stop();
Console.WriteLine("Runtime:{" + sw.ElapsedMilliseconds + "} ms");
#endregion //get result from all output
GetResult(outs, org, threshold, nmsThreshold); Bitmap Bitmap1 = BitmapConverter.ToBitmap(org);
pictureBox2.Image = Bitmap1; } /// <summary>
/// Get result form all output
/// </summary>
/// <param name="output"></param>
/// <param name="image"></param>
/// <param name="threshold"></param>
/// <param name="nmsThreshold">threshold for nms</param>
/// <param name="nms">Enable Non-maximum suppression or not</param>
private static void GetResult(IEnumerable<Mat> output, Mat image, float threshold, float nmsThreshold, bool nms = true)
{
//for nms
var classIds = new List<int>();
var confidences = new List<float>();
var probabilities = new List<float>();
var boxes = new List<Rect2d>(); var w = image.Width;
var h = image.Height;
/*
YOLO3 COCO trainval output
0 1 : center 2 3 : w/h
4 : confidence 5 ~ 84 : class probability
*/
const int prefix = 5; //skip 0~4 foreach (var prob in output)
{
for (var i = 0; i < prob.Rows; i++)
{
var confidence = prob.At<float>(i, 4);
if (confidence > threshold)
{
//get classes probability
OpenCvSharp.Point max;
OpenCvSharp.Point minLoc;
Cv2.MinMaxLoc(prob.Row[i].ColRange(prefix, prob.Cols), out minLoc, out max);
var classes = max.X;
var probability = prob.At<float>(i, classes + prefix); if (probability > threshold) //more accuracy, you can cancel it
{
//get center and width/height
var centerX = prob.At<float>(i, 0) * w;
var centerY = prob.At<float>(i, 1) * h;
var width = prob.At<float>(i, 2) * w;
var height = prob.At<float>(i, 3) * h; if (!nms)
{
// draw result (if don't use NMSBoxes)
Draw(image, classes, confidence, probability, centerX, centerY, width, height);
continue;
} //put data to list for NMSBoxes
classIds.Add(classes);
confidences.Add(confidence);
probabilities.Add(probability);
boxes.Add(new Rect2d(centerX, centerY, width, height));
}
}
}
} if (!nms) return; //using non-maximum suppression to reduce overlapping low confidence box
int[] indices;
CvDnn.NMSBoxes(boxes, confidences, threshold, nmsThreshold, out indices); Console.WriteLine("NMSBoxes drop {" + (confidences.Count - indices.Length) + "} overlapping result."); foreach (var i in indices)
{
var box = boxes[i];
Draw(image, classIds[i], confidences[i], probabilities[i], box.X, box.Y, box.Width, box.Height);
} } /// <summary>
/// Draw result to image
/// </summary>
/// <param name="image"></param>
/// <param name="classes"></param>
/// <param name="confidence"></param>
/// <param name="probability"></param>
/// <param name="centerX"></param>
/// <param name="centerY"></param>
/// <param name="width"></param>
/// <param name="height"></param>
private static void Draw(Mat image, int classes, float confidence, float probability, double centerX, double centerY, double width, double height)
{
//label formating
var label = Labels[classes] + " " + (probability * 100).ToString("0.00") + "%"; Console.WriteLine("confidence " + (confidence * 100).ToString("0.00") + "% " + label); var x1 = (centerX - width / 2) < 0 ? 0 : centerX - width / 2; //avoid left side over edge
//draw result
image.Rectangle(new OpenCvSharp.Point(x1, centerY - height / 2), new OpenCvSharp.Point(centerX + width / 2, centerY + height / 2), Colors[classes], 2); int baseline;
var textSize = Cv2.GetTextSize(label, HersheyFonts.HersheyTriplex, 0.5, 1, out baseline); Cv2.Rectangle(image, new Rect(new OpenCvSharp.Point(x1, centerY - height / 2 - textSize.Height - baseline),
new OpenCvSharp.Size(textSize.Width, textSize.Height + baseline)), Colors[classes], Cv2.FILLED); var textColor = Cv2.Mean(Colors[classes]).Val0 < 70 ? Scalar.White : Scalar.Black; Cv2.PutText(image, label, new OpenCvSharp.Point(x1, centerY - height / 2 - baseline), HersheyFonts.HersheyTriplex, 0.5, textColor);
} private string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
Bitmap bmp; private void button2_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = fileFilter;
if (ofd.ShowDialog() != DialogResult.OK) return;
var imagebyte = File.ReadAllBytes(ofd.FileName);
bmp = new Bitmap(new MemoryStream(imagebyte));
pictureBox1.Image = bmp; } }
}

Demo下载

C#OpenCvSharp YOLO v3 Demo的更多相关文章

  1. 深度学习笔记(十三)YOLO V3 (Tensorflow)

    [代码剖析]   推荐阅读! SSD 学习笔记 之前看了一遍 YOLO V3 的论文,写的挺有意思的,尴尬的是,我这鱼的记忆,看完就忘了  于是只能借助于代码,再看一遍细节了. 源码目录总览 tens ...

  2. YOLO v3

    yolo为you only look once. 是一个全卷积神经网络(FCN),它有75层卷积层,包含跳跃式传递和降采样,没有池化层,当stide=2时用做降采样. yolo的输出是一个特征映射(f ...

  3. YOLO系列:YOLO v3解析

    本文好多内容转载自 https://blog.csdn.net/leviopku/article/details/82660381 yolo_v3 提供替换backbone.要想性能牛叉,backbo ...

  4. Yolo V3整体思路流程详解!

    结合开源项目tensorflow-yolov3(https://link.zhihu.com/?target=https%3A//github.com/YunYang1994/tensorflow-y ...

  5. YOLO v3算法介绍

    图片来自https://towardsdatascience.com/yolo-v3-object-detection-with-keras-461d2cfccef6 数据前处理 输入的图片维数:(4 ...

  6. 一文看懂YOLO v3

    论文地址:https://pjreddie.com/media/files/papers/YOLOv3.pdf论文:YOLOv3: An Incremental Improvement YOLO系列的 ...

  7. YOLO V3 原理

    基本思想V1: 将输入图像分成S*S个格子,每隔格子负责预测中心在此格子中的物体. 每个格子预测B个bounding box及其置信度(confidence score),以及C个类别概率. bbox ...

  8. Pytorch从0开始实现YOLO V3指南 part5——设计输入和输出的流程

    本节翻译自:https://blog.paperspace.com/how-to-implement-a-yolo-v3-object-detector-from-scratch-in-pytorch ...

  9. Pytorch从0开始实现YOLO V3指南 part1——理解YOLO的工作

    本教程翻译自https://blog.paperspace.com/how-to-implement-a-yolo-object-detector-in-pytorch/ 视频展示:https://w ...

  10. yolo类检测算法解析——yolo v3

    每当听到有人问“如何入门计算机视觉”这个问题时,其实我内心是拒绝的,为什么呢?因为我们说的计算机视觉的发展史可谓很长了,它的分支很多,而且理论那是错综复杂交相辉映,就好像数学一样,如何学习数学?这问题 ...

随机推荐

  1. Nand flash基本原理

    Nand flash基本原理       Flash全名叫做Flash Memory,属于非易失性存储设备(Non-volatile Memory Device),与此相对应的是易失性存储设备(Vol ...

  2. java 注解结合 spring aop 实现自动输出日志

    auto-log auto-log 是一款为 java 设计的自动日志监控框架. 创作目的 经常会写一些工具,有时候手动加一些日志很麻烦,引入 spring 又过于大材小用. 所以希望从从简到繁实现一 ...

  3. 【Unity3D】AudioSource组件

    1 简介 ​ 1)AudioSource 与 AudioListener 简介 ​ AudioSource(音频源)组件用于控制播放 AudioClip(音频片段),能够控制 2D 和 3D(距离越远 ...

  4. Java并发编程实例--20.使用Semaphores(信号量)控制资源的并发读取

    前面我们介绍了2种同步机制: 1)使用synchronized关键字 2)使用Lock接口及其实现类: ReentrantLock,ReentrantReadWriteLock.ReadLock, a ...

  5. 迭代器,map,filter,reduce,sorted函数---day12

    1.迭代器 迭代器能被next调用,并不断返回下一个值的对象,叫作迭代器(迭代器是对象) 概念:迭代器指的是迭代取值的工具,迭代是一个重复的过程每次重复都是基于上一次的结果而继续单纯的重复不是迭代. ...

  6. Xilinx GTH 简介 ,CoaXpress FPGA PHY 部分

    什么是GTH GTH 是Xilinx UltraScale系列FPGA上高速收发器的一种类型,本质上和其它名称如GTP, GTX等只是器件类型不同.速率有差异:GTH 最低速率在500Mbps,最高在 ...

  7. JAVA对象生命周期(三)-对象的销毁

    目录 从引用说起 指针直接引用 句柄引用 优缺点 如何判断对象死亡 引用计数法 可达性分析法 垃圾收集算法 标记-清除算法 复制算法 复制算法--优化 有关年轻代的JVM参数 标记-整理算法 分代收集 ...

  8. Spring Boot+Thymeleaf+MyBatis--推荐一个后端练手极佳的商城项目

    项目整体架构 newbee-mall ├── src/main/java └── ltd.newbee.mall ├── common // 存放相关的常量配置及枚举类 ├── config // 存 ...

  9. CPNtools协议建模安全分析---实例变迁标记(五)

    之前的说了库所的标记,现在我们开始加讲变迁标记 1.描述变迁的标记有四种类型,分别是变迁的标记,门卫的标记,世间的标记,代码片段的标记. 咋变迁中限制更严格的输入token,其中Code Segeme ...

  10. Git 常用的基础命令

    #克隆项目到本地.url:项目的git地址:local_dir_name:克隆项目到本地的目录名称,如果不写就默认是git项目中的目录名称 git clone <url> <loca ...