C#OpenCvSharp YOLO v3 Demo
效果

项目

代码
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;
}
}
}
C#OpenCvSharp YOLO v3 Demo的更多相关文章
- 深度学习笔记(十三)YOLO V3 (Tensorflow)
[代码剖析] 推荐阅读! SSD 学习笔记 之前看了一遍 YOLO V3 的论文,写的挺有意思的,尴尬的是,我这鱼的记忆,看完就忘了 于是只能借助于代码,再看一遍细节了. 源码目录总览 tens ...
- YOLO v3
yolo为you only look once. 是一个全卷积神经网络(FCN),它有75层卷积层,包含跳跃式传递和降采样,没有池化层,当stide=2时用做降采样. yolo的输出是一个特征映射(f ...
- YOLO系列:YOLO v3解析
本文好多内容转载自 https://blog.csdn.net/leviopku/article/details/82660381 yolo_v3 提供替换backbone.要想性能牛叉,backbo ...
- Yolo V3整体思路流程详解!
结合开源项目tensorflow-yolov3(https://link.zhihu.com/?target=https%3A//github.com/YunYang1994/tensorflow-y ...
- YOLO v3算法介绍
图片来自https://towardsdatascience.com/yolo-v3-object-detection-with-keras-461d2cfccef6 数据前处理 输入的图片维数:(4 ...
- 一文看懂YOLO v3
论文地址:https://pjreddie.com/media/files/papers/YOLOv3.pdf论文:YOLOv3: An Incremental Improvement YOLO系列的 ...
- YOLO V3 原理
基本思想V1: 将输入图像分成S*S个格子,每隔格子负责预测中心在此格子中的物体. 每个格子预测B个bounding box及其置信度(confidence score),以及C个类别概率. bbox ...
- Pytorch从0开始实现YOLO V3指南 part5——设计输入和输出的流程
本节翻译自:https://blog.paperspace.com/how-to-implement-a-yolo-v3-object-detector-from-scratch-in-pytorch ...
- Pytorch从0开始实现YOLO V3指南 part1——理解YOLO的工作
本教程翻译自https://blog.paperspace.com/how-to-implement-a-yolo-object-detector-in-pytorch/ 视频展示:https://w ...
- yolo类检测算法解析——yolo v3
每当听到有人问“如何入门计算机视觉”这个问题时,其实我内心是拒绝的,为什么呢?因为我们说的计算机视觉的发展史可谓很长了,它的分支很多,而且理论那是错综复杂交相辉映,就好像数学一样,如何学习数学?这问题 ...
随机推荐
- NC17315 背包
题目链接 题目 题目描述 Applese有 \(1\) 个容量为 \(v\) 的背包,有 \(n\) 个物品,每一个物品有一个价值 \(a_i\) ,以及一个大小 \(b_i\) 然后他对此提出了自己 ...
- OpenWrt的多WAN和静态路由设置
配置第二个WAN 增加新VLAN Network->Switch 增加新的VLAN, 默认安装已经存在两个VLAN ID 1和2,新增的VLAND ID为3. 对应这行新记录,将CPU设为tag ...
- 虚拟化技术VirtualBox和vagrant基本使用
虚拟化技术VirtualBox和vagrant基本使用 1.首先安装VirtualBox 可以去官网下载 https://www.virtualbox.org/ 2.安装vagrant(根据自己电脑得 ...
- Basic语言开发笔记:Basic语言介绍、环境搭建、基本语法示例与程序实例
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- djang中orm使用iterator()
当查询结果有很多对象时,QuerySet的缓存行为会导致使用大量内存.如果你需要对查询结果进行好几次循环,这种缓存是有意义的,但是对于 queryset 只循环一次的情况,缓存就没什么意义了.在这种情 ...
- ProtoBuf 基本使用
一.是什么 Protocol Buffers,是Google公司开发的一种数据描述语言,是一种平台无关.语言无关.可扩展且类似于XML能够将结构化数据序列化,可用于数据存储.通信协议等方面. 二.为什 ...
- Windows 实例如何开放端口
矩池云 Windows 实例相比于 Linux 实例,除了在租用机器的时候自定义端口外,还需要在 Windows防火墙中添加入口规则.接下来将教大家如何设置 Windows 防火墙,启用端口. 租用成 ...
- 【Azure App Service】同一个App Service下创建多个测试站点的方式
问题描述 在一个App Service中,部署多个应用,每个应用相互独立,类似与IIS中在根目录下创建多个子应用的情况. 问题解答 可以的.通过App Service Configuration页面, ...
- 【Azure 云服务】Cloud Service Worker Role Workerrole突然停机,查看Events发现 Defrag Error (0x8900002D)
问题描述 Cloud Service Worker Role Workerrole突然停机,查看Events,发现是错误源为 Defrag. 错误消息: The volume Windows was ...
- 【Azure Developer】PHP网站使用AAD授权登录的参考示例
问题描述 如果有个PHP网站,需要使用AAD授权登录,有没有PHP代码实例 可供参考呢? 参考代码 参考一篇博文(Single sign-on with Azure AD in PHP),学习使用SS ...