C# Open Vocabulary Object Detection 部署开放域目标检测

news2024/11/17 3:44:35

目录

介绍

效果

模型信息

owlvit-image.onnx

owlvit-post.onnx

owlvit-text.onnx

项目

代码

Form1.cs

OWLVIT.cs 

下载 


C# Open Vocabulary Object Detection 部署开放域目标检测

介绍

训练源码地址:https://github.com/google-research/scenic/tree/main/scenic/projects/owl_vit

效果

模型信息

owlvit-image.onnx

Inputs
-------------------------
name:pixel_values
tensor:Float[1, 3, 768, 768]
---------------------------------------------------------------

Outputs
-------------------------
name:image_embeds
tensor:Float[1, 24, 24, 768]
name:pred_boxes
tensor:Float[1, 576, 4]
---------------------------------------------------------------

owlvit-post.onnx

Inputs
-------------------------
name:image_embeds
tensor:Float[1, 24, 24, 768]
name:/owlvit/Div_output_0
tensor:Float[1, 512]
name:input_ids
tensor:Int64[1, 16]
---------------------------------------------------------------

Outputs
-------------------------
name:logits
tensor:Float[-1, 576, 1]
---------------------------------------------------------------

owlvit-text.onnx

Inputs
-------------------------
name:input_ids
tensor:Int64[1, 16]
name:attention_mask
tensor:Int64[1, 16]
---------------------------------------------------------------

Outputs
-------------------------
name:text_embeds
tensor:Float[1, 1, 512]
---------------------------------------------------------------

项目

代码

Form1.cs

using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Onnx_Demo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        OWLVIT owlvit = new OWLVIT("model/owlvit-image.onnx", "model/owlvit-text.onnx", "model/owlvit-post.onnx", "model/vocab.txt");

        string image_path = "";
        string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";

        StringBuilder sb = new StringBuilder();

        Mat image;
        Mat result_image;

        private void button2_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            if (ofd.ShowDialog() != DialogResult.OK) return;

            pictureBox1.Image = null;
            pictureBox2.Image = null;
            txtInfo.Text = "";

            image_path = ofd.FileName;
            pictureBox2.Image = new Bitmap(image_path);
            image = new Mat(image_path);

        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (image_path == "")
            {
                return;
            }

            if (String.IsNullOrEmpty(txt_input_text.Text))
            {
                return;
            }

            pictureBox1.Image = null;
            txtInfo.Text = "检测中,请稍等……";
            button3.Enabled=false;
            if (pictureBox1.Image!=null)
            {
                pictureBox1.Image.Dispose();
                pictureBox1.Image = null;   
            }
            Application.DoEvents();

            List<string> texts = txt_input_text.Text.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).ToList();

            owlvit.encode_texts(texts);

            List<BoxInfo> objects = owlvit.detect(image, texts);

            result_image = image.Clone();
            sb.Clear();
            for (int i = 0; i < objects.Count; i++)
            {
                Cv2.Rectangle(result_image, objects[i].box, new Scalar(0, 0, 255), 2);
                Cv2.PutText(result_image, objects[i].text + " " + objects[i].prob.ToString("F2"), new OpenCvSharp.Point(objects[i].box.X, objects[i].box.Y), HersheyFonts.HersheySimplex, 1, new Scalar(0, 0, 255), 2); ;
                sb.AppendLine(objects[i].text + " " + objects[i].prob.ToString("F2"));
            }
            pictureBox1.Image = new Bitmap(result_image.ToMemoryStream());

            button3.Enabled = true;
            txtInfo.Text = sb.ToString();

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            image_path = "test_img/2.jpg";
            pictureBox2.Image = new Bitmap(image_path);
            image = new Mat(image_path);

            owlvit.encode_image(image);
        }
    }
}

OWLVIT.cs 

using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
using OpenCvSharp;
using OpenCvSharp.Dnn;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Onnx_Demo
{
    public class OWLVIT
    {
        float bbox_threshold = 0.02f;

        int inpWidth = 768;
        int inpHeight = 768;

        float[] mean = new float[] { 0.48145466f, 0.4578275f, 0.40821073f };
        float[] std = new float[] { 0.26862954f, 0.26130258f, 0.27577711f };

        Net net;
        float[] image_features_input;

        SessionOptions options;
        InferenceSession onnx_session;

        List<NamedOnnxValue> input_container;
        IDisposableReadOnlyCollection<DisposableNamedOnnxValue> result_infer;
        DisposableNamedOnnxValue[] results_onnxvalue;
        Tensor<float> result_tensors;

        TokenizerBase tokenizer;

        SessionOptions options_transformer;
        InferenceSession onnx_session_transformer;

        float[] image_features;

        List<long[]> input_ids = new List<long[]>();
        List<float[]> text_features = new List<float[]>();

        long[] attention_mask;

        int len_image_feature = 24 * 24 * 768;
        int cnt_pred_boxes = 576;
        int len_text_token = 16;
        int context_length = 52;
        int len_text_feature = 512;
        int[] image_features_shape = { 1, 24, 24, 768 };
        int[] text_features_shape = { 1, 512 };

        public int imgnum = 0;
        public List<string> imglist = new List<string>();

        List<Rect2f> pred_boxes = new List<Rect2f>();

        public OWLVIT(string image_modelpath, string text_modelpath, string decoder_model_path, string vocab_path)
        {
            net = CvDnn.ReadNetFromOnnx(image_modelpath);

            input_container = new List<NamedOnnxValue>();

            options = new SessionOptions();
            options.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_INFO;
            options.AppendExecutionProvider_CPU(0);
            onnx_session = new InferenceSession(text_modelpath, options);

            options_transformer = new SessionOptions();
            options_transformer.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_INFO;
            options_transformer.AppendExecutionProvider_CPU(0);
            onnx_session_transformer = new InferenceSession(decoder_model_path, options);

            load_tokenizer(vocab_path);

        }

        void load_tokenizer(string vocab_path)
        {
            tokenizer = new TokenizerClip();
            tokenizer.load_tokenize(vocab_path);
        }

        Mat normalize_(Mat src)
        {
            Cv2.CvtColor(src, src, ColorConversionCodes.BGR2RGB);
            Mat[] bgr = src.Split();
            for (int i = 0; i < bgr.Length; ++i)
            {
                bgr[i].ConvertTo(bgr[i], MatType.CV_32FC1, 1.0 / (255.0 * std[i]), (0.0 - mean[i]) / std[i]);
            }
            Cv2.Merge(bgr, src);
            foreach (Mat channel in bgr)
            {
                channel.Dispose();
            }
            return src;
        }

        float sigmoid(float x)
        {
            return (float)(1.0f / (1.0f + Math.Exp(-x)));
        }

        public unsafe void encode_image(Mat srcimg)
        {
            pred_boxes.Clear();
            Mat temp_image = new Mat();
            Cv2.Resize(srcimg, temp_image, new Size(inpWidth, inpHeight));
            Mat normalized_mat = normalize_(temp_image);

            Mat blob = CvDnn.BlobFromImage(normalized_mat);
            net.SetInput(blob);
            //模型推理,读取推理结果
            Mat[] outs = new Mat[2] { new Mat(), new Mat() };
            string[] outBlobNames = net.GetUnconnectedOutLayersNames().ToArray();
            net.Forward(outs, outBlobNames);

            float* ptr_feat = (float*)outs[0].Data;

            image_features = new float[len_image_feature];

            for (int i = 0; i < len_image_feature; i++)
            {
                image_features[i] = ptr_feat[i];
            }

            float* ptr_box = (float*)outs[1].Data;
            Rect2f temp;
            for (int i = 0; i < cnt_pred_boxes; i++)
            {
                float xc = ptr_box[i * 4 + 0] * inpWidth;
                float yc = ptr_box[i * 4 + 1] * inpHeight;

                temp = new Rect2f();

                temp.Width = ptr_box[i * 4 + 2] * inpWidth;
                temp.Height = ptr_box[i * 4 + 3] * inpHeight;
                temp.X = (float)(xc - temp.Width * 0.5);
                temp.Y = (float)(yc - temp.Height * 0.5);

                pred_boxes.Add(temp);
            }
        }

        public unsafe void encode_texts(List<string> texts)
        {
            List<List<int>> text_token = new List<List<int>>(texts.Count);
            for (int i = 0; i < texts.Count; i++)
            {
                text_token.Add(new List<int>());
            }

            text_features.Clear();
            input_ids.Clear();

            for (int i = 0; i < texts.Count; i++)
            {
                tokenizer.encode_text(texts[i], text_token[i]);

                int len_ids = text_token[i].Count;

                long[] temp_ids = new long[len_text_token];
                attention_mask = new long[len_text_token];

                for (int j = 0; j < len_text_token; j++)
                {
                    if (j < len_ids)
                    {
                        temp_ids[j] = text_token[i][j];
                        attention_mask[j] = 1;
                    }
                    else
                    {
                        temp_ids[j] = 0;
                        attention_mask[j] = 0;
                    }
                }
                input_ids.Add(temp_ids);
                input_container.Clear();

                Tensor<long> input_tensor = new DenseTensor<long>(input_ids[i], new[] { 1, len_text_token });
                Tensor<long> input_tensor_mask = new DenseTensor<long>(attention_mask, new[] { 1, attention_mask.Length });

                input_container.Add(NamedOnnxValue.CreateFromTensor("input_ids", input_tensor));
                input_container.Add(NamedOnnxValue.CreateFromTensor("attention_mask", input_tensor));

                result_infer = onnx_session.Run(input_container);

                results_onnxvalue = result_infer.ToArray();

                result_tensors = results_onnxvalue[0].AsTensor<float>();

                float[] temp_text_features = results_onnxvalue[0].AsTensor<float>().ToArray();

                text_features.Add(temp_text_features);

            }
        }

        List<float> decode(float[] input_image_feature, float[] input_text_feature, long[] input_id)
        {
            input_container.Clear();

            Tensor<float> input_tensor_image_embeds = new DenseTensor<float>(input_image_feature, image_features_shape);
            Tensor<float> input_tensor_Div_output_0 = new DenseTensor<float>(input_text_feature, text_features_shape);
            Tensor<long> input_ids = new DenseTensor<long>(input_id, new[] { 1, 16 });

            /*
                name:image_embeds
                tensor:Float[1, 24, 24, 768]
                name:/owlvit/Div_output_0
                tensor:Float[1, 512]
                name:input_ids
                tensor:Int64[1, 16]
             
             */
            input_container.Add(NamedOnnxValue.CreateFromTensor("image_embeds", input_tensor_image_embeds));
            input_container.Add(NamedOnnxValue.CreateFromTensor("/owlvit/Div_output_0", input_tensor_Div_output_0));
            input_container.Add(NamedOnnxValue.CreateFromTensor("input_ids", input_ids));

            result_infer = onnx_session_transformer.Run(input_container);

            results_onnxvalue = result_infer.ToArray();

            result_tensors = results_onnxvalue[0].AsTensor<float>();

            return results_onnxvalue[0].AsTensor<float>().ToList();
        }

        public List<BoxInfo> detect(Mat srcimg, List<string> texts)
        {
            float ratioh = 1.0f * srcimg.Rows / inpHeight;
            float ratiow = 1.0f * srcimg.Cols / inpWidth;

            List<float> confidences = new List<float>();
            List<Rect> boxes = new List<Rect>();
            List<string> className = new List<string>();

            for (int i = 0; i < input_ids.Count; i++)
            {
                List<float> logits = decode(image_features, text_features[i], input_ids[i]);

                for (int j = 0; j < logits.Count; j++)
                {
                    float score = sigmoid(logits[j]);
                    if (score >= bbox_threshold)
                    {
                        //还原回到原图
                        int xmin = (int)(pred_boxes[j].X * ratiow);
                        int ymin = (int)(pred_boxes[j].Y * ratioh);
                        int xmax = (int)((pred_boxes[j].X + pred_boxes[j].Width) * ratiow);
                        int ymax = (int)((pred_boxes[j].Y + pred_boxes[j].Height) * ratioh);
                        //越界检查保护
                        xmin = Math.Max(Math.Min(xmin, srcimg.Cols - 1), 0);
                        ymin = Math.Max(Math.Min(ymin, srcimg.Rows - 1), 0);
                        xmax = Math.Max(Math.Min(xmax, srcimg.Cols - 1), 0);
                        ymax = Math.Max(Math.Min(ymax, srcimg.Rows - 1), 0);

                        boxes.Add(new Rect(xmin, ymin, xmax - xmin, ymax - ymin));
                        confidences.Add(score);
                        className.Add(texts[i]);
                    }
                }
            }

            float nmsThreshold = 0.5f;
            int[] indices;

            CvDnn.NMSBoxes(boxes, confidences, bbox_threshold, nmsThreshold, out indices);

            List<BoxInfo> objects = new List<BoxInfo>();

            for (int i = 0; i < indices.Length; ++i)
            {
                BoxInfo temp = new BoxInfo();
                temp.text = className[i];
                temp.prob = confidences[i];
                temp.box = boxes[i];
                objects.Add(temp);
            }

            return objects;
        }

    }
}

下载 

源码下载

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

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

相关文章

flink重温笔记(九):Flink 高级 API 开发——flink 四大基石之WaterMark(Time为核心)

Flink学习笔记 前言&#xff1a;今天是学习 flink 的第 9 天啦&#xff01;学习了 flink 四大基石之 Time的应用—> Watermark&#xff08;水印&#xff0c;也称水位线&#xff09;&#xff0c;主要是解决数据由于网络延迟问题&#xff0c;出现数据乱序或者迟到数据现象&…

九州金榜|导致孩子厌学的家庭因素有哪些?

造成孩子厌学的因素有很多&#xff0c;其中家庭因素是非常重要的因素&#xff0c;而家庭因素造成孩子厌学的原因主要是因为家长在教育中&#xff0c;更多的不懂如何正确教育孩子&#xff0c;就会造成孩子厌学&#xff0c;下面九州金榜家庭教育从以下几个方面分析因为家庭因素造…

C/C++工程师面试题(数据库篇)

索引的优缺点 索引是一种支持快速查找特定行的数据结构&#xff0c;如果没有索引&#xff0c;就需要遍历整个表进行查找。用于提高数据检索的速度和效率。 好处&#xff1a; 提高检索速度&#xff1a; 索引可以加快数据的检索速度&#xff0c;因为它们允许数据库系统直接定位到…

枚举法实例以及试题

题目 1 因子个数 思路: 从因子1找到它本身,其中我们发现因子都是成对出现的,除非它是完全平方数,因此我们采用for循环一个一个找出来就行,查找它因子的个数。 题目 2 阶乘因子 思路: 创建一个【n+1】的数组,初始值全都为0,用来存放它的质数因子个数。用两个for循环,…

mTLS: openssl创建CA证书

证书可以通过openssl或者keytool创建&#xff0c;在本篇文章中&#xff0c;只介绍openssl。 openssl 生成证书 申请操作流程 生成ca证书私钥, 文件名&#xff1a;ca.key生成ca证书&#xff0c;文件名&#xff1a;ca.crt生成Server/Client 证书私钥&#xff0c;文件名&#x…

8、IBOScms代码审计

一、sql注入 1、sql注入(Ⅰ) 限制 rreport/api/getlist {"offset":0,"type":"send","keyword":{"subject":"111) AND (updatexml(1,concat(0x7e,(select user()),0x7e),1))-- qw"}}复现 POST /?rreport/api/…

项目-论坛系统

基于Spring前后端分离版本的论坛系统。 1、构建项目结构 common公共类&#xff1a;统一返回结果、全局变量、异常枚举信息config配置类&#xff1a;Swagger&#xff0c;用于自动生成CRUD和基本对象controller控制器类&#xff1a;用于接受前端信息和控制路由dao数据库访问类&…

uniapp聊天记录本地存储(详细易懂)

目录 目录 1、通过websocket拿取数据 2、获取聊天数据 3、聊天信息存储 、更新 4、读取聊天记录 5、发送信息&#xff0c;信息获取 6、最终效果 1.聊天信息的存储格式 2、样式效果 写聊天项目&#xff0c;使用到了本地存储。需要把聊天信息保存在本地&#xff0c;实时获…

synchrosized 的可重入特性、死锁、哲学家就餐问题以及解决死锁的方法等干货

文章目录 &#x1f490;synchrosized的可重入特性关于死锁&#xff1a;哲学家就餐问题&#x1f4a1;如何避免/解决死锁 &#x1f490;synchrosized的可重入特性 可重入特性&#xff1a;当一个线程针对一个对象同时加锁多次&#xff0c;不会构成死锁&#xff0c;这样的特性称为…

flynn发布服务小结

背景 flynn是一个基于容器的paas平台&#xff0c;可以快速的发布运行新的应用&#xff0c;用户只需要提交代码到git上&#xff0c;flynn就会基于提交的代码进行发布和部署&#xff0c;本文就简单看下flynn发布部署的流程 flynn发布服务 1.首先flynn会基于用户的web代码构建一…

二叉树的右视图,力扣

目录 题目&#xff1a; 我们直接看题解吧&#xff1a; 快速理解解题思路小建议&#xff1a; 审题目事例提示&#xff1a; 解题方法&#xff1a; 解题分析&#xff1a; 解题思路&#xff1a; 代码实现(DFS)&#xff1a; 代码1&#xff1a; 补充说明&#xff1a; 代码2&#xff1…

LeetCode---【链表的操作】

目录 206反转链表【链表结构基础】21合并两个有序链表【递归】我的答案【错误】自己修改【超出时间限制】在官方那里学到的【然后自己复写,错误】对照官方【自己修改】 160相交链表【未理解题目目的】在b站up那里学到的【然后自己复写,错误】【超出时间限制】对照官方【自己修改…

Mybatis插入数据时有外键怎么办?

今天在写代码的时候遇到了一个问题&#xff1a; 比方说我的数据库如下&#xff1a; 其中work_position和auth都是外键&#xff0c;关联了另一张表。 但我现在要往mysql里插入一条数据&#xff0c;如下&#xff1a; insert into t_employee_info(salary, work_time, work_posi…

Qt 简约又简单的加载动画 第七季 音量柱风格

今天和大家分享两个音量柱风格的加载动画,这次的加载动画的最大特点就是简单,只有几行代码. 效果如下: 一共三个文件,可以直接编译运行 //main.cpp #include "LoadingAnimWidget.h" #include <QApplication> #include <QGridLayout> int main(int argc…

飞天使-学以致用-devops知识点4-SpringBoot项目CICD实现(实验失败,了解大概流程)

文章目录 代码准备创建jenkins 任务测试推送使用项目里面的jenkinsfile 进行升级操作 文字版本流程项目构建 代码准备 推送代码到gitlab 代码去叩叮狼教育找 k8s 创建jenkins 任务 创建一个k8s-cicd-demo 流水线任务 将jenkins 里面构建时候的地址还有token&#xff0c; 给到…

langchain学习笔记(十)

Bind runtime args | &#x1f99c;️&#x1f517; Langchain 1、有时&#xff0c;我们希望使用常量参数调用Runnable序列中的Runnable&#xff0c;这些参数不是序列中前一个Runnable的输出的一部分&#xff0c;也不是用户的输入&#xff0c;这时可以用Runnable.bind() from …

离散系统的冲激响应和阶跃响应

离散系统的冲激响应和阶跃响应 方法一&#xff1a; 使用 impz()dstep() 求冲激和阶跃响应 \textbf{方法一&#xff1a;}使用\textbf{impz()}\textbf{dstep()}求冲激和阶跃响应 方法一&#xff1a;使用impz()dstep()求冲激和阶跃响应 方法二&#xff1a; 使用 filtic()filter() …

精准唇语同步:Wav2Lip 引领视频技术前沿 | 开源日报 No.188

Rudrabha/Wav2Lip Stars: 8.4k License: NOASSERTION Wav2Lip 是一个准确地在野外进行视频唇语同步的项目。 该项目的主要功能、关键特性和核心优势包括&#xff1a; 可以高精度地将视频与任何目标语音进行唇语同步适用于任何身份、声音和语言&#xff0c;也适用于 CGI 面孔和…

SpringCloud负载均衡源码解析 | 带你从表层一步步剖析Ribbon组件如何实现负载均衡功能

目录 1、负载均衡原理 2、源码分析 2.1、LoadBalanced 2.2、LoadBalancerClient 2.3、RibbonAutoConfiguration 2.4、LoadBalancerAutoConfiguration 2.5、LoadBalancerIntercepor⭐ 2.6、再回LoadBalancerClient 2.7、RibbonLoadBalancerClient 2.7.1、DynamicServe…

Git 如何上传本地的所有分支

Git 如何上传本地的所有分支 比如一个本地 git 仓库里定义了两个远程分支&#xff0c;一个名为 origin&#xff0c; 一个名为 web 现在本地有一些分支是 web 远程仓库没有的分支&#xff0c;如何将本地所有分支都推送到 web 这个远程仓库上呢 git push web --all