首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

C# OpenCvSharp DNN 卡证检测矫正

  • 25-02-19 03:42
  • 4639
  • 5130
blog.csdn.net

目录

说明

效果

模型

项目

代码

下载

参考


说明

源码地址:https://modelscope.cn/models/iic/cv_resnet_carddetection_scrfd34gkps

在实人认证、文档电子化等场景中需要自动化提取卡证的信息,以便进一步做录入处理。这类场景通常存在两类问题,一是识别卡证类型时易受背景干扰,二是卡证拍摄角度造成的文字畸变影响OCR准确率。鉴于证件类数据的敏感性,我们采用大量合成卡证数据做训练(参见:SyntheticCards), 并改造人脸检测SOTA方法SCRFD(论文地址, 代码地址)训练了卡证检测矫正模型,可以对各类国际常见卡证(如,身份证、护照、驾照等)进行检测、定位及矫正,得到去除背景的正视角卡证图像,便于后续卡证分类或OCR内容提取。

效果

模型

Model Properties
-------------------------
---------------------------------------------------------------

Inputs
-------------------------
name:input.1
tensor:Float[1, 3, 640, 640]
---------------------------------------------------------------

Outputs
-------------------------
name:1401
tensor:Float[1, 25600, 1]
name:1455
tensor:Float[1, 6400, 1]
name:1507
tensor:Float[1, 1600, 1]
name:1408
tensor:Float[1, 25600, 4]
name:1461
tensor:Float[1, 6400, 4]
name:1513
tensor:Float[1, 1600, 4]
name:1415
tensor:Float[1, 25600, 8]
name:1467
tensor:Float[1, 6400, 8]
name:1519
tensor:Float[1, 1600, 8]
---------------------------------------------------------------

项目

代码

using OpenCvSharp;
using OpenCvSharp.Dnn;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;

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

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

        private void Form1_Load(object sender, EventArgs e)
        {
            startupPath = System.Windows.Forms.Application.StartupPath;

            image_path = "1.jpg";
            pictureBox1.Image = new Bitmap(image_path);
            image = new Mat(image_path);

            opencv_net = CvDnn.ReadNetFromOnnx("carddetection_scrfd34gkps.onnx");
        }

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

        Stopwatch stopwatch = new Stopwatch();
        Net opencv_net;
        Mat BN_image;
        Mat image;
        Mat result_image;

        float[] stride = { 8.0f, 16.0f, 32.0f };
        int inpWidth = 640;
        int inpHeight = 640;
        float confThreshold = 0.5f;
        float nmsThreshold = 0.5f;
        bool keep_ratio = true;

        Mat resize_image(Mat srcimg, ref int newh, ref int neww, ref int top, ref int left)
        {
            int srch = srcimg.Rows, srcw = srcimg.Cols;
            newh = inpHeight;
            neww = inpWidth;
            Mat dstimg = new Mat();
            if (keep_ratio && srch != srcw)
            {
                float hw_scale = (float)srch / srcw;
                if (hw_scale > 1)
                {
                    newh = inpHeight;
                    neww = (int)(inpWidth / hw_scale);
                    Cv2.Resize(srcimg, dstimg, new OpenCvSharp.Size(neww, newh));
                    left = (int)((inpWidth - neww) * 0.5);
                    Cv2.CopyMakeBorder(dstimg, dstimg, 0, 0, left, inpWidth - neww - left, BorderTypes.Constant, 0);
                }
                else
                {
                    newh = (int)(inpHeight * hw_scale);
                    neww = inpWidth;
                    Cv2.Resize(srcimg, dstimg, new OpenCvSharp.Size(neww, newh));
                    top = (int)((inpHeight - newh) * 0.5);
                    Cv2.CopyMakeBorder(dstimg, dstimg, top, inpHeight - newh - top, 0, 0, BorderTypes.Constant, 0);
                }
            }
            else
            {
                Cv2.Resize(srcimg, dstimg, new OpenCvSharp.Size(neww, newh));
            }
            return dstimg;
        }

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

            stopwatch.Restart();
            image = new Mat(image_path);
            result_image = image.Clone();

            int newh = 0, neww = 0, padh = 0, padw = 0;
            Mat img = resize_image(image, ref newh, ref neww, ref padh, ref padw);
            Mat blob = new Mat();

            BN_image = CvDnn.BlobFromImage(img, 1 / 128.0, new OpenCvSharp.Size(inpWidth, inpHeight), new Scalar(127.5, 127.5, 127.5), true, false);

            opencv_net.SetInput(BN_image);

            Mat[] outs = new Mat[9] { new Mat(), new Mat(), new Mat(), new Mat(), new Mat(), new Mat(), new Mat(), new Mat(), new Mat() };
            string[] outBlobNames = opencv_net.GetUnconnectedOutLayersNames();
            opencv_net.Forward(outs, outBlobNames);

            //generate proposals
            List confidences = new List();
            List boxes = new List();
            List> landmarks = new List>();
            float ratioh = (float)image.Rows / newh, ratiow = (float)image.Cols / neww;
            int n = 0, i = 0, j = 0, k = 0, l = 0;
            for (n = 0; n < 3; n++)
            {
                int num_grid_x = (int)(inpWidth / stride[n]);
                int num_grid_y = (int)(inpHeight / stride[n]);
                float* pdata_score = (float*)outs[n * 3].Data;  //score
                float* pdata_bbox = (float*)outs[n * 3 + 1].Data;  //bounding box
                float* pdata_kps = (float*)outs[n * 3 + 2].Data;  //face landmark
                for (i = 0; i < num_grid_y; i++)
                {
                    for (j = 0; j < num_grid_x; j++)
                    {
                        for (k = 0; k < 4; k++)
                        {
                            if (pdata_score[0] > confThreshold)
                            {
                                int xmin = (int)(((j - pdata_bbox[0]) * stride[n] - padw) * ratiow);
                                int ymin = (int)(((i - pdata_bbox[1]) * stride[n] - padh) * ratioh);
                                int width = (int)((pdata_bbox[2] + pdata_bbox[0]) * stride[n] * ratiow);
                                int height = (int)((pdata_bbox[3] + pdata_bbox[1]) * stride[n] * ratioh);
                                confidences.Add(pdata_score[0]);
                                boxes.Add(new Rect(xmin, ymin, width, height));
                                List landmark = new List();
                                for (l = 0; l < 8; l += 2)
                                {
                                    landmark.Add((int)(((j + pdata_kps[l]) * stride[n] - padw) * ratiow));
                                    landmark.Add((int)(((i + pdata_kps[l + 1]) * stride[n] - padh) * ratioh));
                                }
                                landmarks.Add(landmark);
                            }
                            pdata_score++;
                            pdata_bbox += 4;
                            pdata_kps += 8;
                        }
                    }
                }
            }

            //vector indices;
            int[] indices;
            CvDnn.NMSBoxes(boxes, confidences, confThreshold, nmsThreshold, out indices);
            //draw bbox and kps
            for (i = 0; i < indices.Length; ++i)
            {
                int idx = indices[i];
                Rect box = boxes[idx];
                Cv2.Rectangle(result_image, new OpenCvSharp.Point(box.X, box.Y), new OpenCvSharp.Point(box.X + box.Width, box.Y + box.Height), new Scalar(0, 0, 255), 2);
                for (k = 0; k < 8; k += 2)
                {
                    Cv2.Circle(result_image, new OpenCvSharp.Point(landmarks[idx][k], landmarks[idx][k + 1]), 10, new Scalar(0, 255, 0), -1);
                }
                //Get the label for the class name and its confidence
                string label = confidences[idx].ToString("P2");
                //Display the label at the top of the bounding box
                int baseLine;
                OpenCvSharp.Size labelSize = Cv2.GetTextSize(label, HersheyFonts.HersheySimplex, 0.5, 2, out baseLine);
                int top = Math.Max(box.Y, labelSize.Height);
                Cv2.PutText(result_image, label, new OpenCvSharp.Point(box.X, top - 10), HersheyFonts.HersheySimplex, 1, new Scalar(0, 255, 0), 2);
            }

            stopwatch.Stop();
            double costTime = stopwatch.Elapsed.TotalMilliseconds;

            textBox1.Text = $"耗时:{costTime:F2}ms";
            pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (pictureBox2.Image == null)
            {
                return;
            }
            Bitmap output = new Bitmap(pictureBox2.Image);
            var sdf = new SaveFileDialog();
            sdf.Title = "保存";
            sdf.Filter = "Images (*.jpg)|*.jpg|Images (*.png)|*.png|Images (*.bmp)|*.bmp";
            if (sdf.ShowDialog() == DialogResult.OK)
            {
                switch (sdf.FilterIndex)
                {
                    case 1:
                        {
                            output.Save(sdf.FileName, ImageFormat.Jpeg);
                            break;
                        }
                    case 2:
                        {
                            output.Save(sdf.FileName, ImageFormat.Png);
                            break;
                        }
                    case 3:
                        {
                            output.Save(sdf.FileName, ImageFormat.Bmp);
                            break;
                        }
                }
                MessageBox.Show("保存成功,位置:" + sdf.FileName);
            }
        }
    }
}

  1. using OpenCvSharp;
  2. using OpenCvSharp.Dnn;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.Drawing;
  7. using System.Drawing.Imaging;
  8. using System.Windows.Forms;
  9. namespace OpenCvSharp_Demo
  10. {
  11. public partial class Form1 : Form
  12. {
  13. public Form1()
  14. {
  15. InitializeComponent();
  16. }
  17. string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
  18. string startupPath;
  19. string image_path;
  20. private void Form1_Load(object sender, EventArgs e)
  21. {
  22. startupPath = System.Windows.Forms.Application.StartupPath;
  23. image_path = "1.jpg";
  24. pictureBox1.Image = new Bitmap(image_path);
  25. image = new Mat(image_path);
  26. opencv_net = CvDnn.ReadNetFromOnnx("carddetection_scrfd34gkps.onnx");
  27. }
  28. private void button1_Click(object sender, EventArgs e)
  29. {
  30. OpenFileDialog ofd = new OpenFileDialog();
  31. ofd.Filter = fileFilter;
  32. if (ofd.ShowDialog() != DialogResult.OK) return;
  33. pictureBox1.Image = null;
  34. pictureBox2.Image = null;
  35. textBox1.Text = "";
  36. image_path = ofd.FileName;
  37. pictureBox1.Image = new Bitmap(image_path);
  38. image = new Mat(image_path);
  39. }
  40. Stopwatch stopwatch = new Stopwatch();
  41. Net opencv_net;
  42. Mat BN_image;
  43. Mat image;
  44. Mat result_image;
  45. float[] stride = { 8.0f, 16.0f, 32.0f };
  46. int inpWidth = 640;
  47. int inpHeight = 640;
  48. float confThreshold = 0.5f;
  49. float nmsThreshold = 0.5f;
  50. bool keep_ratio = true;
  51. Mat resize_image(Mat srcimg, ref int newh, ref int neww, ref int top, ref int left)
  52. {
  53. int srch = srcimg.Rows, srcw = srcimg.Cols;
  54. newh = inpHeight;
  55. neww = inpWidth;
  56. Mat dstimg = new Mat();
  57. if (keep_ratio && srch != srcw)
  58. {
  59. float hw_scale = (float)srch / srcw;
  60. if (hw_scale > 1)
  61. {
  62. newh = inpHeight;
  63. neww = (int)(inpWidth / hw_scale);
  64. Cv2.Resize(srcimg, dstimg, new OpenCvSharp.Size(neww, newh));
  65. left = (int)((inpWidth - neww) * 0.5);
  66. Cv2.CopyMakeBorder(dstimg, dstimg, 0, 0, left, inpWidth - neww - left, BorderTypes.Constant, 0);
  67. }
  68. else
  69. {
  70. newh = (int)(inpHeight * hw_scale);
  71. neww = inpWidth;
  72. Cv2.Resize(srcimg, dstimg, new OpenCvSharp.Size(neww, newh));
  73. top = (int)((inpHeight - newh) * 0.5);
  74. Cv2.CopyMakeBorder(dstimg, dstimg, top, inpHeight - newh - top, 0, 0, BorderTypes.Constant, 0);
  75. }
  76. }
  77. else
  78. {
  79. Cv2.Resize(srcimg, dstimg, new OpenCvSharp.Size(neww, newh));
  80. }
  81. return dstimg;
  82. }
  83. unsafe private void button2_Click(object sender, EventArgs e)
  84. {
  85. if (image_path == "")
  86. {
  87. return;
  88. }
  89. stopwatch.Restart();
  90. image = new Mat(image_path);
  91. result_image = image.Clone();
  92. int newh = 0, neww = 0, padh = 0, padw = 0;
  93. Mat img = resize_image(image, ref newh, ref neww, ref padh, ref padw);
  94. Mat blob = new Mat();
  95. BN_image = CvDnn.BlobFromImage(img, 1 / 128.0, new OpenCvSharp.Size(inpWidth, inpHeight), new Scalar(127.5, 127.5, 127.5), true, false);
  96. opencv_net.SetInput(BN_image);
  97. Mat[] outs = new Mat[9] { new Mat(), new Mat(), new Mat(), new Mat(), new Mat(), new Mat(), new Mat(), new Mat(), new Mat() };
  98. string[] outBlobNames = opencv_net.GetUnconnectedOutLayersNames();
  99. opencv_net.Forward(outs, outBlobNames);
  100. //generate proposals
  101. List<float> confidences = new List<float>();
  102. List<Rect> boxes = new List<Rect>();
  103. List<List<int>> landmarks = new List>();
  104. float ratioh = (float)image.Rows / newh, ratiow = (float)image.Cols / neww;
  105. int n = 0, i = 0, j = 0, k = 0, l = 0;
  106. for (n = 0; n < 3; n++)
  107. {
  108. int num_grid_x = (int)(inpWidth / stride[n]);
  109. int num_grid_y = (int)(inpHeight / stride[n]);
  110. float* pdata_score = (float*)outs[n * 3].Data; //score
  111. float* pdata_bbox = (float*)outs[n * 3 + 1].Data; //bounding box
  112. float* pdata_kps = (float*)outs[n * 3 + 2].Data; //face landmark
  113. for (i = 0; i < num_grid_y; i++)
  114. {
  115. for (j = 0; j < num_grid_x; j++)
  116. {
  117. for (k = 0; k < 4; k++)
  118. {
  119. if (pdata_score[0] > confThreshold)
  120. {
  121. int xmin = (int)(((j - pdata_bbox[0]) * stride[n] - padw) * ratiow);
  122. int ymin = (int)(((i - pdata_bbox[1]) * stride[n] - padh) * ratioh);
  123. int width = (int)((pdata_bbox[2] + pdata_bbox[0]) * stride[n] * ratiow);
  124. int height = (int)((pdata_bbox[3] + pdata_bbox[1]) * stride[n] * ratioh);
  125. confidences.Add(pdata_score[0]);
  126. boxes.Add(new Rect(xmin, ymin, width, height));
  127. List<int> landmark = new List<int>();
  128. for (l = 0; l < 8; l += 2)
  129. {
  130. landmark.Add((int)(((j + pdata_kps[l]) * stride[n] - padw) * ratiow));
  131. landmark.Add((int)(((i + pdata_kps[l + 1]) * stride[n] - padh) * ratioh));
  132. }
  133. landmarks.Add(landmark);
  134. }
  135. pdata_score++;
  136. pdata_bbox += 4;
  137. pdata_kps += 8;
  138. }
  139. }
  140. }
  141. }
  142. //vector<int> indices;
  143. int[] indices;
  144. CvDnn.NMSBoxes(boxes, confidences, confThreshold, nmsThreshold, out indices);
  145. //draw bbox and kps
  146. for (i = 0; i < indices.Length; ++i)
  147. {
  148. int idx = indices[i];
  149. Rect box = boxes[idx];
  150. Cv2.Rectangle(result_image, new OpenCvSharp.Point(box.X, box.Y), new OpenCvSharp.Point(box.X + box.Width, box.Y + box.Height), new Scalar(0, 0, 255), 2);
  151. for (k = 0; k < 8; k += 2)
  152. {
  153. Cv2.Circle(result_image, new OpenCvSharp.Point(landmarks[idx][k], landmarks[idx][k + 1]), 10, new Scalar(0, 255, 0), -1);
  154. }
  155. //Get the label for the class name and its confidence
  156. string label = confidences[idx].ToString("P2");
  157. //Display the label at the top of the bounding box
  158. int baseLine;
  159. OpenCvSharp.Size labelSize = Cv2.GetTextSize(label, HersheyFonts.HersheySimplex, 0.5, 2, out baseLine);
  160. int top = Math.Max(box.Y, labelSize.Height);
  161. Cv2.PutText(result_image, label, new OpenCvSharp.Point(box.X, top - 10), HersheyFonts.HersheySimplex, 1, new Scalar(0, 255, 0), 2);
  162. }
  163. stopwatch.Stop();
  164. double costTime = stopwatch.Elapsed.TotalMilliseconds;
  165. textBox1.Text = $"耗时:{costTime:F2}ms";
  166. pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());
  167. }
  168. private void button3_Click(object sender, EventArgs e)
  169. {
  170. if (pictureBox2.Image == null)
  171. {
  172. return;
  173. }
  174. Bitmap output = new Bitmap(pictureBox2.Image);
  175. var sdf = new SaveFileDialog();
  176. sdf.Title = "保存";
  177. sdf.Filter = "Images (*.jpg)|*.jpg|Images (*.png)|*.png|Images (*.bmp)|*.bmp";
  178. if (sdf.ShowDialog() == DialogResult.OK)
  179. {
  180. switch (sdf.FilterIndex)
  181. {
  182. case 1:
  183. {
  184. output.Save(sdf.FileName, ImageFormat.Jpeg);
  185. break;
  186. }
  187. case 2:
  188. {
  189. output.Save(sdf.FileName, ImageFormat.Png);
  190. break;
  191. }
  192. case 3:
  193. {
  194. output.Save(sdf.FileName, ImageFormat.Bmp);
  195. break;
  196. }
  197. }
  198. MessageBox.Show("保存成功,位置:" + sdf.FileName);
  199. }
  200. }
  201. }
  202. }

下载

源码下载

参考

https://github.com/hpc203/cv_resnet_carddetection_scrfd34gkps-opencv-dnn

天天代码码天天
微信公众号
.NET 人工智能实践
注:本文转载自blog.csdn.net的天天代码码天天的文章"https://lw112190.blog.csdn.net/article/details/144754559"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top