Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现各种食物的类型检测识别(C#代码UI界面版)

Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现各种食物的类型检测识别(C#代码UI界面版)

工业相机使用YoloV8模型实现电池的检测识别

本项目集成了 YOLOv8 检测模型 与 C#图形界面工具,实现了包括图片、文件夹、视频与摄像头等多种输入方式的实现各种食物的类型检测。

Baumer工业相机堡盟相机是一种高性能、高质量的工业相机,可用于各种应用场景,如物体检测、计数和识别、运动分析和图像处理。

Baumer的万兆网相机拥有出色的图像处理性能,可以实时传输高分辨率图像。此外,该相机还具有快速数据传输、低功耗、易于集成以及高度可扩展性等特点。

Baumer工业相机由于其性能和质量的优越和稳定,常用于高速同步采集领域,通常使用各种图像算法来提高其捕获的图像的质量。

本文以Baumer工业相机作为案例进行演示,实现将工业相机的图像或者本地图像夹导入Yolo模型从而实现各种食物的类型检测等功能。

工业相机通过YoloV8模型实现各种食物的类型检测的技术背景

本文通过C#中实现一个简单的UI界面,用于将YoloV8模型实现各种食物的类型检测。

用户可以通过该界面执行以下操作:

  1. 转换相机图像为Mat图像:通过YoloV8模型实现各种食物的类型检测

  2. 转换本地图像为mat图像:通过YoloV8模型实现各种食物的类型检测

通过这个UI界面,用户能够在实时应用机器视觉数据处理时快速有效地进行操作,无需深入了解图像数据的底层处理过程。这个简单的介绍旨在为开发人员提供一个明确的方向,以便开始构建此类应用程序,并且该程序主要用于演示目的。

在相机SDK中获取图像转换图像的代码分析

本文介绍使用Baumer工业相机,实现将图像转换为Bitmap图像,再转换Mat图像,导入到Yolo模型进行推理,输出实现各种食物的类型检测的结果。

工业相机图像转换Bitmap图像格式和Mat图像重要核心代码

csharp 复制代码
//将相机内部图像内存数据转为bitmap数据
System.Drawing.Bitmap bitmap  = new System.Drawing.Bitmap((int)mBufferFilled.Width, (int)mBufferFilled.Height,(int)mBufferFilled.Width,System.Drawing.Imaging.PixelFormat.Format8bppIndexed, (IntPtr)((ulong)mBufferFilled.MemPtr + mBufferFilled.ImageOffset));
                                      
#region//Mono图像数据转换。彩色图像数据转换于此不同
System.Drawing.Imaging.ColorPalette palette = bitmap.Palette;
int nColors = 256;
for (int ix = 0; ix < nColors; ix++)
{
     uint Alpha = 0xFF;
     uint Intensity = (uint)(ix * 0xFF / (nColors - 1));
     palette.Entries[ix] = System.Drawing.Color.FromArgb((int)Alpha, (int)Intensity,(int)Intensity, (int)Intensity);
}
bitmap.Palette = palette;
#endregion

string strtime = DateTime.Now.ToString("yyyyMMddhhmmssfff");
string saveimagepath = pImgFileDir + "\\" + strtime + ".brw";
      
//使用Bitmap格式保存         
bitmap.Save(saveimagepath, System.Drawing.Imaging.ImageFormat.Bmp);  


//用bitmap转换为mat
OpenCvSharp.Mat Matgray1 = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap);

本地文件图像转换Bitmap图像格式和Mat图像重要核心代码

C#环境下代码如下所示:

csharp 复制代码
if (imagePaths.Count() == 0)
{
    LoadImagePaths("test_img");
}

string currentImagePath = imagePaths[currentImageIndex];

    // 显示到pictureBoxA
pictureBoxA.Image.Dispose(); // 释放上一张图片资源,避免内存泄漏
pictureBoxA.Image = new Bitmap(currentImagePath);
image_path = currentImagePath;

currentImageIndex = (currentImageIndex + 1) % imagePaths.Count;

OnNotifyShowRecieveMsg("检测中,请稍等......");
//textBox1.Text = "检测中,请稍等......";
//pictureBox2.Image = null;
Application.DoEvents();

image = new Mat(image_path);

float ratio = Math.Min(1.0f * inpHeight / image.Rows, 1.0f * inpWidth / image.Cols);
int neww = (int)(image.Cols * ratio);
int newh = (int)(image.Rows * ratio);

Mat dstimg = new Mat();
Cv2.Resize(image, dstimg, new OpenCvSharp.Size(neww, newh));

Cv2.CopyMakeBorder(dstimg, dstimg, 0, inpHeight - newh, 0, inpWidth - neww, BorderTypes.Constant);

Mat图像导入YoloV8模型重要核心代码

C#环境下代码如下所示:

csharp 复制代码
// 定义 ONNX 模型的路径
string onnxModelPath = "model/Battery_detection.onnx";
// 定义输入图像的形状
OpenCvSharp.Size inputShape = new OpenCvSharp.Size(640, 640);
// 从 ONNX 模型文件加载网络
if(net==null)
    net = CvDnn.ReadNetFromOnnx(onnxModelPath);

            
string[] modelClassify = { "Battery"};

if (imagePaths.Count() == 0)
{
    LoadImagePaths("test_img");
}

string currentImagePath = imagePaths[currentImageIndex];

    // 显示到pictureBoxA
pictureBoxA.Image.Dispose(); // 释放上一张图片资源,避免内存泄漏
pictureBoxA.Image = new Bitmap(currentImagePath);
image_path = currentImagePath;

if (pictureBoxA.Image == null)
{
    return;
}
currentImageIndex = (currentImageIndex + 1) % imagePaths.Count;

OnNotifyShowRecieveMsg("检测中,请稍等......");
            
Application.DoEvents();

image = new Mat(image_path);

dt1 = DateTime.Now;
// 调用识别图像的函数,并传入图像路径、阈值、网络、输入形状和分类类别列表
//result_image = Recognize(image, 0.35, net, inputShape, modelClassify);
result_image = RecognizeMat(image, 0.35, net, inputShape, modelClassify);
// 获取计算结束时间
dt2 = DateTime.Now;
// 显示输出的图像
pictureBoxA.Image = new Bitmap(result_image.ToMemoryStream());
         
// 显示推理耗时时间
OnNotifyShowRecieveMsg("推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms");
csharp 复制代码
static Mat RecognizeMat(Mat imgInput, double threshold, Net net, OpenCvSharp.Size inputShape, string[] modelClassify)
{
    using (Mat img = imgInput)
    {

        int inpHeight = inputShape.Height; // 输入图像的高度
        int inpWidth = inputShape.Width; // 输入图像的宽度

        // 对图像进行预处理,调整尺寸
        Mat image = img;
        float ratio = Math.Min(1.0f * inpHeight / image.Rows, 1.0f * inpWidth / image.Cols);
        int neww = (int)(image.Cols * ratio);
        int newh = (int)(image.Rows * ratio);

        //// 将图像调整为模型需要的大小
        //Mat dstimg = new Mat();
        //Cv2.Resize(image, dstimg, new OpenCvSharp.Size(neww, newh));
        //Cv2.CopyMakeBorder(dstimg, dstimg, 0, inpHeight - newh, 0, inpWidth - neww, BorderTypes.Constant);
        //Mat BN_image = CvDnn.BlobFromImage(dstimg); // 将调整后的图像转换为Blob格式

        //// 配置图片输入数据 // 将 blob 设置为网络的输入
        //net.SetInput(BN_image);

        //// 从图像生成用于网络输入的 blob
        //Mat blob = CvDnn.BlobFromImage(img, 1 / 255.0, inputShape, new Scalar(0, 0, 0), false);
        ////Mat blob = CvDnn.BlobFromImage(img, 1.0 / 255.0, inputShape, new Scalar(0, 0, 0), true, false);
        // 将 blob 设置为网络的输入
        //net.SetInput(blob);

        //// 从图像生成用于网络输入的 blob
        Mat img0 = img;



        Mat blob0 = CvDnn.BlobFromImage(img0, 1 / 255.0, new OpenCvSharp.Size(inputShape.Width, inputShape.Height), swapRB: true, crop: false);
        net.SetInput(blob0);


        // 执行前向传播获取输出
        Mat output = net.Forward();
        // 此处可能需要根据 C# 中 OpenCV 的特性来处理转置操作
        output = ReshapeAndTranspose(output);


        // 获取图像的行数(高度)
        int height = img.Height;
        // 获取图像的列数(宽度)
        int width = img.Width;
        // 计算宽度的缩放因子
        double xFactor = (double)width / inputShape.Width;
        // 计算高度的缩放因子
        double yFactor = (double)height / inputShape.Height;

        // 初始化分类类别、得分和检测框的列表
        List<string> classifys = new List<string>();
        List<float> scores = new List<float>();
        List<Rect> boxes = new List<Rect>();

        List<Double> maxVales = new List<Double>();
        List<OpenCvSharp.Point> maxloces = new List<OpenCvSharp.Point>();

        // 遍历输出的行
        for (int i = 0; i < output.Rows; i++)
        {
            // 获取当前行的检测框数据
            using (Mat box = output.Row(i))
            {

                // 在框数据的特定范围中找到最小值、最大值及其位置
                OpenCvSharp.Point minloc, maxloc;
                double minVal, maxVal;
                // Mat classes_scores = box.ColRange(4, 5);//GetArray(i, 5, classes_scores);

                // double curmates0 = box.At<float>(0);
                double curmates1 = box.At<float>(4);
                int collength = box.Cols;
                int rowlength = box.Rows;


                Mat curmates = box.ColRange(4, box.Cols);
                //Cv2.MinMaxLoc(box.ColRange(4, box.Cols), out minVal, out maxVal, out minloc, out maxloc);
                Cv2.MinMaxLoc(box.ColRange(4, box.Cols), out minVal, out maxVal, out minloc, out maxloc);
                int classId = maxloc.Y;

                if (classId == 0)
                {
                    // 获取对应类别的得分                         
                    float score = (float)maxVal;

                    // 如果得分大于阈值
                    if (score > threshold)
                    {
                        // 将得分添加到得分列表
                        scores.Add(score);
                        // 将类别添加到类别列表
                        classifys.Add(modelClassify[classId]);

                        // 获取框的原始坐标
                        float x = box.At<float>(0, 0);
                        float y = box.At<float>(0, 1);
                        float w = box.At<float>(0, 2);
                        float h = box.At<float>(0, 3);


                        // 计算调整后的坐标
                        int xInt = (int)((x - 0.5 * w) * xFactor);
                        int yInt = (int)((y - 0.5 * h) * yFactor);
                        int wInt = (int)(w * xFactor);
                        int hInt = (int)(h * yFactor);
                        // 将调整后的框坐标添加到框列表
                        boxes.Add(new Rect(xInt, yInt, wInt, hInt));
                    }
                }

                   

            }
        }






        // 执行非极大值抑制操作
        int[] indices;
        CvDnn.NMSBoxes(boxes, scores, 0.25f, 0.45f, out indices);
        // 遍历非极大值抑制操作后的索引
        foreach (int i in indices)
        {
            // 获取对应的类别、得分和框
            string classify = classifys[i];
            float score = scores[i];
            Rect box = boxes[i];

            // 获取框的坐标和尺寸
            // 在图像上绘制矩形框
            Cv2.Rectangle(img, box, new Scalar(0, 255, 0), 3);
            // 生成类别和得分的标签文本
            string label = $"{classify}: {score:F2}";
            // 在图像上添加标签文本
            Cv2.PutText(img, label, new OpenCvSharp.Point(box.X, box.Y - 10), HersheyFonts.HersheySimplex, 0.5, new Scalar(0, 255, 0), 2);
        }
        // 将图像复制输出返回
        Mat result_image0 = img.Clone();
        return result_image0;
        // 将处理后的图像保存为文件
        // Cv2.ImWrite("result.jpg", img);
    }
}

代码实现演示(实现各种食物的类型检测)

源码下载链接

C# WinForms工业相机+本地图像 通过YoloV8深度学习模型实现各种食物的类型检测 源码

工业相机通过YoloV8模型实现各种食物的类型检测识别的行业应用

工业相机 + YOLOv8 在「各种食物类型检测识别」的 8 大最新行业应用

(信息均来自 2024-2025 年公开项目,按落地成熟度排序)

行业场景 业务痛点 工业相机/硬件形态 YOLOv8 技术方案 & 现场效果 公开资源
① 火龙果分级产线 成熟度人工判断误差大 4K 全局快门 60 fps + 环形 LED YOLOv8 + PSP-Ellipse 分割,成熟度准确率 97.6 %,2 秒/果 食品与机械 2024
② 餐饮场景智能监控 50 类菜品实时识别 8 K 线阵相机 20 kHz + 白光补光 YOLOv8 多类别检测,9284 张图训练,mAP@0.5 94 % CSDN 源码
③ 厨房餐具检测 7 类餐具(刀/叉/勺等)混放 顶装 4K 广角相机 YOLOv8 + 数据增强,遮挡/油污场景下识别率 96 % 微信公众号
④ 番茄新鲜度检测 新鲜/腐烂/半腐烂分类 6 mm 定焦 120 fps + 穹顶光 YOLOv8-seg,IoU 0.85,系统 PyQt5 界面一键部署 CSDN 博客
⑤ 柠檬品质等级识别 大小、瑕疵、色泽分级 分选线 5 MP 全局快门 YOLOv8 + SE 注意力,模型 3.1 MB,准确率 98 % CSDN 源码
⑥ 水果多品类分拣 19 类水果混合上料 龙门架 8 K 相机阵列 YOLOv8-tile 切片推理,单帧 25 ms,分拣误差 <1 % 知乎专栏
⑦ 冷链仓库盘点 肉类、蔬菜、水果混装 手持 12 MP 相机 + RTK YOLOv8 + DeepSort 跟踪,一次扫 20 箱,漏扫率 <0.1 % GitHub
⑧ 零售自助收银 商品遮挡、角度多变 广角 4K 相机 + 白光补光 网页版 YOLOv8 实时检测,支持图片/视频/摄像头三种输入 开源项目

关键技术细节

模型 :YOLOv8n/s/x 按需选型,输入 640×640;

小目标/遮挡:增加 P2 检测头 + CBAM/SE 注意力,mAP↑3-5 %;
部署 :Jetson Orin Nano INT8 量化 3-5 MB,单帧 15-25 ms;
合规 :原始图像 24 h 内自动覆盖,仅留识别结果,符合《数据安全法》。

一键体验

相关推荐
NAGNIP1 小时前
一文搞懂深度学习中的通用逼近定理!
人工智能·算法·面试
冬奇Lab2 小时前
一天一个开源项目(第36篇):EverMemOS - 跨 LLM 与平台的长时记忆 OS,让 Agent 会记忆更会推理
人工智能·开源·资讯
冬奇Lab2 小时前
OpenClaw 源码深度解析(一):Gateway——为什么需要一个"中枢"
人工智能·开源·源码阅读
AngelPP6 小时前
OpenClaw 架构深度解析:如何把 AI 助手搬到你的个人设备上
人工智能
宅小年6 小时前
Claude Code 换成了Kimi K2.5后,我再也回不去了
人工智能·ai编程·claude
九狼6 小时前
Flutter URL Scheme 跨平台跳转
人工智能·flutter·github
ZFSS7 小时前
Kimi Chat Completion API 申请及使用
前端·人工智能
天翼云开发者社区8 小时前
春节复工福利就位!天翼云息壤2500万Tokens免费送,全品类大模型一键畅玩!
人工智能·算力服务·息壤
知识浅谈8 小时前
教你如何用 Gemini 将课本图片一键转为精美 PPT
人工智能
Ray Liang8 小时前
被低估的量化版模型,小身材也能干大事
人工智能·ai·ai助手·mindx