C# OpenCvSharp DNN 实现百度网盘AI大赛-表格检测第2名方案第一部分-表格边界框检测

news2024/12/21 4:12:48

目录

说明

效果

模型

项目

代码

frmMain.cs

YoloDet.cs 

参考

下载

其他


说明

百度网盘AI大赛-表格检测的第2名方案。

该算法包含表格边界框检测、表格分割和表格方向识别三个部分,首先,ppyoloe-plus-x 对边界框进行预测,并对置信度较高的表格边界框(box)进行裁剪。裁剪后的单个表格实例会送入到DBNet中进行语义分割,分割结果通过opencv轮廓处理获得表格关键点(point)。之后,我们根据DBNet计算的关键点在裁剪后的单个表格实例上绘制表格边界。最后,PP-LCNet结合表格边界先验和表格实例图像,对表格的方向进行预测,并根据之前定义的几何轮廓点与语义轮廓点的对应关系,将几何轮廓点映射为语义轮廓点。

本文使用C# OpenCvSharp DNN 实现百度网盘AI大赛-表格检测第2名方案第一部分-表格边界框检测。

效果

模型

Model Properties
-------------------------
date:2024-10-28T13:52:42.181333
description:Ultralytics YOLO11l model trained on coco.yaml
author:Ultralytics
version:8.3.23
task:detect
license:AGPL-3.0 License (https://ultralytics.com/license)
docs:https://docs.ultralytics.com
stride:32
batch:1
imgsz:[928, 928]
names:{0: 'table'}
---------------------------------------------------------------

Inputs
-------------------------
name:images
tensor:Float[1, 3, 928, 928]
---------------------------------------------------------------

Outputs
-------------------------
name:output0
tensor:Float[1, 5, 17661]
---------------------------------------------------------------

项目

代码

frmMain.cs

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

namespace OpenCvSharp_DNN_Demo
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }

        YoloDet obj_detector;

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

        DateTime dt1 = DateTime.Now;
        DateTime dt2 = DateTime.Now;

        Mat image;

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

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

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

        private void Form1_Load(object sender, EventArgs e)
        {
            string obj_model_path = "model/yolo_obj_det.onnx";

            obj_detector = new YoloDet(obj_model_path);

            image_path = "test_img/real5.jpg";
            pictureBox1.Image = new Bitmap(image_path);

        }

        private unsafe void button2_Click(object sender, EventArgs e)
        {
            if (image_path == "")
            {
                return;
            }
            textBox1.Text = "检测中,请稍等……";
            pictureBox2.Image = null;
            Application.DoEvents();

            Mat src = new Mat(image_path);

            dt1 = DateTime.Now;
            List<Bbox> result = obj_detector.infer(src);
            dt2 = DateTime.Now;

            //绘制
            Mat draw_img = src.Clone();
            for (int i = 0; i < result.Count; i++)
            {
                Rect r = Rect.FromLTRB(result[i].xmin, result[i].ymin, result[i].xmax, result[i].ymax);

                Cv2.PutText(draw_img, $"table:{result[0].score:P0}", new OpenCvSharp.Point(r.TopLeft.X, r.TopLeft.Y - 10), HersheyFonts.HersheySimplex, 8, Scalar.Red, 8);
                Cv2.Rectangle(draw_img, r, Scalar.Red, thickness: 8);

                //裁剪,保存,为下一步检测做准备
                Mat crop_img = new Mat(src, r);
                Cv2.ImWrite(i + ".jpg", crop_img);
            }
            pictureBox2.Image = new Bitmap(draw_img.ToMemoryStream());
            textBox1.Text = "推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms";
        }
       
        private void pictureBox2_DoubleClick(object sender, EventArgs e)
        {
            Common.ShowNormalImg(pictureBox2.Image);
        }
        
        private void pictureBox1_DoubleClick(object sender, EventArgs e)
        {
            Common.ShowNormalImg(pictureBox1.Image);
        }
    }
}
 

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

namespace OpenCvSharp_DNN_Demo
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }

        YoloDet obj_detector;

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

        DateTime dt1 = DateTime.Now;
        DateTime dt2 = DateTime.Now;

        Mat image;

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

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

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

        private void Form1_Load(object sender, EventArgs e)
        {
            string obj_model_path = "model/yolo_obj_det.onnx";

            obj_detector = new YoloDet(obj_model_path);

            image_path = "test_img/real5.jpg";
            pictureBox1.Image = new Bitmap(image_path);

        }

        private unsafe void button2_Click(object sender, EventArgs e)
        {
            if (image_path == "")
            {
                return;
            }
            textBox1.Text = "检测中,请稍等……";
            pictureBox2.Image = null;
            Application.DoEvents();

            Mat src = new Mat(image_path);

            dt1 = DateTime.Now;
            List<Bbox> result = obj_detector.infer(src);
            dt2 = DateTime.Now;

            //绘制
            Mat draw_img = src.Clone();
            for (int i = 0; i < result.Count; i++)
            {
                Rect r = Rect.FromLTRB(result[i].xmin, result[i].ymin, result[i].xmax, result[i].ymax);

                Cv2.PutText(draw_img, $"table:{result[0].score:P0}", new OpenCvSharp.Point(r.TopLeft.X, r.TopLeft.Y - 10), HersheyFonts.HersheySimplex, 8, Scalar.Red, 8);
                Cv2.Rectangle(draw_img, r, Scalar.Red, thickness: 8);

                //裁剪,保存,为下一步检测做准备
                Mat crop_img = new Mat(src, r);
                Cv2.ImWrite(i + ".jpg", crop_img);
            }
            pictureBox2.Image = new Bitmap(draw_img.ToMemoryStream());
            textBox1.Text = "推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms";
        }
       
        private void pictureBox2_DoubleClick(object sender, EventArgs e)
        {
            Common.ShowNormalImg(pictureBox2.Image);
        }
        
        private void pictureBox1_DoubleClick(object sender, EventArgs e)
        {
            Common.ShowNormalImg(pictureBox1.Image);
        }
    }
}

YoloDet.cs 

using OpenCvSharp;
using OpenCvSharp.Dnn;
using System;
using System.Collections.Generic;
using System.Linq;

namespace OpenCvSharp_DNN_Demo
{
    internal class YoloDet
    {

        Net model;
        int[] resize_shape = new int[2] { 928, 928 };

        public YoloDet(string model_path)
        {
            model = CvDnn.ReadNetFromOnnx(model_path);
        }

        unsafe public List<Bbox> infer(Mat srcimg, float score = 0.4f)
        {
            int ori_h = srcimg.Rows;
            int ori_w = srcimg.Cols;
            img_preprocess
            Mat img;
            int new_w = 0;
            int new_h = 0;
            int left = 0;
            int top = 0;
            img = Common.ResizePad(srcimg, resize_shape[0], ref new_w, ref new_h, ref left, ref top);

            //Cv2.ImWrite("0.jpg", img);

            img.ConvertTo(img, MatType.CV_32FC3, 1.0 / 255.0);
            Mat blob = CvDnn.BlobFromImage(img);

            model.SetInput(blob);

            //模型推理,读取推理结果
            Mat[] outs = new Mat[1] { new Mat() };
            string[] outBlobNames = model.GetUnconnectedOutLayersNames().ToArray();
            model.Forward(outs, outBlobNames);

            img_postprocess
            float x_factor = (float)ori_w / new_w;
            float y_factor = (float)ori_h / new_h;
            List<Rect> boxes = new List<Rect>();
            List<float> scores = new List<float>();
            int rows = outs[0].Size(2);

            //将推理结果转为float数据类型
            //5, 17661
            Mat result_mat = new Mat(5, 17661, MatType.CV_32F, outs[0].Data);
            result_mat = result_mat.T();
            //string str = result_mat.Dump();

            for (int i = 0; i < rows; i++)
            {
                float* ptr = (float*)(result_mat.Ptr(i).ToPointer());
                float max_score = ptr[4];
                //float max_score = result_mat.At<float>(i, 4);

                if (max_score >= score)
                {
                    //At效率不高
                    //float x1 = result_mat.At<float>(i, 0);
                    //float y2 = result_mat.At<float>(i, 1);
                    //float w2 = result_mat.At<float>(i, 2);
                    //float h2 = result_mat.At<float>(i, 3);

                    float x = ptr[0];
                    float y = ptr[1];
                    float w = ptr[2];
                    float h = ptr[3];

                    int xmin = Math.Max((int)((x - w / 2 - left) * x_factor), 0);
                    int ymin = Math.Max((int)((y - h / 2 - top) * y_factor), 0);
                    boxes.Add(new Rect(xmin, ymin, (int)(w * x_factor), (int)(h * y_factor)));
                    scores.Add(max_score);
                }
            }

            int[] indices;
            CvDnn.NMSBoxes(boxes, scores, score, 0.4f, out indices);
            int num_keep = indices.Length;
            List<Bbox> bboxes = new List<Bbox>();
            for (int i = 0; i < num_keep; i++)
            {
                int ind = indices[i];
                bboxes.Add(new Bbox(boxes[ind].X, boxes[ind].Y, Math.Min(boxes[ind].X + boxes[ind].Width, ori_w - 1), Math.Min(boxes[ind].Y + boxes[ind].Height, ori_h - 1), scores[ind]));
            }
            return bboxes;
        }
    }
}

/*
 
 Model Properties
-------------------------
date:2024-10-28T13:52:42.181333
description:Ultralytics YOLO11l model trained on coco.yaml
author:Ultralytics
version:8.3.23
task:detect
license:AGPL-3.0 License (https://ultralytics.com/license)
docs:https://docs.ultralytics.com
stride:32
batch:1
imgsz:[928, 928]
names:{0: 'table'}
---------------------------------------------------------------

Inputs
-------------------------
name:images
tensor:Float[1, 3, 928, 928]
---------------------------------------------------------------

Outputs
-------------------------
name:output0
tensor:Float[1, 5, 17661]
---------------------------------------------------------------

 */

参考

https://github.com/hpc203/TableDetection
 
https://aistudio.baidu.com/projectdetail/5398861?searchKeyword=%E8%A1%A8%E6%A0%BC%E6%A3%80%E6%B5%8B%E5%A4%A7%E8%B5%9B&searchTab=ALL

下载

源码下载

其他

C# OnnxRuntime 第二部分-表格分割-CSDN博客

C# OpenCvSharp DNN 第三部分-表格方向识别-CSDN博客

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

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

相关文章

创建项目以及本地仓库和远程仓库并上传项目

创建项目以及本地仓库和远程仓库并上传项目 其详细流程如下&#xff1a; 1、本地创建项目 2、创建本地仓库&#xff08;若使用idea在创建项目时选择了创建.git本地仓库&#xff0c;则此步骤省略&#xff09; 进入到你需要上传的项目的目录下&#xff0c;右键找到Git Bah He…

鸿蒙操作系统简介

华为鸿蒙系统&#xff08;HUAWEI HarmonyOS&#xff09;&#xff0c;是华为公司于2019年8月9日在东莞举行的华为开发者大会&#xff08;HDC.2019&#xff09;上正式发布的面向全场景的分布式操作系统&#xff0c;可以创造一个超级虚拟终端互联的世界&#xff0c;将人、设备、场…

MySQL存储引擎-概述

存储引擎 存储引擎&#xff08;Storage Engine&#xff09;是数据库管理系统中负责数据存储和检索的部分。之前在MySQL的历史地位中曾经讲过&#xff0c;存储引擎是可插拔的。5.5之前默认采用MyISAM存储引擎&#xff0c;从5.5开始采用InnoDB存储引擎。 9大存储引擎 可以通过…

【网络取证篇】取证实战之PHP服务器镜像网站重构及绕密分析

【网络取证篇】取证实战之PHP服务器镜像网站重构及绕密分析 在裸聊敲诈、虚假理财诈骗案件类型中&#xff0c;犯罪分子为了能实现更低成本、更快部署应用的目的&#xff0c;其服务器架构多为常见的初始化网站架构&#xff0c;也称为站库同体服务器&#xff01;也就是说网站应用…

【数据结构进阶】AVL树深度剖析 + 实现(附源码)

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;数据结构 目录 前言 一、AVL树的概念 二、AVL树底层解析及实现 1. 节点的定义 2. 接口声明 3. AVL树的插入 3.1 更新平衡因子 3.2 旋转&#xff08;重点…

java_断点调试(debug)

按照如下配置好后&#xff0c;即可点击“F7”,进入相应的方法&#xff0c;查看源码 package com.hspedu.debug_;//debug对象创建的过程&#xff0c;加深对调试的理解 public class Debug01 {public static void main(String[] args) {//创建对象的流程//&#xff08;1&#xff…

YOLOv11融合[CVPR2024]Starnet中的star block特征提取模块

YOLOv11v10v8使用教程&#xff1a; YOLOv11入门到入土使用教程 YOLOv11改进汇总贴&#xff1a;YOLOv11及自研模型更新汇总 《Rewrite the Stars》 一、 模块介绍 论文链接&#xff1a;https://arxiv.org/abs/2403.19967 代码链接&#xff1a;https://github.com/ma-xu/Rewri…

【kubernetes】k8s集群的简述与搭建

简述 Kubernetes&#xff08;简称 K8s&#xff09;是一个开源的容器编排平台&#xff0c;用于自动化部署、扩展和管理容器化应用程序 关键特性 自动化部署和回滚&#xff1a;Kubernetes 可以自动化地部署和回滚应用程序&#xff0c;确保应用程序始终处于预期的状态。服务发现…

SpringBoot+vue实现WebSocket通信

WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单&#xff0c;允许服务器主动向客户端推送数据。 WebSocket的主要特点&#xff1a; 全双工通信&#xff1a;客户端和服务器之间的数据可以同时双向传输低延迟&…

【BUG】记一次context canceled的报错

文章目录 案例分析gorm源码解读gin context 生命周期context什么时候cancel的什么时候context会被动cancel掉呢&#xff1f; 野生协程如何处理 案例分析 报错信息 {"L":"ERROR","T":"2024-12-17T11:11:33.0050800","file"…

H5 中 van-popup 的使用以及题目的切换

H5 中 van-popup 的使用以及题目的切换 在移动端开发中&#xff0c;弹窗组件是一个常见的需求。vant 是一个轻量、可靠的移动端 Vue 组件库&#xff0c;其中的 van-popup 组件可以方便地实现弹窗效果。本文将介绍如何使用 van-popup 实现题目详情的弹窗展示&#xff0c;并实现…

【第一节】Git的简介和安装

目录 一、git的介绍 二、git 的安装 2.1 Linux 平台安装 2.2 源码安装 2.3 Windows 平台安装 2.4 Mac 平台安装 2.5 Git 配置 2.5.1 配置文件 2.5.2 用户信息配置 2.5.3 文本编辑器配置 2.5.4 差异分析工具配置 2.5.5 查看配置信息 一、git的介绍 Git 是一种开源的…

奇怪的知识又增加了,ESP32下的Lisp编程:ULisp--Lisp for microcontrollers

ESP32下有MicroPython&#xff0c;那么我就在想&#xff0c;有Lisp语言支持吗&#xff1f;答案是果然有&#xff01;有ULisp&#xff0c;专门为MCU设计的Lisp&#xff01; 网址&#xff1a;uLisp - Lisp for microcontrollers 介绍&#xff1a;用于微控制器的 Lisp 适用于 Ar…

决策树的生成与剪枝

决策树的生成与剪枝 决策树的生成生成决策树的过程决策树的生成算法 决策树的剪枝决策树的损失函数决策树的剪枝算法 代码 决策树的生成 生成决策树的过程 为了方便分析描述&#xff0c;我们对上节课中的训练样本进行编号&#xff0c;每个样本加一个ID值&#xff0c;如图所示…

51c嵌入式~单片机~合集2

我自己的原文哦~ https://blog.51cto.com/whaosoft/12362395 一、不同的电平信号的MCU怎么通信&#xff1f; 下面这个“电平转换”电路&#xff0c;理解后令人心情愉快。电路设计其实也可以很有趣。 先说一说这个电路的用途&#xff1a;当两个MCU在不同的工作电压下工作&a…

Kerberos实验

kdc&#xff1a;192.168.72.163 客户端&#xff08;机器账户win10&#xff09;&#xff1a;192.168.72.159 用户&#xff1a;administrator 抓包&#xff1a;开机登录win10&#xff0c;使用administrator域用户凭据登录。 生成 Kerberos 解密文件 抓取 krbtgt 用户和 win1…

AI一键分析小红书对标账号‼️

宝子们&#xff0c;AI小助手近期发现了一款宝藏AI工具&#xff0c;拥有对标账号AI分析功能&#xff0c;只需10秒就能全面掌握对标账号的运营情况&#xff0c;并且可以根据分析结果提供创作方向和灵感&#xff0c;轻松助力1:1复刻起号&#xff01; 功能亮点&#xff1a; &…

大腾智能CAD:国产云原生三维设计新选择

在快速发展的工业设计领域&#xff0c;CAD软件已成为不可或缺的核心工具。它通过强大的建模、分析、优化等功能&#xff0c;不仅显著提升了设计效率与精度&#xff0c;还促进了设计思维的创新与拓展&#xff0c;为产品从概念构想到实体制造的全过程提供了强有力的技术支持。然而…

VMware虚拟机 Ubuntu没有共享文件夹的问题

在虚拟机的Ubuntu系统中&#xff0c;共享文件目录存放在 mnt/hgfs 下面&#xff0c;但是我安装完系统并添加共享文件后发现&#xff0c;在mnt下连/hgfs目录都没有。 注意&#xff1a;使用共享文件目录需要已安装VMtools工具。 添加共享文件目录 一&#xff1a;在超级用户下 可…