国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當前位置: 首頁 > news >正文

山東做網(wǎng)站的公司蘭州做網(wǎng)站的公司

山東做網(wǎng)站的公司,蘭州做網(wǎng)站的公司,網(wǎng)站一年費用多少錢,中山網(wǎng)站建設(shè)平臺文章目錄 0 簡介1 項目背景2 項目目的3 系統(tǒng)設(shè)計3.1 目標對象3.2 系統(tǒng)架構(gòu)3.3 軟件設(shè)計方案 4 圖像預(yù)處理4.1 灰度二值化4.2 形態(tài)學處理4.3 算式提取4.4 傾斜校正4.5 字符分割 5 字符識別5.1 支持向量機原理5.2 基于SVM的字符識別5.3 SVM算法實現(xiàn) 6 算法測試7 系統(tǒng)實現(xiàn)8 最后 0…

文章目錄

  • 0 簡介
  • 1 項目背景
  • 2 項目目的
  • 3 系統(tǒng)設(shè)計
    • 3.1 目標對象
    • 3.2 系統(tǒng)架構(gòu)
    • 3.3 軟件設(shè)計方案
  • 4 圖像預(yù)處理
    • 4.1 灰度二值化
    • 4.2 形態(tài)學處理
    • 4.3 算式提取
    • 4.4 傾斜校正
    • 4.5 字符分割
  • 5 字符識別
    • 5.1 支持向量機原理
    • 5.2 基于SVM的字符識別
    • 5.3 SVM算法實現(xiàn)
  • 6 算法測試
  • 7 系統(tǒng)實現(xiàn)
  • 8 最后

0 簡介

🔥 優(yōu)質(zhì)競賽項目系列,今天要分享的是

基于機器視覺的試卷系統(tǒng) - opencv python 視覺識別

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

🧿 更多資料, 項目分享:

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

1 項目背景

機器視覺的發(fā)展對存在的作業(yè)批改問題, 提供了有效的解決方案。 通過基于機器視覺的作業(yè)批改系統(tǒng)可以對老師的教學工作進行輔助,改變傳統(tǒng)的批改作業(yè)方式,
幫助老師減輕教學壓力和工作負擔, 老師可以快速完成批改過程,及時反饋給學生。 家長同樣需要從繁重的重復(fù)性檢查作業(yè)工作中解脫出來,
將更多的精力放在關(guān)注學生的學習情況和發(fā)現(xiàn)學習問題上。 學生可以通過自我批改作業(yè)中發(fā)現(xiàn)問題、加深理解, 培養(yǎng)自主學習意識, 提高分析問題和解決問題的能力。
因此, 自動批改作業(yè)系統(tǒng)在教育領(lǐng)域的應(yīng)用表現(xiàn)出了無可比擬的教育價值和發(fā)展前景。
在這里插入圖片描述

在這里插入圖片描述

2 項目目的

在教育領(lǐng)域中人工智能應(yīng)用愈加廣泛, 作業(yè)在教學過程中起到重要的作用,當前作業(yè)批改存在著重復(fù)勞動、 效率低下等諸多問題,
這種傳統(tǒng)的批改作業(yè)方式占據(jù)了老師寶貴的時間。 本文設(shè)計一種作業(yè)批改視覺系統(tǒng), 將人工智能應(yīng)用到教育領(lǐng)域中, 改變老師傳統(tǒng)的批改作業(yè)方式,
實現(xiàn)自動批改數(shù)學算式作業(yè)的任務(wù)。

學長設(shè)計了一個系統(tǒng)系統(tǒng),可以協(xié)助老師和家長完成繁重和重復(fù)的作業(yè)批改和檢查工作, 提高工作效率。

3 系統(tǒng)設(shè)計

3.1 目標對象

學長這里以數(shù)學作業(yè)試卷識別為目標。

在這里插入圖片描述

數(shù)學作業(yè)圖像中一列包含多個算式, 字符主要包括印刷體的算式題目和手寫體答案組成, 如上圖 所示為一張數(shù)學算式作業(yè)圖像。
本課題的難點在于如何有效的去除光線等外部干擾因素, 準確的提取到作業(yè)圖像中的單個算式信息;選取有效的字符識別算法,
針對印刷體字符和手寫體字符設(shè)計混合字符分類器,進行有效、 快速的識別; 選取適合的嵌入式設(shè)備, 進行軟件與硬件的系統(tǒng)集成,實現(xiàn)視覺系統(tǒng)的基本功能,
完成穩(wěn)定性的批改過程。

3.2 系統(tǒng)架構(gòu)

通過對視覺系統(tǒng)的研究以及完成作業(yè)批改解決方案的設(shè)計目標, 采取 PC 平臺與嵌入式平臺相結(jié)合的設(shè)計方案。 針對 PC 平臺進行軟件設(shè)計與算法優(yōu)化,
完成系統(tǒng)的功能要求后, 將程序移植到嵌入式系統(tǒng)中, 在嵌入式設(shè)備實現(xiàn)系統(tǒng)的便捷化應(yīng)用。 對于設(shè)計的系統(tǒng)采取多平臺測試分析, 保證系統(tǒng)在 PC
平臺準確高效的運行, 同時保證嵌入式系統(tǒng)中表現(xiàn)出穩(wěn)定的性能。 系統(tǒng)的總體結(jié)構(gòu)框圖如下。

在這里插入圖片描述

首先按照系統(tǒng)功能需求進行分析, 確定要完成的設(shè)計任務(wù)和目標, 并對系統(tǒng)的功能和性能分析做出設(shè)計要求。 其次根據(jù)系統(tǒng)的功能劃分, 選取基于 PC
平臺的軟件設(shè)計方案完成軟件編程, 對系統(tǒng)實現(xiàn)的功能進行驗證, 測試其功能和性能是否符合設(shè)計要求。 選取視覺系統(tǒng)的嵌入式開發(fā)平臺,
進行硬件模塊設(shè)計和開發(fā)環(huán)境及軟件平臺的搭建, 將系統(tǒng)軟硬件集成在一起進行調(diào)試進行, 對系統(tǒng)存在的問題做出改進和優(yōu)化。

最后通過系統(tǒng)測試, 分別對系統(tǒng)的功能和性能進行測試驗證, 是否滿足設(shè)計的要求。 最終構(gòu)建一款多平臺應(yīng)用, 基于機器視覺的自動作業(yè)批改視覺系統(tǒng)。

3.3 軟件設(shè)計方案

該系統(tǒng)基于機器視覺的圖像處理和字符識別技術(shù), 整個系統(tǒng)的核心是軟件設(shè)計部分。 能否對作業(yè)有效和快速的批改,
很大程度上取決于軟件設(shè)計部分圖像處理的效果和字符識別的準確率。 軟件設(shè)計主要完成系統(tǒng)相關(guān)的功能操作,設(shè)計流程可分為圖 中的模塊組成。

在這里插入圖片描述

圖像獲取是將攝像頭等設(shè)備獲取的作業(yè)圖像信息轉(zhuǎn)化為數(shù)字圖像信息; 預(yù)處理是對圖像進行二值化轉(zhuǎn)換, 去除多余噪聲, 進行每一組算式提取,
分割獲得單個清晰字符輪廓的過程; 特征提取是對預(yù)處理后的字符圖像, 進行字符特征提取, 將提取好的特征量輸入到分類器, 為字符識別做準備;
字符識別是系統(tǒng)的核心, 對字符分類器進行設(shè)計, 通過分析訓(xùn)練樣本的特征, 將待預(yù)測的樣本進行分類, 對字符完成準確識別;
結(jié)果輸出是通過公式計算器計算印刷體算式結(jié)果與手寫結(jié)果進行對比, 判斷算式作業(yè)是否作答正確完成反饋的程。

4 圖像預(yù)處理

試卷字符識別過程中, 通過攝像頭采集到的紙張作業(yè)圖像信息由于受到光線產(chǎn)生的噪聲、 書寫的污點等干擾因素, 影響字符圖像的提取效果。
為了得到完整的字符區(qū)域特征, 同時去除無關(guān)信息的干擾, 需要對圖像進行預(yù)處理操作。

在這里插入圖片描述

4.1 灰度二值化

灰度二值化是將圖像先進行灰度處理, 再進行二值化處理。 經(jīng)過灰度二值化處理的圖像降低了像素的運算量, 同時突出圖像中算式的特征。
灰度化是將采取到的彩色圖像進行灰度值轉(zhuǎn)換, 灰度化后的圖像去除了彩色信息, 只保留了算式字符與背景之間的亮度信息, 圖像中每個像素點都是介于 0 至 255
灰度值中的一種。

在這里插入圖片描述

關(guān)鍵代碼

?
#3、將 RGB 轉(zhuǎn)為灰度圖
def rgb2gray(rgb):
return np.dot(rgb[…,:3], [0.299, 0.587, 0.114])

gray = rgb2gray(lena)    
# 也可以用 plt.imshow(gray, cmap = plt.get_cmap('gray'))
plt.imshow(gray, cmap='Greys_r')
plt.axis('off')
plt.show()from scipy import misc
lena_new_sz = misc.imresize(lena, 0.5) # 第二個參數(shù)如果是整數(shù),則為百分比,如果是tuple,則為輸出圖像的尺寸
plt.imshow(lena_new_sz)
plt.axis('off')
plt.show()附上imresize的用法
功能:改變圖像的大小。
用法:
B = imresize(A,m)
B = imresize(A,m,method)
B = imresize(A,[mrows ncols],method)
B = imresize(...,method,n)
B = imresize(...,method,h)imrersize函數(shù)使用由參數(shù)method指定的插值運算來改變圖像的大小。
method的幾種可選值:
'nearest'(默認值)最近鄰插值
'bilinear'雙線性插值
'bicubic'雙三次插值
B = imresize(A,m)表示把圖像A放大m倍
B = imresize(...,method,h)中的h可以是任意一個FIR濾波器(h通常由函數(shù)ftrans2、fwind1、fwind2、或fsamp2等生成的二維FIR濾波器)。

?

4.2 形態(tài)學處理

形態(tài)學處理是通過一定形態(tài)的結(jié)構(gòu)元素, 對圖像產(chǎn)生基于形狀的操作 。它可以在保持圖像基本形狀的基礎(chǔ)上簡化數(shù)據(jù), 去除多余結(jié)構(gòu)。
形態(tài)學運算主要包括開運算和閉運算, 這兩個操作包含了膨脹和腐蝕。

在這里插入圖片描述

算式圖像經(jīng)過形態(tài)學處理后, 實驗效果如上圖所示。 在圖中可以看出左側(cè)的算式圖像經(jīng)過形態(tài)學處理之后, 其斷裂的乘號字符在右側(cè)的算式圖像中形成了連通區(qū)域。
形態(tài)處理后字符整體趨于完整, 邊界變的平滑。

在手寫字符識別的過程中, 由于手寫字符的字跡大小、 粗細程度存在的隨意性很大, 在特征提取的過程中, 相同字符的冗余度導(dǎo)致特征向量差異很大 。

因此對獲取字符圖像要進行適當?shù)募毣幚?#xff0c; 有利于特征提取的準確性。 圖像細化指將二值圖像進行骨架化操作的運算, 細化操作過程就是剝離字符圖像上邊緣輪廓的點,
細化操作要求字符骨架保持原有的筆畫特征, 不能造成筆劃斷開, 同時具有連續(xù)性, 字符圖像應(yīng)盡量保留原始的結(jié)構(gòu)特征。

在這里插入圖片描述

關(guān)鍵代碼

?
import cv2 as cv

img = cv.imread(r"C:\Users\Administrator\Desktop\chinese.png")
img_cvt = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,img_thr = cv.threshold(img_cvt,100,255,cv.THRESH_BINARY)
kernel = cv.getStructuringElement(cv.MORPH_RECT,(30,1)) #由于是1*30的矩陣,字體會被橫向空隙的白色腐蝕掉,而下劃線橫向都是黑色,不會腐蝕
dst = cv.dilate(img_thr,kernel,iterations=1)  #由于是白底黑字,所有進行膨脹操作來去除黑色字體
cv.imshow("img_thr",img_thr)
cv.imshow("dst",dst)
cv.waitKey(0)
cv.destroyAllWindows()

4.3 算式提取

算式提取的主要任務(wù)是從紙張中找到其中一組算式的字符區(qū)域, 并將算式從所在的區(qū)域中提取出來。 經(jīng)過算式提取操作,
可以針對每一組算式進行批改,同時也便于下一步的字符分割, 算式提取準確性對作業(yè)批改效果有直接的影響。二值化處理后的算式圖像中算式的灰度值為 255,
背景的灰度值為 0。

采取基于投影的方法, 進行水平和垂直方向的投影對算式進行提取 , 由于字符圖像和背景圖像對比度較大, 背景幾乎不存在噪音干擾,
因此投影分割可以取得較好的效果。

在這里插入圖片描述

在這里插入圖片描述

對圖像進行列掃描, 得到垂直方向投影圖, 投影后字符間隔的白色像素點的個數(shù)為 0, 在字符區(qū)域處形成波峰。 此時根據(jù)多個連續(xù)的波峰圖像,
記錄開始和結(jié)束的位置, 就可求得算式的左右邊界, 進行分割得到僅包含一組算式區(qū)域的圖像。

在這里插入圖片描述
在這里插入圖片描述

4.4 傾斜校正

在圖像獲取的過程中, 由于攝像頭拍攝角度和作業(yè)圖像有時會產(chǎn)生一個傾斜角度, 此時圖像會發(fā)生垂直傾斜, 如果不對算式圖像進行傾斜校正處理,
可能會無法正確識別出字符。 因此算式提取后要對算式圖像進行傾斜校正, 采用基于 Hough 變換的方法,
其原理為圖像中的直線和曲線經(jīng)過變換映射到參數(shù)空間上的一個點, 通過累加的峰值檢驗圖像中的直線和曲線。 Hough
變換的實質(zhì)是將圖像中一定形狀元素的點進行聚類, 通過解析式將參數(shù)空間對應(yīng)的點聯(lián)系起來。

在這里插入圖片描述

4.5 字符分割

字符分割指是將一組算式中的多個字符圖像根據(jù)字符之間的空隙, 分割成多張只包含單個字符的圖像,
字符分割需要保證對每個字符進行完整的提取。作業(yè)字符圖像是一連串的數(shù)字算式字符, 由于算式中包含除號和等號不連通的字符圖像,
因此不便采取投影法對字符進行分割。

在這里插入圖片描述

5 字符識別

支持向量機是一種新的解決分類問題的機器學習方法, 基于統(tǒng)計學習理論,采用結(jié)構(gòu)風險最小原則。 其原理是在訓(xùn)練樣本集通過少量支持向量,
自動構(gòu)造分類函數(shù)建立一個最大間隔分類平面, 以此解決分類問題。 支持向量機不需要構(gòu)建網(wǎng)絡(luò)結(jié)構(gòu)設(shè)計, 通過非線性變換解決高維空間中樣本識別問題。
支持向量機越來越多的應(yīng)用到了字符識別中, 表現(xiàn)出較好的字符識別效果。

5.1 支持向量機原理

支持向量機(Support Vector Machine, SVM), 是 Vapnik [35] 研究小組在統(tǒng)計學習理論基礎(chǔ)上, 于 1995
年針對分類問題提出的最佳分類準則。 SVM 是一種基于統(tǒng)計學習理論的模式識別方法, 主要應(yīng)用于解決分類和回歸問題。
傳統(tǒng)的統(tǒng)計學理論基于樣本無窮大的統(tǒng)計性質(zhì), SVM 專門針對有限樣本, 算法轉(zhuǎn)化成一個二次型尋優(yōu)問題, 得到的是全局最優(yōu)解。 它具有解的唯一性,
經(jīng)過非線性變化轉(zhuǎn)化到高維特征空間, 其算法與樣本的復(fù)雜度無關(guān), 不依賴輸入空間的維數(shù),得到的最優(yōu)解優(yōu)于傳統(tǒng)的學習方法 。 因此迅速的發(fā)展起來,
在手寫字符識別領(lǐng)域取得了巨大的成功。

對于最優(yōu)間隔平面分類問題, 根據(jù)樣本分布的情況分為線性可分與非線性可分進行討論。 在線性可分的情況下, 其目標就是尋找最優(yōu)間隔超平面, 將樣本準確的分開。
根據(jù)少量支持向量確定平面, 保證樣本數(shù)據(jù)與超平面距離最大,如圖所示。

最優(yōu)分類面示意圖
在這里插入圖片描述

5.2 基于SVM的字符識別

數(shù)學算式作業(yè)中包含印刷體字符和手寫體字符, 將這些字符全部放在一個分類器中會導(dǎo)致分類過于復(fù)雜, 類別過多會使識別速率降低。
因此按照字符的分布位置將分類器分為兩種類型: 印刷體字符分類器和手寫字符分類器。 采取一對一分類的方法對印刷體字符和手寫體字符分別設(shè)計了二分類器,
對于算式中同時包含印刷體和手寫體數(shù)字字符, 選用相應(yīng)的分類器, 會提高識別的準確性和速率。 如圖所示, 根據(jù)字符在算式中的位置, 選用對應(yīng)的分類器。

在這里插入圖片描述

每個分類器只能將一個字符與其他字符分開, 對于手寫字符而言, 其中一類字符樣本的特征向量作為正集(標簽對應(yīng)的值為+1), 其余 9
個樣本的特征向量做負集(標簽對應(yīng)的值為-1)。 按照這種形式依次劃分, 將訓(xùn)練集依次進行訓(xùn)練, 可得到 10 個二分類器, 測試階段將未知樣本輸入到這 10
個分類器進行分類判斷, 決策結(jié)果取相應(yīng)結(jié)果的最大值。 若輸出的值為+1, 則對應(yīng)相應(yīng)類的字符。

網(wǎng)格特征是字符識別中常用的特征提取方法之一, 體現(xiàn)了字符形狀的整體分布。 其中粗網(wǎng)格特征提取的方法是將字符圖像等分成多個網(wǎng)格區(qū)域, 進行特征提取。
首先將歸一化的字符樣本圖像, 其中大小為 128 128, 等分成 16 16 個網(wǎng)格, 如下圖所示。
統(tǒng)計每個網(wǎng)格中黑色像素點占整個網(wǎng)格圖像的有效像素比例, 最后將特征值按照網(wǎng)格排列轉(zhuǎn)換為向量形式。

在這里插入圖片描述

5.3 SVM算法實現(xiàn)

?

import numpy as npimport randomimport matplotlib.pyplot as plt'''類名稱:dataStruct功能:用于存儲一些需要保存或者初始化的數(shù)據(jù)'''class dataStruct:def __init__(self,dataMatIn,labelMatIn,C,toler,eps):self.dataMat = dataMatIn                        #樣本數(shù)據(jù)self.labelMat = labelMatIn                      #樣本標簽self.C = C                                      #參數(shù)Cself.toler = toler                              #容錯率self.eps = eps                                  #乘子更新最小比率self.m = np.shape(dataMatIn)[0]                 #樣本數(shù)self.alphas = np.mat(np.zeros((self.m,1)))      #拉格朗日乘子alphas,shape(m,1),初始化全為0self.b = 0                                      #參數(shù)b,初始化為0self.eCache = np.mat(np.zeros((self.m,2)))      #誤差緩存,'''函數(shù)名稱:loadData函數(shù)功能:讀取文本文件中的數(shù)據(jù),以樣本數(shù)據(jù)和標簽的形式返回輸入?yún)?shù):filename       文本文件名返回參數(shù):dataMat        樣本數(shù)據(jù)labelMat       樣本標簽'''def loadData(filename):dataMat = [];labelMat = []fr = open(filename)for line in fr.readlines():                 #逐行讀取lineArr = line.strip().split('\t')      #濾除行首行尾空格,以\t作為分隔符,對這行進行分解num = np.shape(lineArr)[0]     dataMat.append(list(map(float,lineArr[0:num-1])))#這一行的除最后一個被添加為數(shù)據(jù)labelMat.append(float(lineArr[num-1]))#這一行的最后一個數(shù)據(jù)被添加為標簽dataMat = np.mat(dataMat)labelMat = np.mat(labelMat).Treturn dataMat,labelMat'''函數(shù)名稱:takeStep函數(shù)功能:給定alpha1和alpha2,執(zhí)行alpha1和alpha2的更新,執(zhí)行b的更新輸入?yún)?shù):i1            alpha1的標號i2            alpha2的標號dataMat       樣本數(shù)據(jù)labelMat      樣本標簽返回參數(shù):如果i1==i2 or L==H or eta<=0 or alpha更新前后相差太小,返回0正常執(zhí)行,返回1'''   def takeStep(i1,i2,dS):#如果選擇了兩個相同的乘子,不滿足線性等式約束條件,因此不做更新if(i1 == i2):print("i1 == i2")return 0#從數(shù)據(jù)結(jié)構(gòu)中取得需要用到的數(shù)據(jù)alpha1 = dS.alphas[i1,0]alpha2 = dS.alphas[i2,0]y1 = dS.labelMat[i1]y2 = dS.labelMat[i2]#如果E1以前被計算過,就直接從數(shù)據(jù)結(jié)構(gòu)的cache中讀取它,這樣節(jié)省計算量,#如果沒有歷史記錄,就計算E1if(dS.eCache[i1,0] == 1):E1 = dS.eCache[i1,1]else:u1 = (np.multiply(dS.alphas,dS.labelMat)).T * np.dot(dS.dataMat,dS.dataMat[i1,:].T) + dS.b     #計算SVM的輸出值u1E1 = float(u1 - y1)    #誤差E1#dS.eCache[i1] = [1,E1] #存到cache中#如果E2以前被計算過,就直接從數(shù)據(jù)結(jié)構(gòu)的cache中讀取它,這樣節(jié)省計算量,#如果沒有歷史記錄,就計算E2if(dS.eCache[i2,0] == 1):E2 = dS.eCache[i2,1]else:u2 = (np.multiply(dS.alphas,dS.labelMat)).T * np.dot(dS.dataMat,dS.dataMat[i2,:].T) + dS.b     #計算SVM的輸出值u2E2 = float(u2 - y2)    #誤差E2#dS.eCache[i2] = [1,E2] #存到cache中        s = y1*y2#計算alpha2的上界H和下界Lif(s==1):       #如果y1==y2L = max(0,alpha1+alpha2-dS.C)H = min(dS.C,alpha1+alpha2)elif(s==-1):    #如果y1!=y2L = max(0,alpha2-alpha1)H = min(dS.C,dS.C+alpha2-alpha1)if(L==H):print("L==H")return 0#計算學習率etak11 = np.dot(dS.dataMat[i1,::],dS.dataMat[i1,:].T)k12 = np.dot(dS.dataMat[i1,::],dS.dataMat[i2,:].T)k22 = np.dot(dS.dataMat[i2,::],dS.dataMat[i2,:].T)eta = k11 - 2*k12 +k22if(eta > 0):#正常情況下eta是大于0的,此時計算新的alpha2,新的alpha2標記為a2a2 = alpha2 + y2*(E1-E2)/eta#這個公式的推導(dǎo),曾經(jīng)花費了我很多精力,現(xiàn)在寫出來卻是如此簡潔,數(shù)學真是個好東西#對a2進行上下界裁剪if(a2 < L):a2 = Lelif(a2 > H):a2 = Helse:#非正常情況下,也有可能出現(xiàn)eta《=0的情況print("eta<=0")return 0'''Lobj = Hobj = if(Lobj < Hobj-eps):a2 = Lelif(Lobj > Hobj+eps):a2 = Helse:a2 = alpha2'''#如果更新量太小,就不值浪費算力繼續(xù)算a1和b,不值得對這三者進行更新if(abs(a2-alpha2) < dS.eps*(a2+alpha2+dS.eps)):print("so small update on alpha2!")return 0#計算新的alpha1,標記為a1a1 = alpha1 + s*(alpha2 - a2)#計算b1和b2,并且更新bb1 = -E1 + y1*(alpha1 - a1)*np.dot(dS.dataMat[i1,:],dS.dataMat[i1,:].T) + y2*(alpha2 - a2)*np.dot(dS.dataMat[i1,:],dS.dataMat[i2,:].T) + dS.bb2 = -E2 + y1*(alpha1 - a1)*np.dot(dS.dataMat[i1,:],dS.dataMat[i2,:].T) + y2*(alpha2 - a2)*np.dot(dS.dataMat[i2,:],dS.dataMat[i2,:].T) + dS.bif(a1>0 and a1<dS.C):dS.b = b1elif(a2>0 and a2<dS.C):dS.b = b2else:dS.b = (b1 + b2) / 2#用a1和a2更新alpha1和alpha2dS.alphas[i1] = a1dS.alphas[i2] = a2#由于本次alpha1、alpha2和b的更新,需要重新計算Ecache,注意Ecache只存儲那些非零的alpha對應(yīng)的誤差validAlphasList = np.nonzero(dS.alphas.A)[0]   #所有的非零的alpha標號列表dS.eCache = np.mat(np.zeros((dS.m,2)))#要把Ecache先清空for k in validAlphasList:#遍歷所有的非零alphauk = (np.multiply(dS.alphas,dS.labelMat).T).dot(np.dot(dS.dataMat,dS.dataMat[k,:].T)) + dS.byk = dS.labelMat[k,0]Ek = float(uk-yk)dS.eCache[k] = [1,Ek]print ("updated")return 1'''函數(shù)名稱:examineExample函數(shù)功能:給定alpha2,如果alpha2不滿足KKT條件,則再找一個alpha1,對這兩個乘子進行一次takeStep輸入?yún)?shù):i2            alpha的標號dataMat       樣本數(shù)據(jù)labelMat      樣本標簽返回參數(shù):如果成功對一對乘子alpha1和alpha2執(zhí)行了一次takeStep,返回1;否則,返回0'''def examineExample(i2,dS):#從數(shù)據(jù)結(jié)構(gòu)中取得需要用到的數(shù)據(jù)y2 = dS.labelMat[i2,0]alpha2 = dS.alphas[i2,0]#如果E2以前被計算過,就直接從數(shù)據(jù)結(jié)構(gòu)的cache中讀取它,這樣節(jié)省計算量,#如果沒有歷史記錄,就計算E2if(dS.eCache[i2,0] == 1):E2 = dS.eCache[i2,1]else:u2 = (np.multiply(dS.alphas,dS.labelMat)).T * np.dot(dS.dataMat,dS.dataMat[i2,:].T) + dS.b#計算SVM的輸出值u2E2 = float(u2 - y2)#誤差E2#dS.eCache[i2] = [1,E2]r2 = E2*y2#如果當前的alpha2在一定容忍誤差內(nèi)不滿足KKT條件,則需要對其進行更新if((r2<-dS.toler and alpha2<dS.C) or (r2>dS.toler and alpha2>0)):'''#隨機選擇的方法確定另一個乘子alpha1,多執(zhí)行幾次可可以收斂到很好的結(jié)果,就是效率比較低i1 = random.randint(0, dS.m-1)if(takeStep(i1,i2,dS)):return 1'''#啟發(fā)式的方法確定另一個乘子alpha1nonZeroAlphasList = np.nonzero(dS.alphas.A)[0].tolist()#找到所有的非0的alphanonCAlphasList = np.nonzero((dS.alphas-dS.C).A)[0].tolist()#找到所有的非C的alphanonBoundAlphasList = list(set(nonZeroAlphasList)&set(nonCAlphasList))#所有非邊界(既不=0,也不=C)的alpha#如果非邊界的alpha數(shù)量至少兩個,則在所有的非邊界alpha上找到能夠使\E1-E2\最大的那個E1,對這一對乘子進行更新if(len(nonBoundAlphasList)  > 1):maxE = 0maxEindex = 0for k in nonBoundAlphasList:if(abs(dS.eCache[k,1]-E2)>maxE):maxE = abs(dS.eCache[k,1]-E2)maxEindex = ki1 = maxEindexif(takeStep(i1,i2,dS)):return 1#如果上面找到的那個i1沒能使alpha和b得到有效更新,則從隨機開始處遍歷整個非邊界alpha作為i1,逐個對每一對乘子嘗試進行更新randomStart = random.randint(0,len(nonBoundAlphasList)-1)for i1 in range(randomStart,len(nonBoundAlphasList)):if(i1 == i2):continueif(takeStep(i1,i2,dS)):return 1for i1 in range(0,randomStart):if(i1 == i2):continueif(takeStep(i1,i2,dS)):return 1#如果上面的更新仍然沒有return 1跳出去或者非邊界alpha數(shù)量少于兩個,這種情況只好從隨機開始的位置開始遍歷整個可能的i1,對每一對嘗試更新 randomStart = random.randint(0,dS.m-1)for i1 in range(randomStart,dS.m):if(i1 == i2):continueif(takeStep(i1,i2,dS)):return 1for i1 in range(0,randomStart):if(i1 == i2):continueif(takeStep(i1,i2,dS)):return 1   '''i1 = random.randint(0,dS.m-1)if(takeStep(i1,i2,dS)):return 1 '''#如果實在還更新不了,就回去重新選擇一個alpha2吧,當前的alpha2肯定是有毒    return 0'''函數(shù)名稱:SVM_with_SMO函數(shù)功能:用SMO寫的SVM的入口函數(shù),里面采用了第一個啟發(fā)式確定alpha2,即在全局遍歷和非邊界遍歷之間來回repeat,直到不再有任何更新輸入?yún)?shù):dS            dataStruct類的數(shù)據(jù)返回參數(shù):None'''def SVM_with_SMO(dS):#初始化控制變量,確保第一次要全局遍歷numChanged = 0examineAll = 1#顯然,如果全局遍歷了一次,并且沒有任何更新,此時examineAll和numChanged都會被置零,算法終止while(numChanged > 0 or examineAll):numChanged = 0if(examineAll):for i in range(dS.m):numChanged += examineExample(i,dS)else:for i in range(dS.m):if(dS.alphas[i] == 0 or dS.alphas[i] == dS.C):continuenumChanged += examineExample(i,dS)if(examineAll == 1):examineAll = 0elif(numChanged == 0):examineAll = 1'''函數(shù)名稱:cal_W函數(shù)功能:根據(jù)alpha和y來計算W輸入?yún)?shù):dS         dataStruct類的數(shù)據(jù)返回參數(shù):W          超平名的法向量W            '''def cal_W(dS):W = np.dot(dS.dataMat.T,np.multiply(dS.labelMat,dS.alphas))return W'''函數(shù)名稱:showClassifer函數(shù)功能:畫出原始數(shù)據(jù)點、超平面,并標出支持向量輸入?yún)?shù):dS         dataStruct類的數(shù)據(jù)W          超平名的法向量W    返回參數(shù):None'''    def showClassifer(dS,w):#繪制樣本點dataMat = dS.dataMat.tolist()data_plus = []                                  #正樣本data_minus = []                                 #負樣本for i in range(len(dataMat)):if dS.labelMat[i,0] > 0:data_plus.append(dataMat[i])else:data_minus.append(dataMat[i])data_plus_np = np.array(data_plus)              #轉(zhuǎn)換為numpy矩陣data_minus_np = np.array(data_minus)            #轉(zhuǎn)換為numpy矩陣plt.scatter(np.transpose(data_plus_np)[0], np.transpose(data_plus_np)[1], s=30, alpha=0.7, c='r')   #正樣本散點圖plt.scatter(np.transpose(data_minus_np)[0], np.transpose(data_minus_np)[1], s=30, alpha=0.7,c='g') #負樣本散點圖#繪制直線x1 = max(dataMat)[0]x2 = min(dataMat)[0]a1, a2 = wb = float(dS.b)a1 = float(a1[0])a2 = float(a2[0])y1, y2 = (-b- a1*x1)/a2, (-b - a1*x2)/a2plt.plot([x1, x2], [y1, y2])#找出支持向量點for i, alpha in enumerate(dS.alphas):if abs(alpha) > 0.000000001:x, y = dataMat[i]plt.scatter([x], [y], s=150, c='none', alpha=0.7, linewidth=1.5, edgecolor='red')plt.xlabel("happy 520 day, 2018.06.13")plt.savefig("svm.png")plt.show()if __name__ == '__main__':dataMat,labelMat = loadData("testSet.txt")dS = dataStruct(dataMat, labelMat, 0.6, 0.001, 0.01)#初始化數(shù)據(jù)結(jié)構(gòu) dataMatIn, labelMatIn,C,toler,epsfor i in range(0,1):#只需要執(zhí)行一次,效果就非常不錯SVM_with_SMO(dS)W = cal_W(dS)showClassifer(dS,W.tolist())

?

6 算法測試

輸入圖像

在這里插入圖片描述

預(yù)處理結(jié)果

在這里插入圖片描述

識別結(jié)果

在這里插入圖片描述

7 系統(tǒng)實現(xiàn)

系統(tǒng)主要流程如下

在這里插入圖片描述

對在 PC 軟件平臺通過 MFC 界面中實現(xiàn)各模塊操作, 系統(tǒng)界面如圖所示。

系統(tǒng)界面采用模塊化設(shè)計, 按照界面分布分為圖像顯示模塊、 按鍵功能模塊、 圖像預(yù)處理模塊、 批改結(jié)果輸出四個模塊組成。

主要內(nèi)容包括:

  • 顯示獲取作業(yè)圖像的基本信息;
  • 通過按鍵控制相應(yīng)功能;
  • 顯示預(yù)處理后圖像的效果;輸出識別的字符信息和批改的結(jié)果。

在這里插入圖片描述
圖像顯示模塊, 通過打開攝像頭按鍵, 將攝像頭獲取到的紙張作業(yè)圖像實時信息傳送到計算機中, 獲取的圖像顯示在界面左側(cè)窗口, 界面運行結(jié)果如圖所示。

在這里插入圖片描述

按鍵功能模塊, 通過算式提取按鍵, 對紙張中單個算式整體區(qū)域進行選框提取, 運行結(jié)果如圖所示,
此時算式檢測的結(jié)果在原圖像上用矩形框標記,在界面右側(cè)顯示提取到的算式效果。

在這里插入圖片描述

圖像處理模塊, 通過檢測識別按鍵完成字符分割和識別, 在界面右側(cè)窗口顯示預(yù)處理后的圖像效果。 批改結(jié)果輸出模塊,
在界面下框中顯示字符的識別結(jié)果以及手寫的計算結(jié)果, 同時在右下角窗口顯示解答正誤, 輸出得到的批改信息。 同時對整個過程運行的時間進行統(tǒng)計,
最后保存按鍵將錯誤的批改結(jié)果保存, 便于后期修改。 此時系統(tǒng)運行界面如圖所示。

在這里插入圖片描述

8 最后

🧿 更多資料, 項目分享:

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

http://aloenet.com.cn/news/32076.html

相關(guān)文章:

  • 房地產(chǎn)營銷門戶網(wǎng)站建設(shè)鄭州網(wǎng)站建設(shè)價格
  • 公司網(wǎng)站制作公司排名網(wǎng)絡(luò)營銷推廣策略有哪些
  • 有關(guān)師德建設(shè)的網(wǎng)站網(wǎng)站建設(shè)需要多少錢?
  • 做網(wǎng)站用的hu軟件網(wǎng)站維護費一年多少錢
  • 企業(yè)管理網(wǎng)站開發(fā)論文可以營銷的十大產(chǎn)品
  • 唐山seo快速排名seo全稱是什么
  • 汕頭百度網(wǎng)站建設(shè)成都網(wǎng)絡(luò)營銷品牌代理機構(gòu)
  • 織夢修改網(wǎng)站后備份網(wǎng)絡(luò)軟文
  • 搭建平臺暢通渠道網(wǎng)站seo推廣
  • 自己做網(wǎng)絡(luò)棋牌網(wǎng)站流程泉州seo報價
  • 商城網(wǎng)站建設(shè)招聘百度搜索風云榜總榜
  • 網(wǎng)站app開發(fā)平臺網(wǎng)站搭建谷歌seo
  • wordpress插件裝多了卡seo代碼優(yōu)化包括哪些
  • 巴中網(wǎng)站建設(shè)免費自助建站網(wǎng)站
  • 煙臺seo網(wǎng)站診斷短視頻營銷推廣方式
  • 南寧美容網(wǎng)站建設(shè)seo智能優(yōu)化公司
  • php動態(tài)網(wǎng)站怎么做商旅100網(wǎng)頁版
  • 做地方門戶網(wǎng)站如何做可靠的網(wǎng)站優(yōu)化
  • 怎么自己做網(wǎng)站發(fā)優(yōu)惠券seo搜索引擎優(yōu)化業(yè)務(wù)
  • 佛山電商網(wǎng)站制作seo自學教程
  • 租網(wǎng)站服務(wù)器價格seo霸屏
  • 網(wǎng)頁與網(wǎng)站設(shè)計nbsp的意思合肥做網(wǎng)站哪家好
  • 做家庭影院的有哪些網(wǎng)站防城港網(wǎng)站seo
  • 環(huán)保企業(yè)的網(wǎng)站怎么做指數(shù)基金是什么意思
  • seo外包 靠譜長沙seo咨詢
  • 網(wǎng)站二維碼鏈接怎么做的遼陽網(wǎng)站seo
  • 筑巢網(wǎng)站百度地圖廣告投放
  • 網(wǎng)站建設(shè)需要域名嗎鄭州seo網(wǎng)站有優(yōu)化
  • 外賣網(wǎng)站制作seo 關(guān)鍵詞優(yōu)化
  • 想做一個部門的網(wǎng)站怎么做頭條熱點新聞