OCR文字识别标注小助手
  yqdtHKhvd9Ja 2023年12月15日 24 0


目录

背景

工具界面

操作

1、选择目录

2、更改为正确的信息

3、保存

4、说明

项目

代码

下载

训练后识别效果


背景

为什么要写这么一个小工具呢?因为要对文字进行标注。

为什么对文字进行标注呢?因为要重新训练识别。

为什么要重新训练识别呢?因为通用OCR识别识别不了。(通用OCR识别参考 )

什么样子的图片通用OCR识别不了呢?它来了,如下图

OCR文字识别标注小助手_计算机视觉

放大看一个

OCR文字识别标注小助手_人工智能_02

识别不了的原因主要是特殊字体+横线干扰

打算重新训练之前,做过哪些努力呢?

1、更换精度更高的服务器端模型,效果不好,放弃

2、图片预处理,去掉文字后面的横线(去掉文字后面横线参考:),再识别,效果不好,放弃。

所以自己标注,重新训练了。

训练效果如何?看最后!

工具界面

OCR文字识别标注小助手_ocr_03

操作

1、选择目录

OCR文字识别标注小助手_ocr_04

选择后默认加载第一张图片

OCR文字识别标注小助手_c#_05

文本框里面的字哪里来的呢,是我用通用OCR识别的,虽然效果不好,但是还是能识别一些,标注的时候可以少打几个字。

2、更改为正确的信息

OCR文字识别标注小助手_c#_06

3、保存

点击保存,或者键盘Enter,自动加载下一张图片,效率还不错。

//保存图片
 Cv2.ImWrite(TargetFolderPath + txtName.Text + "." + name.Split('.')[1], src);
 //写个缓存
 FileStream fs = new FileStream(CacheFolderPath + name.Split('.')[0] + ".txt", FileMode.Create);
 StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);
 sw.WriteLine(txtName.Text);
 sw.Close();
 fs.Close();if (pictureBox2.Image != null)
 {
     pictureBox2.Image.Dispose();
 }if (src != null)
 {
     src.Dispose();
 }//下一张
 button2_Click(null, null);

OCR文字识别标注小助手_计算机视觉_07

4、说明

OCR文字识别标注小助手_Text_08

默认会在选择的目录下生成两个文件夹,标注不会对原数据进行任何处理。

target存放标注好保存的文件。

cache记录一下标注的文件,方便后续工作(比如今天标不完了,关机下班,明天来了打开工具,可以从昨天标注的图片的下一张图片继续标注)。

项目

OCR文字识别标注小助手_Text_09

代码

代码写的比较糙,因为只是一个临时性的工具,需要的可以根据自己的需要修改、重构。

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

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

        int index = -1;
        Mat src;
        String name;
        String ImageFolderPath;
        String TargetFolderPath;
        String CacheFolderPath;
        List<String> ImgFile = new List<string>();
        List<String> CacheImgFile = new List<string>();

        //下一张
        private void button2_Click(object sender, EventArgs e)
        {
            index = index + 1;

            if (index > ImgFile.Count - 1)
            {
                index = ImgFile.Count;
                MessageBox.Show("下一张没有了,干完了!");
                return;
            }

            ShowImg(index);
        }

        //上一张
        private void button4_Click(object sender, EventArgs e)
        {
            index = index - 1;

            if (index < 0)
            {
                MessageBox.Show("上一张没有了");
                index = 0;
                return;
            }

            ShowImg(index);
        }

        private void ShowImg(int index)
        {
            name = ImgFile[index];
            txtName.Text = name.Split('.')[0];
            txtInfo.Text = name + " " + index + "/" + ImgFile.Count;

            if (File.Exists(CacheFolderPath + name.Split('.')[0] + ".txt"))
            {
                string info = System.IO.File.ReadAllText(CacheFolderPath + name.Split('.')[0] + ".txt");
                if (info.StartsWith("del_"))
                {
                    //标记为删除
                    txtInfo.Text = name + "[标记为删除] " + (index + 1).ToString() + "/" + ImgFile.Count;
                }
                else
                {
                    //已经标注
                    txtInfo.Text = name + "[已经标注] " + (index + 1) + "/" + ImgFile.Count;
                    txtName.Text = info;
                }
            }
            else
            {
                //未标注
                txtInfo.Text = name + " " + (index + 1) + "/" + ImgFile.Count;
            }

            if (src!=null)
            {
                src.Dispose();
            }

            if (pictureBox2.Image != null)
            {
                pictureBox2.Image.Dispose();
            }

            src = new Mat(ImageFolderPath + name);

            pictureBox2.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(src);

        }

        //保存
        private void button1_Click(object sender, EventArgs e)
        {
            //保存图片
            Cv2.ImWrite(TargetFolderPath + txtName.Text + "." + name.Split('.')[1], src);

            //写个缓存
            FileStream fs = new FileStream(CacheFolderPath + name.Split('.')[0] + ".txt", FileMode.Create);
            StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);
            sw.WriteLine(txtName.Text);
            sw.Close();
            fs.Close();

            if (pictureBox2.Image != null)
            {
                pictureBox2.Image.Dispose();
            }

            if (src != null)
            {
                src.Dispose();
            }

            //下一张
            button2_Click(null, null);
        }

        /// <summary>
        /// 选择目录
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dialog = new FolderBrowserDialog();

            if (dialog.ShowDialog(this) != DialogResult.OK)
            {
                return;
            }

            ImageFolderPath = dialog.SelectedPath + "\\";

            TargetFolderPath = ImageFolderPath + "target\\";
            CacheFolderPath = ImageFolderPath + "cache\\";

            if (!Directory.Exists(TargetFolderPath))
            {
                Directory.CreateDirectory(TargetFolderPath);
            }

            DirectoryInfo root = new DirectoryInfo(ImageFolderPath);
            foreach (FileInfo f in root.GetFiles())
            {
                if (f.Extension.Contains(".jpg") || f.Extension.Contains(".jpeg") || f.Extension.Contains(".png"))
                {
                    ImgFile.Add(f.Name);
                }
            }

            if (ImgFile.Count == 0)
            {
                MessageBox.Show("没有图片");
                return;
            }

            txtInfo.Text = "共计[" + ImgFile.Count + "]张图片";

            if (!Directory.Exists(CacheFolderPath))
            {
                Directory.CreateDirectory(CacheFolderPath);
            }
            else
            {
                //定位上一次标注的位置,然后下一张
                root = new DirectoryInfo(CacheFolderPath);
                foreach (FileInfo f in root.GetFiles())
                {
                    if (f.Extension.Contains(".txt"))
                    {
                        CacheImgFile.Add(f.Name);
                    }
                }

                if (CacheImgFile.Count > 0)
                {
                    string lastImg = CacheImgFile.Last();
                    lastImg = lastImg.Split('.')[0];
                    string temp = ImgFile.Find(o => o.StartsWith(lastImg));
                    if (!string.IsNullOrEmpty(temp))
                    {
                        index = ImgFile.IndexOf(temp);
                    }
                }
            }

            //自动下一张
            button2_Click(null, null);

        }

        //删除
        private void button5_Click(object sender, EventArgs e)
        {
            //保存
            Cv2.ImWrite(TargetFolderPath + "del_" + txtName.Text + "." + name.Split('.')[1], src);

            //写个缓存
            FileStream fs = new FileStream(CacheFolderPath + name.Split('.')[0] + ".txt", FileMode.Create);
            StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);
            sw.WriteLine("del_" + txtName.Text);
            sw.Close();
            fs.Close();

            if (pictureBox2.Image != null)
            {
                pictureBox2.Image.Dispose();
            }

            if (!src.Empty())
            {
                src.Dispose();
            }

            //下一张
            button2_Click(null, null);
        }
    }
}

下载

源码下载

训练后识别效果

OCR文字识别标注小助手_c#_10

OCR文字识别标注小助手_ocr_11

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月15日 0

暂无评论

推荐阅读
yqdtHKhvd9Ja