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

目录

介绍

效果

模型信息

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);
        }
    }
}

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;
        }

    }
}

下载 

源码下载

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

性格是如何形成的?能不能改变性格?

有一句话叫“性格决定命运”&#xff0c;广泛流传&#xff0c;也就是说 “命运”与“性格”是紧密相连的&#xff0c;可见“性格”对于一个人的重要性。 性格是怎么来的&#xff1f; 1、遗传基因 根据一些心理学家的最新研究&#xff0c;认为性格与人体内的基因有关系&#x…

浏览器缓存引发的odoo前端报错

前两天&#xff0c;跑了一个odoo16项目&#xff0c;莫名其妙的前端报错&#xff0c; moment.js 报的错&#xff0c; 这是一个时间库&#xff0c;不是我自己写的代码&#xff0c;我也没做过任何修改&#xff0c;搞不清楚为什么报错。以为是odoo的bug&#xff0c;所以从gitee下载…

【Python】编程练习的解密与实战(一)

​&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《Python | 编程解码》⏰诗赋清音&#xff1a;云生高巅梦远游&#xff0c; 星光点缀碧海愁。 山川深邃情难晤&#xff0c; 剑气凌云志自修。 目录 &#x1fa90;1. 初识Python &a…

RuntimeError: CUDA error: invalid device ordinal解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

C#基础-空处理

在c#中&#xff0c;值对象是没有办法赋值为null的。比如说&#xff0c;你想要定义一个布尔值&#xff0c;你的赋值数据要么得是true、要么就得是false&#xff0c;默认情况下我们永远没可能给这个布尔赋值为null&#xff0c;即使只是对这个变量进行声明而不初始化数据&#xff…

ChatGPT会给教育界带来怎样的冲击,又将与教育碰撞出怎样的火花?

11 月 7 日凌晨&#xff0c;美国人工智能公司 OpenAI 的开发者大会正式开启&#xff0c;创始人 Sam Altman 和其同事&#xff0c;发布了团队最新的成果GPT-4 Turbo&#xff0c;新一代的GPT不仅更快、有更长的上下文、而且更好的控制。而随之推出的「GPTs」——让人们能用自然语…

服务器执行rm命令时自动记录到审计日志中

目的 当在服务器上执行类似于 rm 命令时&#xff0c;自动记录该命令执行的时间&#xff0c;在哪里执行的&#xff0c;删除的什么文件&#xff0c;记录到审计日志中&#xff0c;能够查找到某些文件丢失原因 配置 # 需要root权限&#xff0c;sudo不行&#xff0c;这里假设执行…

Java:爬虫htmlunit实践

之前我们已经讲过使用htmlunit及基础&#xff0c;没有看过的可以参考Java&#xff1a;爬虫htmlunit-CSDN博客 我们今天就来实际操作一下&#xff0c;爬取指定网站的数据 1、首先我们要爬取一个网站数据的时候我们需要对其数据获取方式我们要进行分析&#xff0c;我们今天就拿双…

注册中心(Nacos)

简介 Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管…

基于DNA的密码学和隐写术综述

摘要 本文全面调研了不同的脱氧核糖核酸(DNA)-基于密码学和隐写术技术。基于DNA的密码学是一个新兴领域,利用DNA分子的大规模并行性和巨大的存储容量来编码和解码信息。近年来,由于其相对传统密码学方法的潜在优势,如高存储容量、低错误率和对环境因素的抗性,该领域引起…

网络之路28:二层链路聚合

正文共&#xff1a;1666 字 14 图&#xff0c;预估阅读时间&#xff1a;2 分钟 目录 网络之路第一章&#xff1a;Windows系统中的网络 0、序言 1、Windows系统中的网络1.1、桌面中的网卡1.2、命令行中的网卡1.3、路由表1.4、家用路由器 网络之路第二章&#xff1a;认识企业设备…

Elasticsearch windows开箱即用【记录】

一、准备工作 安装ES之前要在本机安装好JDK&#xff0c;对应的兼容性见官网链接&#xff1a;https://www.elastic.co/cn/support/matrix ES官网链接&#xff1a;https://www.elastic.co/cn/, 我本机安装的是JDK8&#xff0c;测试使用的是7.3.0版本的ES和Kibana。 1、首先去…

Spring Boot 2.6 以上整合 Swagger + Knife4j 报错

Spring Boot 2.6 以上整合 Swagger Knife4j 报错 报错信息报错原因解决办法 报错信息 org.springframework.context.ApplicationContextException: Failed to start bean documentationPluginsBootstrapper; nested exception is java.lang.NullPointerException: Cannot inv…

premiere简约大气3D动画logo片头Pr模板Mogrt免费下载

Premiere简约大气3D动画logo片头pr模板mogrt下载&#xff0c;无需插件&#xff0c;高清分辨率&#xff0c;易于自定义&#xff0c;包括教程&#xff0c;不包括音频和图像。免费下载&#xff1a;https://prmuban.com/37065.html

centos下系统全局检测工具dstat使用

目录 一&#xff1a;没有需要安装 二&#xff1a;dstat命令参数 三、监测界面各参数含义&#xff08;部分&#xff09; 四、dstat的高级用法 一&#xff1a;没有需要安装 yum install dstat 二&#xff1a;dstat命令参数 有默认选项&#xff0c;执行dstat命令不加任何参数…

C语言初始化效率问题以及关键字解释

一、初始化效率 1、在静态变量的初始化中&#xff0c;我们可以把可执行程序文件想要初始化的值放在当程序执行时变量将会使用的位置。当可执行文件载入到内存时&#xff0c;这个已经保存了正确初始值的位置将赋值给那个变量&#xff0c;完成这个任务并不需要额外的时间&#xf…

自动化的运维管理:探究Kubernetes工作机制的奥秘

1 云计算时代的操作系统 Kubernetes 是一个生产级别的 容器编排平台 和 集群管理系统 &#xff0c;能够 创建、调度容器&#xff0c;监控、管理服务器。 容器是什么&#xff1f;容器是软件&#xff0c;是应用&#xff0c;是进程。服务器是什么&#xff1f;服务器是硬件&#…

CMake入门教程【高级篇】管理MSVC编译器警告

😈「CSDN主页」:传送门 😈「Bilibil首页」:传送门 😈「动动你的小手」:点赞👍收藏⭐️评论📝 文章目录 1.什么是MSVC?2.常用的屏蔽警告3.MSVC所有警告4.target_compile_options用法5.如何在CMake中消除MSVC的警告?6.屏蔽警告编写技巧

一台Linux服务jdk1.6 与 jdk1.8 并存,tomcat6+tomcat8 并存

Linux jdk1.6,1.8 tomcat6 tomcat8 并存 需求场景&#xff1a; 有一个项目 原来是 jdk1.6tomcat6 部署的&#xff0c;现在需要进行项目架构升级 项目需要适配jdk1.8 然后用 jdk.8 tomcat 8进行部署&#xff0c;然后下架 jdk1.6 的linux服务 现在有一台 jdk.8 tomcat 8的linu…

100V耐压 LED恒流驱动芯片 SL2516D兼容替换LN2516车灯照明芯片

SL2516D LED恒流驱动芯片是一款专为LED照明设计的高效、高精度恒流驱动芯片。与LN2516车灯照明芯片兼容&#xff0c;可直接替换LN2516芯片&#xff0c;为LED车灯照明提供稳定、可靠的电源解决方案。 一、SL2516D LED恒流驱动芯片的特点 1. 高效率&#xff1a;SL2516D采用先进的…