計算機設計大賽 深度學習火車票識別系統

文章目錄

  • 0 前言
  • 1 課題意義
    • 課題難點:
  • 2 實現方法
    • 2.1 圖像預處理
    • 2.2 字符分割
    • 2.3 字符識別
      • 部分實現代碼
  • 3 實現效果
  • 4 最后

0 前言

🔥 優質競賽項目系列,今天要分享的是

🚩 圖像識別 火車票識別系統

該項目較為新穎,適合作為競賽課題方向,學長非常推薦!

🥇學長這里給一個題目綜合評分(每項滿分5分)

  • 難度系數:3分
  • 工作量:3分
  • 創新點:4分

🧿 更多資料, 項目分享:

https://gitee.com/dancheng-senior/postgraduate

1 課題意義

在這里插入圖片描述

目前火車乘務員在臥鋪旅客在上車前為其提供將火車票換成位置信息卡服務,在旅客上車前,由于上車人數多,而且大多數旅客都攜帶大量行李物品,而且乘車中老人和小孩也較多。在換卡這一過程中,人員擁擠十分厲害,而且上火車時,火車門窄階梯也較陡,危險系數十分高。乘務員維持秩序十分困難。換卡之后,在旅客下車之前乘務員又要將位置信息卡換成火車票。這一過程冗長且對于旅客基本沒有任何有用的意義。如果通過光學符識別軟件,乘務員利用ipad等電子產品掃描采集火車票圖像,讀取文本圖像,通過識別算法轉成文字,將文字信息提取出來,之后存儲起來,便于乘務員統計查看,在旅客到站是,系統自動提醒乘務員某站點下車的所有旅客位置信息。隨著鐵路交通的不斷優化,車次與旅客人數的增加,火車票免票系統將更加便捷,為人們帶來更好的服務。

課題難點:

由于火車票票面文字識別屬于多種字體混排,低品質的專用印刷漢子識別。火車票文字筆畫粘連,斷裂,識別復雜度高,難度大,采用目前較好的OCR技術都比較難以實現。

2 實現方法

2.1 圖像預處理

火車票經過掃描裝置火車照相機等裝置將圖像傳遞到計算機,經過灰度處理保存為一幅灰度圖。如果要對火車票進行后期的識別,那么就一定要對圖像做二值化,之后再對二值化的圖像進行版面分析,確定我們所需要的信息所在,之后才能進行單個字符的分割,才能對字符做提取特征點的工作,之后按照我們對比確定的規則來進行判決從而達到識別效果。

由于火車票容易被污損、彎折,而且字符的顏色也是有所不同,火車票票號是紅色,而其他信息顯示則為黑色,票面的背景包括紅色和藍色兩種彩色,這些特點都使得火車票的文字識別不同于一般的文字識別。在識前期,要對火車票圖像做出特定的處理才能很好的進行后續的識別。本次課題所研究的預處理有平常所處理的二值化,平滑去噪之外還需要針對不同字符顏色來進行彩色空間上的平滑過濾。

預處理流程如下所示

在這里插入圖片描述

2.2 字符分割

字符分割就是在版面分析后得到的文本塊切分成為文字行,之后再將行分割成單個字符,來進行后續的字符識別。這是OCR系統里至關重要的一環,直接影響識別效果。字符分割的主流方式有三種,一種是居于圖像特種來尋找分割的準則,這是從結構角度進行分析切割。另一種方式是根據識別效果反饋來確認分割結果有無問題,這種方式是基于識別的切分。還有一種整體切分方式,把字符串當做整體,系統進行以詞為基礎的識別比并非字識別,一般這一方式要根據先驗知識來進行輔助判斷。

分割效果如下圖所示:
在這里插入圖片描述
在這里插入圖片描述

2.3 字符識別

中文/數字/英文 識別目前最高效的方法就是使用深度學習算法進行識別。

字符識別對于深度學習開發者來說是老生常談了,這里就不在復述了;

網絡可以視為編解碼器結構,編碼器由特征提取網絡ResneXt-50和雙向長短時記憶網絡(BiLSTM)構成,解碼器由加入注意力機制的長短時記憶網絡(LSTM)構成。網絡結構如下圖所示。

在這里插入圖片描述

網絡訓練流程如下:
在這里插入圖片描述

部分實現代碼

這里學長提供一個簡單網絡字符識別的訓練代碼:
(需要完整工程及代碼的同學聯系學長獲取)

?

import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
#1、開始建立一個圖
sess = tf.InteractiveSession()#啟動一個交互會話
x = tf.placeholder(tf.float32, shape=[None, 784])#x和y_都用一個占位符表示
y_ = tf.placeholder(tf.float32, shape=[None, 10])W = tf.Variable(tf.zeros([784, 10]))#W和b因為需要改變,所以定義為初始化為0的變量
b = tf.Variable(tf.zeros(10))#2、建立預測部分的操作節點
y = tf.matmul(x,W) + b  #計算wx+b
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y)) #計算softmax交叉熵的均值#3、現在已經得到了損失函數,接下來要做的就是最小化這一損失函數,這里用最常用的梯度下降做
# 為了用到前幾節說過的內容,這里用學習率隨訓練下降的方法執行
global_step = tf.Variable(0, trainable = False)#建立一個可變數,而且這個變量在計算梯度時候不被影響,其實就是個全局變量
start_learning_rate = 0.5#這么寫是為了清楚
#得到所需的學習率,學習率每100個step進行一次變化,公式為decayed_learning_rate = learning_rate * decay_rate ^(global_step / decay_steps)
learning_rate = tf.train.exponential_decay(start_learning_rate, global_step, 10, 0.9, staircase=True)train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(cross_entropy)#梯度下降最小化交叉熵
#這是因為在交互的Session下可以這樣寫Op.run(),還可以sess.run(tf.global_variables_initializer())
tf.global_variables_initializer().run()#初始化所有變量#iteration = 1000, Batch_Size = 100 
for _ in range(1000):batch = mnist.train.next_batch(100)#每次選出100個數據train_step.run(feed_dict = {x:batch[0], y_: batch[1]})#給Placeholder填充數據就可以了correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1)) #首先比較兩個結果的差異
#這時的correct_prediction應該類似[True, False, True, True],然后只要轉為float的形式再求加和平均就知道準確率了
#這里的cast是用于形式轉化
accuracy = tf.reduce_mean(tf.cast(correct_prediction, dtype=tf.float32))
#打印出來就可以了,注意這個時候accuracy也只是一個tensor,而且也只是一個模型的代表,還需要輸入數據
print(accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels}))sess.close()#首先把要重復用的定義好
def weight_variable(shape):initial = tf.truncated_normal(shape=shape, stddev=0.1)return tf.Variable(initial)
def bias_variable(shape):initial = tf.constant(0.1, shape=shape)#常量轉變量,return tf.Variable(initial)
def conv2d(x, f):return tf.nn.conv2d(x, f, strides=[1,1,1,1], padding='SAME')
def max_pool_22(x):return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')sess = tf.InteractiveSession()#啟動一個交互會話
x = tf.placeholder(tf.float32, shape=[None, 784])#x和y_都用一個占位符表示
y_ = tf.placeholder(tf.float32, shape=[None, 10])
x_image = tf.reshape(x, [-1, 28, 28, 1])
#第一層:
#1、設計卷積核1
fW1 = weight_variable([5,5,1,32])#[height, weight, in_channel, out_channel]
fb1 = bias_variable([32])#2、卷積加池化
h1 = tf.nn.relu(conv2d(x_image,fW1)+ fb1)
h1_pool = max_pool_22(h1)#第二層
fW2 = weight_variable([5,5,32,64])#[height, weight, in_channel, out_channel]
fb2 = bias_variable([64])h2 = tf.nn.relu(conv2d(h1_pool,fW2)+ fb2)
h2_pool = max_pool_22(h2)#全部變成一維全連接層,這里因為是按照官方走的,所以手動計算了經過第二層后的圖片尺寸為7*7
#來定義了一個wx+b所需的w和b的尺寸,注意這里的W和b不是卷積所用的了
h2_pool_flat = tf.reshape(h2_pool, [-1, 7*7*64])#首先把數據變成行表示
W_fc1 = weight_variable([7 * 7 * 64, 1024])
b_fc1 = bias_variable([1024])
h_fc1 = tf.nn.relu(tf.matmul(h2_pool_flat, W_fc1) + b_fc1)#定義dropout,選擇性失活,首先指定一個失活的比例
prob = tf.placeholder(tf.float32)
h_dropout = tf.nn.dropout(h_fc1, prob)#最后一個全連接層,輸出10個值,用于softmax
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])
y_conv = tf.matmul(h_dropout, W_fc2) + b_fc2#梯度更新,這里采用另一種優化方式AdamOptimizer
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y_conv))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))#初始化
sess.run(tf.global_variables_initializer())
for i in range(2000):batch = mnist.train.next_batch(50)if i%100 == 0:train_accuracy = accuracy.eval(feed_dict = {x:batch[0],y_:batch[1], prob:1.0}) #這里是計算accuracy用的eval,不是在run一個Operationprint("step %d, training accuracy %g"%(i, train_accuracy))train_step.run(feed_dict={x: batch[0], y_: batch[1], prob: 0.5})
print("test accuracy %g"%accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels, prob: 1.0}) )

3 實現效果

車票圖
在這里插入圖片描述
識別效果:
在這里插入圖片描述

4 最后

🧿 更多資料, 項目分享:

https://gitee.com/dancheng-senior/postgraduate

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/716069.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/716069.shtml
英文地址,請注明出處:http://en.pswp.cn/news/716069.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Pycharm的下載安裝與漢化

一.下載安裝包 1.接下來按照步驟來就行 2.然后就能在桌面上找到打開了 3.先建立一個文件夾 二.Pycharm的漢化

ABAP - SALV教程07 斑馬紋顯示和SALV標題

SALV設置斑馬紋和標題 METHOD set_layout.DATA: lo_display TYPE REF TO cl_salv_display_settings. * 取得顯示對象lo_display co_alv->get_display_settings( ).* 設置ZEBRA顯示lo_display->set_striped_pattern( X ). * 設置Titlelo_display->set_list_he…

企業微信變更主體怎么改?

企業微信變更主體有什么作用?做過企業運營的小伙伴都知道,很多時候經常會遇到現有的企業需要注銷,切換成新的企業進行經營的情況,但是原來企業申請的企業微信上面卻積累了很多客戶,肯定不能直接丟棄,所以這…

【二】【SQL】去重表數據及分組聚合查詢

去重表數據 表的準備工作 去除表中重復的數據,重復的數據只留一份。 mysql> create table duplicate_table (-> id int,-> name varchar(20)-> ); Query OK, 0 rows affected (0.03 sec)mysql> insert into duplicate_table values-> (100,aaa)…

Day24-yum與rpm軟件包管理2

Day24-yum與rpm軟件包管理2 1. 配置緩存rpm包2. 為什么要緩存?3. 組包相關指令4. yum幫助與補全功能4.1 補全4.2 什么是yum源4.3 常見互聯網 yum 源 5. 搭建局域網YUM倉庫實踐 1. 配置緩存rpm包 修改yum.conf配置 [rootoldboy ~]# sed -i.bak s#keepcache0#keepca…

SLAM基礎知識:前端和后端

在基于濾波的SLAM算法中,使用迭代卡爾曼濾波(Iterative Kalman Filtering)來求解當前幀狀態量的步驟通常屬于SLAM系統的前端部分。 前端負責處理傳感器數據,進行狀態估計和地圖構建的初步步驟。迭代卡爾曼濾波作為一種濾波器&…

批次大小對ES寫入性能影響初探

問題背景 ES使用bulk寫入時每批次的大小對性能有什么影響?設置每批次多大為好? 一般來說,在Elasticsearch中,使用bulk API進行批量寫入時,每批次的大小對性能有著顯著的影響。具體來說,當批量請求的大小增…

PVLAN組網實驗

一,PVLAN類型 主VLAN 主VLAN可以由多個輔助私用VLAN組成,而這些輔VLAN與主VLAN屬于同一子網。 輔助VLAN ① 團體VLAN:如果某個端口屬于團體VLAN,那么它就不僅能夠與相同團體VLAN中的其他端口進行通信,而且還能夠與…

使用rsync同步服務器和客戶端的文件夾

使用rsync同步服務器和客戶端的文件夾 實現目的實驗準備實驗操作步驟服務器操作關閉防火墻和SELINUX安裝rsync修改服務器配置文件/etc/rsync.conf創建服務器備份文件的目錄創建rsync系統運行的用戶修改備份文件的所有者和所屬組創建rsync.passwd啟動rsync服務并進行驗證 客戶端…

中間件安全(概述)有中間件的各類鏈接和官網信息和漏洞庫以及配置問題和開源工具

分類主要包括Apache、IIS、Tomcat、weblogic、websphere、Jboss等相關的技術知識和實踐。 以Apache為例講一講如何保證中間件安全 中間件安全是指保護中間件軟件和服務的安全性,防止被惡意攻擊或者濫用。中間件軟件是指在操作系統和應用程序之間提供通信和集成功能…

【Go】命令行相關

查看go的環境 go env # 查看go的環境變量 goRoot # 編譯器的環境 goPath設置go module 打開cmd命令行,執行以下命令 go env -w GO111MODULEoff # on-打開 off-關閉 auto-自動相關命令 go build # 項目路徑下執行,能編譯當前go項目(一個…

RFID(Radio Frequency Identification)技術筆記

一、RFID的介紹 RFID,全稱為Radio Frequency Identification,即射頻識別技術,也常被稱為電子標簽或無線射頻識別。它是一種非接觸式的自動識別技術,通過射頻信號自動識別目標對象并獲取相關數據,識別過程無需人工干預&…

[云原生] k8s之pod容器

一、pod的相關知識 1.1 Pod基礎概念 Pod是kubernetes中最小的資源管理組件,Pod也是最小化運行容器化應用的資源對象。一個Pod代表著集群中運行的一個進程。kubernetes中其他大多數組件都是圍繞著Pod來進行支撐和擴展Pod功能的,例如,用于管理…

如何確保JDK版本與操作系統架構匹配?

1. 序言 最近的工作中,需要升級JDK版本到17.0.7,以解決一個JDK bug:JDK-8299626該bug的core dump關鍵字如下:SIGSEGV in PhaseIdealLoop::build_loop_late_post_work公司JDK團隊提供的、包含JDK的基礎鏡像,有aarch64和…

Hololens2開發環境配置及項目生成部署

Hololens2開發環境配置及項目生成部署 Hololens2開發環境配置及項目生成部署一、官方文檔及推薦配置說明1.官方文檔介紹2.推薦配置及配置說明 二、安裝步驟0.現有Visual Stuido和Unity卸載1.Windows SDK安裝2.Visual Studio安裝3.Unity安裝4.MRTK配置 三、初次環境配置1.新建Un…

vmware的詭異網絡

坦白說,vmware的網絡我始終是沒有搞太懂。 我習慣使用的是“僅主機”和“NAT”。 “僅主機”我習慣配置靜態IP,互相訪問沒問題。 “NAT”則主要用于windows系統,簡單方便。windows虛擬機一般也沒啥特別的互相訪問需求,直接文件復制…

簡單了解GaussDB

大家都已經很熟悉openGauss了,昨天我的文章中說陜西電力的用采系統用Gaussdb替代了Oracle,就有朋友問我這個Gaussdb是不是就是openGauss。這個問題還真的有點不好回答,Gaussdb和openGauss淵源很近,但是還不是一碼事。華為在數據庫…

c++八股文:c++面向對象

文章目錄 1.c面向對象三大特性2.c的三個訪問修飾符3.多重繼承4.重載與重寫5.c多態怎么實現6.成員函數/成員變量/靜態成員函數/靜態成員變量的區別7.構造函數和析構函數8.c構造函數有幾種9.什么是虛函數什么是虛函數表10.虛函數和純虛函數的區別11.抽象類和純虛函數12.虛析構13.…

ABAP - SALV教程05 添加頁眉和頁腳

先看看效果叭CL_SALV_TABLE提供了SET_TOP_OF_LIST方法設置頁眉顯示和SET_TOP_OF_LIST_PRINT方法設置頁眉打印來實現添加頁眉的目的。CL_SALV_TABLE提供了SET_END_OF_LIST方法設置頁腳顯示和SET_END_OF_LIST_PRINT方法設置頁腳打印來實現添加頁腳的目的。這個四個方法的傳入參數…

Flutter異常上報及性能監控實現

1. 頁面異常監測 在Flutter中,通常用FlutterError監測Flutter框架拋出的異常,用runZonedGuarded監測應用中用戶代碼異常。 class AppGuarded {run(Widget app) {//1. 用FlutterError監測flutter框架拋出的異常FlutterError.onError (FlutterErrorDetail…