halcon识别验证码,先训练后识别

news2025/1/9 12:51:34

识别验证码图片,使用halcon 21.05
下面代码识别准确率100%

目录

    • 训练,图片打标签
    • 使用代码创建分类器;
    • 识别验证码,检验识别效果
    • 使用“助手”加载训练文件,加载训练分类器,察看收集的字符,训练识别准确率

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

训练,图片打标签

* 
* Training of the OCR
* The font is used in "bottle.hdev"
* 
* 
* Step 0: Preparations
 

* 
* Step 1: Segmentation
FontName:='yan_zheng_ma119'

* 训练文件保存
TrainingFileName:='E:/Work/'+FontName+'.trf'

* 分类器保存
FontFileOMC:='E:/Work/'+FontName+'.omc'

dev_update_window ('off')
*训练
* 1  ,18   
* 30
*  已经训练 
* 已经训练了39,40,52
    * 图29、54 重点识别
*   read_image (Image, 'E:/Work/验证码图片/9.jpg')   
read_image (Image, 'E:/Work/验证码图片1/744.jpg')
    
*获取图片尺寸
get_image_size (Image, Width, Height)
dev_close_window ()
dev_open_window (0, 0, 4 * Width, 7 * Height, 'black', WindowID)
* 设置打印字符的大小
set_display_font (WindowID, 80, 'mono', 'true', 'false')

*放大图片
zoom_image_size(Image,ImageZoom,4 * Width,4 * Height ,'constant')
 

*创建指定区域
gen_rectangle1 (Rectangle, 36, 57, 189, 588)
* 获取图片指定区域的图片
reduce_domain(ImageZoom,Rectangle,imgMask)


* 根据阈值选取图像,筛选体积大的,数字越大体积越大,红色为选中
*threshold (Image, RawSegmentation, 200, 300)
threshold (imgMask, RawSegmentation, 0.1, 160)



*connection (circleRegion, ConnectedRegions)

*内部充满
fill_up (RawSegmentation, RegionFillUp)

*char_threshold (Image, Image, Characters, 3, 50, Threshold)

*根据形状特征填充孔洞
 *fill_up_shape(RawSegmentation, fillRegin, 'area', 5, 5)

*去掉小的模块
*opening_rectangle1 (RegionFillUp, Cut,2,2)

*利用矩形结构元素执行开运算。矩形宽设为1,高为7,相当于低于7的连接被截断
*opening_rectangle1 (RegionFillUp, Cut,3, 3)

*分割粘连字符  10,30,,60,80    不行:90,100;宽度79,74,84,71
  * 20 等号污染了问号;
  * per 55识别成功29、54
  *partition_dynamic(circleRegion,parRegion,70,55)
   
  * 成功拆分,图片9
  *partition_dynamic(circleRegion,parRegion,55,50)
   * 成功拆分,图片11
  * partition_dynamic(circleRegion,parRegion,55,55)
 * 成功拆分,图片29   
  *partition_dynamic(circleRegion,parRegion,55,70)
 *成功划分7.jpg  `
   *partition_dynamic(circleRegion,parRegion,60,70)
  *成功划分998.jpg    
 *  partition_dynamic(circleRegion,parRegion,60,50)

     *將單個字符暈染連成一塊,水平、垂直方向延伸粘连
    closing_rectangle1 (RegionFillUp, RegionClosing1,1, 25)
     
* 开口可以消除小区域(比圆形结构元件小)并平滑区域的边界。
opening_circle (RegionClosing1, circleRegion,5)
     
     *着色
     connection (circleRegion, ConnPatterns)
 
*分割 ,默认以 partition_dynamic分割,能正确分割大多数图片情况;
*partition_dynamic(RegionFillUp,parRegion,60,50)
 partition_rectangle (ConnPatterns, par2, 76, 150)
partition_dynamic(ConnPatterns,par1,60,80)
  
*着色对象个数
  count_obj (par1, par1_count)
  count_obj (par2, par2_count)
  
  AgainCheck:=0
  
  * 检查两个对象分割的块个数是否一致
  if ( par1_count != par2_count )
      partition_rectangle (ConnPatterns, par1, 76, 150)
      
       AgainCheck:=1
  endif
  
  
   * 第二次检查,每个分割块的宽度,是否在允许范围?
   if (AgainCheck==0)
        count_obj (par1, par1_count)
        
              *select_obj调用之前,必须调用sort_region
              sort_region (par1, SortedRegions2, 'first_point', 'true', 'column')
*                select_obj (SortedRegions2, CharRegion, 1)
*                select_obj (SortedRegions2, CharRegion, 2)
*                select_obj (SortedRegions2, CharRegion, 3)
*                select_obj (SortedRegions2, CharRegion, 4)
*                select_obj (SortedRegions2, CharRegion, 5)              
            
              for P := 1 to par1_count   by 1
                select_obj (SortedRegions2, CharRegion, P )
                
                 * 获取region的宽度
                 region_features (CharRegion, 'width', CharWidth)
                 if (CharWidth < 46  or  CharWidth>107 )
                      partition_rectangle (ConnPatterns, par1, 76, 150)
                      break
                 endif
                 
              endfor
   endif

*  与threshold后的图,求交集
intersection (par1, RawSegmentation, NumberCandidates)
 
* 选择指定尺寸的块
select_shape (NumberCandidates, Numbers, ['width','height'], 'and',[40, 10],[100,150])

*着色对象个数
* count_obj (Numbers, Check_count)
* 如果着色对象数不足5个,说明分割有问题
* if ( Check_count!=5)
*       partition_rectangle (ConnPatterns, par2, 76, 150) 
*       intersection (par2, RawSegmentation, NumberCandidates)
*       select_shape (NumberCandidates, Numbers, ['width','height'], 'and',[40, 10],[100,150])
* endif


sort_region (Numbers, SortedRegions, 'first_point', 'true', 'column')
dev_display (imgMask)
dev_set_color ('green')
dev_set_line_width (2)
dev_set_shape ('rectangle1')
dev_set_draw ('margin')
dev_display (SortedRegions)
* 
stop()

*----------------训练模型,开始-----------------------
TrainingNames := ['1','/','1','=' ,'?']
*TrainingFileName := FontName + '.trf'
shape_trans (SortedRegions, RegionTrans, 'rectangle1')
area_center (RegionTrans, Area, Row, Column)
MeanRow := mean(Row)
dev_set_check ('~give_error')
*delete_file (TrainingFileName)
dev_set_check ('give_error')
 
*图片数字下标
K:=0
for I := 0 to |Column| - 1 by 1
    select_obj (SortedRegions, CharaterRegions, I+1)
    * 获取region的宽度
   *  region_features (CharaterRegions, 'width', CharWidth)
     
    gen_empty_region (EmptyObject)     
    if(CharaterRegions!=EmptyObject)          
         append_ocr_trainf (CharaterRegions, imgMask, TrainingNames[K], TrainingFileName)
         disp_message (WindowID, TrainingNames[K], 'window', MeanRow+180, Column[I]-26, 'magenta', 'false') 
        K:=K+1
    endif
      
  
endfor

*----------------训练模型,结束-----------------------


使用代码创建分类器;

在所有的样本图片都打上标签后,就可以训练多层感知分类器了


TrainFile:='E:/Work/yan_zheng_ma119.trf'
FontFileOMC:='E:/Work/yan_zheng_ma119.omc'

*读取训练文件的字符
read_ocr_trainf_names (TrainFile, CharacterNames, CharacterCount)

*使用多层感知器创建OCR分类器。
create_ocr_class_mlp (8, 10, 'constant', 'default', CharacterNames, 20,'none', 81, 42, OCRHandle)

*训练OCR分类器。
trainf_ocr_class_mlp (OCRHandle, TrainFile, 100, 0.01, 0.01, Error, ErrorLog)

*写入分类器文件保存
write_ocr_class_mlp (OCRHandle, FontFileOMC)

识别验证码,检验识别效果



* 
* Step 1: Segmentation
FontName:='yan_zheng_ma119'

* 分类器保存
FontFileOMC:='E:/Work/'+FontName+'.omc'

dev_update_window ('off')

*训练
 * 重点识别:图29、54、9,11,
 *
 * 循环图片文件列表,一个个识别
 
 *读取目录里面的文件
 list_files ('E:/Work/验证码3', ['files' ], ImageFiles)
 
 for ImgIndex := 1 to |ImageFiles|  by 1
 *for ImgIndex := 1 to 1000  by 1 
  fileName:=ImageFiles[ImgIndex - 1]
  read_image (Image, fileName) 
*   read_image (Image, 'E:/Work/验证码图片/29.jpg')
 
  * 拆分字符串
  tuple_split(fileName,'\\',fileNameShort)
  *取最后一个字符串
  fileShortName:=fileNameShort[5]
  
  *文件数量数
   fileCount := |ImageFiles|
   * 待处理文件数
   fileCount_surplus  := |ImageFiles|-ImgIndex

get_image_size (Image, Width, Height)
dev_close_window ()
dev_open_window (0, 0, 4 * Width, 7 * Height, 'black', WindowID)
* 设置显示字体大小
set_display_font (WindowID, 27, 'mono', 'true', 'false')

zoom_image_size(Image,ImageZoom,4 * Width,4 * Height ,'constant')

 *显示图片序号
disp_message (WindowID, fileShortName+',剩余待处理数'+fileCount_surplus+'/'+fileCount, 'window', 0, 0, 'magenta', 'false') 
 

*regiongrowing (ImageInvert, Regions, 2, 2, 1, 255)
*gen_rectangle1 (Rectangle, 4.875, 24.125, 46.625, 141.875)
gen_rectangle1 (Rectangle, 36, 57, 189, 588)
reduce_domain(ImageZoom,Rectangle,imgMask)

* 筛选体积大的,数字越大体积越大,红色为选中
threshold (imgMask, RawSegmentation, 0.1, 160)


*内部充满
fill_up (RawSegmentation, RegionFillUp)

*char_threshold (Image, Image, Characters, 3, 50, Threshold)

*根据形状特征填充孔洞
 *fill_up_shape(RawSegmentation, fillRegin, 'area', 5, 5)

*去掉小的模块
*opening_rectangle1 (RegionFillUp, Cut,2,2)

*利用矩形结构元素执行开运算。矩形宽设为1,高为7,相当于低于7的连接被截断
*opening_rectangle1 (RegionFillUp, Cut,3, 3)

     *將單個字符暈染連成一塊,水平、垂直方向延伸粘连
    closing_rectangle1 (RegionFillUp, RegionClosing1,1, 25)

     
* 开口可以消除小区域(比圆形结构元件小)并平滑区域的边界。
opening_circle (RegionClosing1, circleRegion,5)
     
     *着色
     connection (circleRegion, ConnPatterns)
 
*分割粘连字符 ,默认以 partition_dynamic分割,能正确分割大多数图片情况;
*partition_dynamic(RegionFillUp,parRegion,60,50)
 partition_rectangle (ConnPatterns, par2, 76, 150)
partition_dynamic(ConnPatterns,par1,60,80)
  
*着色对象个数
  count_obj (par1, par1_count)
  count_obj (par2, par2_count)
  
  AgainCheck:=0
  
  * 检查两个对象分割的块个数是否一致
  if ( par1_count != par2_count )
      partition_rectangle (ConnPatterns, par1, 76, 150)
      
       AgainCheck:=1
  endif
  
  
   * 第二次检查,每个分割块的宽度,是否在允许范围?
   if (AgainCheck==0)
        count_obj (par1, par1_count)
        
              *select_obj调用之前,必须调用sort_region
              sort_region (par1, SortedRegions2, 'first_point', 'true', 'column')
*                select_obj (SortedRegions2, CharRegion, 1)
*                select_obj (SortedRegions2, CharRegion, 2)
*                select_obj (SortedRegions2, CharRegion, 3)
*                select_obj (SortedRegions2, CharRegion, 4)
*                select_obj (SortedRegions2, CharRegion, 5)              
            
              for P := 1 to par1_count   by 1
                select_obj (SortedRegions2, CharRegion, P )
                
                 * 获取region的宽度
                 region_features (CharRegion, 'width', CharWidth)
                 if (CharWidth < 46  or  CharWidth>107 )
                      partition_rectangle (ConnPatterns, par1, 76, 150)
                      break
                 endif
                 
              endfor
   endif

*  与threshold后的图,求交集
intersection (par1, RawSegmentation, NumberCandidates)
 
* 选择指定尺寸的块
select_shape (NumberCandidates, Numbers, ['width','height'], 'and',[40, 10],[100,150])

*着色对象个数
* count_obj (Numbers, Check_count)
* 如果着色对象数不足5个,说明分割有问题
* if ( Check_count!=5)
*       partition_rectangle (ConnPatterns, par2, 76, 150) 
*       intersection (par2, RawSegmentation, NumberCandidates)
*       select_shape (NumberCandidates, Numbers, ['width','height'], 'and',[40, 10],[100,150])
* endif

sort_region (Numbers, SortedRegions, 'first_point', 'true', 'column')
dev_display (imgMask)
dev_set_color ('green')
dev_set_line_width (2)
dev_set_shape ('rectangle1')
dev_set_draw ('margin')
dev_display (SortedRegions)
* 
* stop()
 
shape_trans (SortedRegions, RegionTrans, 'rectangle1')
area_center (RegionTrans, Area, Row, Column)
MeanRow := mean(Row)
dev_set_check ('~give_error')

dev_set_check ('give_error')
 
* 设置显示字体大小
set_display_font (WindowID, 80, 'mono', 'true', 'false')

*----------------识别 ,开始 -----------------------
read_ocr_class_mlp (FontFileOMC, OCRHandle2)

*图片数字下标
K:=0
for I := 0 to |Column| - 1 by 1
    select_obj (SortedRegions, CharaterRegions, I+1)
     
    gen_empty_region (EmptyObject)     
    if(CharaterRegions!=EmptyObject)          
         do_ocr_multi_class_mlp (CharaterRegions, imgMask, OCRHandle2, Class, Confidence)
         disp_message (WindowID, Class, 'window', MeanRow+180, Column[I]-26, 'magenta', 'false') 
        K:=K+1
    endif
      
    * 不打印第二个数字右侧的 =,?
   if( I==2 )
       break
   endif
    
endfor

* 等待0.5秒钟
 wait_seconds (0.5)

* 循环图片结束
 endfor

*----------------识别 ,结束-----------------------


使用“助手”加载训练文件,加载训练分类器,察看收集的字符,训练识别准确率

在这里插入图片描述在这里插入图片描述
加载训练文件,加载分类器;
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

创建数据透视表:根据表中一列作为分类的依据统计每个类别下不同子项数量cross_tab()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 创建数据透视表&#xff1a; 根据表中一列作为分类的依据 统计每个类别下不同子项数量 cross_tab() [太阳]选择题 关于以下代码的说法中正确的是? import pandas as pd data{A:[a1,a2,a1,a2,a…

StyleGAN:彻底改变生成对抗网络的艺术

一、介绍 多年来&#xff0c;人工智能领域取得了显着的进步&#xff0c;其中最令人兴奋的领域之一是生成模型的发展。这些模型旨在生成与人类创作没有区别的内容&#xff0c;例如图像和文本。其中&#xff0c;StyleGAN&#xff08;即风格生成对抗网络&#xff09;因其创建高度逼…

数据库概率 期末复习

第一章 绪论 概述 数据 定义&#xff1a;描述事物的符号记录 地位&#xff1a;数据库中存储的基本对象 数据的语义&#xff1a;数据的含义&#xff0c;数据与其语义是不可分的 数据库 定义&#xff1a;长期储存在计算机内、有组织的、可共享的大量数据的集合 特点&…

JSP 购物商城系统eclipse定制开发mysql数据库BS模式java编程servlet

一、源码特点 java 购物商城系统是一套完善的web设计系统 系统采用serlvetdaobean 模式开发&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模 式开发。开发环境为TOMCAT7.0,eclipse开发&#xff0c;数…

从0开始学习JavaScript--JavaScript 异步编程

在现代的Web开发中&#xff0c;异步编程变得愈发重要。随着用户期望的提高和网络应用的复杂性增加&#xff0c;有效地处理异步操作成为构建高性能、交互丰富的应用的关键。JavaScript作为一门单线程的语言&#xff0c;采用异步机制来处理并发任务&#xff0c;确保用户体验不受阻…

计算机网络五层协议的体系结构

计算机网络中两个端系统之间的通信太复杂&#xff0c;因此把需要问题分而治之&#xff0c;通过把一次通信过程中涉及的所有问题分层归类来进行研究和处理 体系结构是抽象的&#xff0c;实现是真正在运行的软件和硬件 1.实体、协议、服务和服务访问点 协议必须把所有不利条件和…

php实现选择排序法

选择排序法是一种简单的排序算法&#xff0c;其基本思想是每次从未排序的部分中选择最小&#xff08;或最大&#xff09;的元素&#xff0c;然后放到已排序部分的末尾。 以下是用PHP实现选择排序法的代码示例&#xff1a; <?php function selectionSort($arr) {$n count…

LeetCode - 26. 删除有序数组中的重复项 (C语言,快慢指针,配图)

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 ​​​​​​​ 思路一&#xff1a;快慢指针 在数组中&#xff0c;快慢指针就是两个整数下标&#xff0c;定义 fast 和 slow 这里我们从下标1开始&#xff08;下标0的数据就1个&#xff0c;没有重复项&…

RabbitMQ之延迟队列(万字总结,手把手教你学习延迟队列)

文章目录 一、延迟队列概念二、延迟队列使用场景三、RabbitMQ 中的 TTL1、队列设置 TTL2、消息设置 TTL3、两者的区别 四、整合 springboot1、添加依赖2、修改配置文件3、添加 Swagger 配置类 五、队列 TTL1、代码架构图2、配置文件类代码3、消息生产者代码4、消息消费者代码 六…

RT-Thread STM32F407 ADC

ADC(Analog-to-Digital Converter) 指模数转换器。是指将连续变化的模拟信号转换为离散的数字信号的器件。真实世界的模拟信号&#xff0c;例如温度、压力、声音或者图像等&#xff0c;需要转换成更容易储存、处理和发射的数字形式。模数转换器可以实现这个功能&#xff0c;在各…

如何解决网页中的pdf文件无法下载?pdf打印显示空白怎么办?

问题描述 偶然间&#xff0c;遇到这样一个问题&#xff0c;一个网页上的附件pdf想要下载打印下来&#xff0c;奈何尝试多种办法都不能将其下载下载&#xff0c;点击打印出现的也是一片空白 百度搜索了一些解决方案都不太行&#xff0c;主要解决方案如&#xff1a;https://zh…

计算机网络——物理层-编码与调制(数字基带信号、模拟基带信号、码元、常用编码、基本调制方法、混合调制)

目录 编码与调制 数字基带信号 模拟基带信号 码元 常用编码 不归零编码 归零编码 曼彻斯特编码 差分曼彻斯特编码 编码习题 基本调制方法 调幅 调频 调相 混合调制 QAM-16 编码与调制 在计算机网络中&#xff0c;计算机需要处理和传输用户的文字、图片、音频…

JavaScript学习_01——JavaScript简介

JavaScript简介 JavaScript介绍 JavaScript是一种轻量级的脚本语言。所谓“脚本语言”&#xff0c;指的是它不具备开发操作系统的能力&#xff0c;而是只用来编写控制其他大型应用程序的“脚本”。 JavaScript 是一种嵌入式&#xff08;embedded&#xff09;语言。它本身提供…

ubuntu中cuda12.1配置(之前存在11.1版本的cuda)(同时配置两个版本)

ubuntu中cuda12.1配置 由于YOLOv8项目中Pytorch版本需要cuda12.1版本 在官网下载12.1版本的deb包 官网地址 sudo dpkg -i cuda-keyring_1.0-1_all.deb sudo apt-get update sudo apt-get -y install cuda然后需要修改bashrc文件&#xff08;隐藏文件&#xff09; 添加 exp…

C#,数值计算——插值和外推,BaryRat_interp的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// 重心有理插值对象 /// Barycentric rational interpolation object. /// After constructing the object, /// call interp for interpolated values. /// Note t…

供应商选择和评估:如何寻找合适的供应商并与其合作

如果供应商不能按时交货或产品质量低劣&#xff0c;制造商的生产计划就会延误&#xff1b;客户交货将被延迟&#xff0c;商品可能被退回&#xff0c;你的公司声誉也将受损。 要在当今竞争激烈的市场中取得成功&#xff0c;你需要一流的、价格合理且来源可靠的原材料和服务&…

Leetcode刷题详解——岛屿数量

1. 题目链接&#xff1a;200. 岛屿数量 2. 题目描述&#xff1a; 给你一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的的二维网格&#xff0c;请你计算网格中岛屿的数量。 岛屿总是被水包围&#xff0c;并且每座岛屿只能由水平方向和/或竖直方向上…

php快速排序法

快速排序是一种常用的排序算法&#xff0c;也是最快的排序算法之一。其基本思想是通过一趟排序将待排序的数据分割成两部分&#xff0c;其中一部分的所有数据都比另一部分的所有数据小&#xff0c;然后再对这两部分分别进行快速排序&#xff0c;递归地重复这个过程&#xff0c;…

wpf devexpress post 更改数据库

这个教程示范如何使用GridControl编辑数据&#xff0c;和保存更改到数据库。这个教程基于前一个篇。 Items Source Wizard 当 CRUD (Create, Read, Update, Delete) 启动选项时添加Post data功能 Items Source Wizard 生成如下代码&#xff1a; 1、设置 TableView.ShowUpdat…

滚雪球学Java(09-1):Java中的算术运算符,你真的掌握了吗?

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…