0 簡(jiǎn)介
?? 優(yōu)質(zhì)競(jìng)賽項(xiàng)目系列,今天要分享的是
基于機(jī)器學(xué)習(xí)的二維碼識(shí)別檢測(cè) - opencv 二維碼 識(shí)別檢測(cè) 機(jī)器視覺(jué)
該項(xiàng)目較為新穎,適合作為競(jìng)賽課題方向,學(xué)長(zhǎng)非常推薦!
?? 更多資料, 項(xiàng)目分享:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-800659.html
https://gitee.com/dancheng-senior/postgraduate文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-800659.html
1 二維碼檢測(cè)
物體檢測(cè)就是對(duì)數(shù)字圖像中一類(lèi)特定的物體的位置進(jìn)行自動(dòng)檢測(cè)。基本的檢測(cè)框架有兩種:
一種是以滑動(dòng)窗口為單位對(duì)圖像進(jìn)行掃描,對(duì)掃描所得的每個(gè)子圖像提取特征,并用學(xué)習(xí)到的分類(lèi)器來(lái)分類(lèi)該特征并且判斷該子圖像是否為所檢測(cè)的特定物體。對(duì)象檢測(cè)的一個(gè)問(wèn)題是,對(duì)象在圖片中的位置和尺度是未知的。算法被要求能夠檢測(cè)各種不同位置、不同大小的對(duì)象,這樣的特性被稱(chēng)為位置無(wú)關(guān)性和尺度無(wú)關(guān)性。為了達(dá)到這樣的特性,常見(jiàn)的方法是使用多尺度框架,即:通過(guò)縮放原始圖像,產(chǎn)生一組大小不同的圖像序列,然后在序列的每幅圖像中都使用固定尺寸
W×H
的滑動(dòng)窗口,檢測(cè)算法將判斷每次滑動(dòng)窗口所截取的圖像子窗口是否存在目標(biāo)對(duì)象?;瑒?dòng)窗口解決了位置無(wú)關(guān)性;而圖像序列中存在至少一幅圖像,其包含的目標(biāo)對(duì)象的尺度符合滑動(dòng)窗口的尺度,這樣一個(gè)圖像金字塔序列解決了尺度無(wú)關(guān)性。
另一種則是在整幅圖像上首先提取興趣點(diǎn),然后僅對(duì)提取出來(lái)的興趣點(diǎn)分類(lèi)。
因此學(xué)長(zhǎng)把物體檢測(cè)方法分為基于滑動(dòng)窗口的物體檢測(cè)和基于興趣點(diǎn)的物體檢測(cè)兩類(lèi)。
無(wú)論是哪種做法,整個(gè)過(guò)程都可以分為特征提取和特征分類(lèi)這兩個(gè)主要階段。也就是說(shuō),物體檢測(cè)的主要問(wèn)題是使用什么樣的特征和使用什么樣的分類(lèi)器。
物體檢測(cè)的難點(diǎn)在于如何用有限的訓(xùn)練集來(lái)學(xué)習(xí)到魯棒的、可以適用到各種情況下的分類(lèi)器。這里所說(shuō)的各種情況包括有:圖像中物體的大小不同;光照條件的差異所引起的圖像明暗的不同;物體在圖像中可能存在的旋轉(zhuǎn)和透視情況;同類(lèi)物體間自身存在的差異。
這里學(xué)長(zhǎng)以定位二維碼 / 條形碼為例,簡(jiǎn)述基于機(jī)器學(xué)習(xí)實(shí)現(xiàn)物體檢測(cè)的大致算法流程。
2 算法實(shí)現(xiàn)流程
算法流程圖如下圖所示:
我們先把輸入圖像分成 25×25
的圖像子塊。把圖像子塊作為特征提取和特征分類(lèi)這兩個(gè)模塊的基本處理對(duì)象,即對(duì)圖像子塊進(jìn)行紋理特征提取,特征分類(lèi)時(shí)判定當(dāng)前處理的圖像子塊是否屬于二維條形碼的一部分
在特征提取模塊中,我們使用紋理特征提取算法從原始輸入圖像中提取出多分辨率直方
在特征分類(lèi)時(shí),我們希望保留所有屬于二維條形碼的圖像子塊,同時(shí)去除所有屬于背景的圖像子塊。在該模塊中,我們使用了自適應(yīng) Spatialboost 算法。
下圖為經(jīng)過(guò)這步處理后的理想輸出結(jié)果,圖中被標(biāo)記的小方塊表示他們屬于二維條形碼的一部分。
3 特征提取
圖像的紋理特征可以描述物體特有的屬性,用以區(qū)別其他物體。紋理特征總體可分為空域和頻域兩大類(lèi)。在本文算法中,我們采用的紋理特征均屬于空域的紋理特征,也是局部特征,它們分別是多分辨率直方圖特征、局部二值模式特征和邊緣方向直方圖特征。
多分辨率直方圖特征具備旋轉(zhuǎn)無(wú)關(guān)的特點(diǎn)。這種紋理特征保留了灰度直方圖特征計(jì)算簡(jiǎn)單和保存方便的特點(diǎn)。同時(shí)它又可以描述紋理的局部信息,彌補(bǔ)了傳統(tǒng)的灰度直方圖特征的缺點(diǎn)。
局部二值模式特征是一種計(jì)算復(fù)雜度較低的局部特征,它具有明暗無(wú)關(guān)和旋轉(zhuǎn)無(wú)關(guān)的特點(diǎn)。
邊緣方向直方圖特征與全局的光照變化是無(wú)關(guān)的,它可以提取出二維條形碼紋理的幾何特點(diǎn)。
4 特征分類(lèi)
學(xué)長(zhǎng)開(kāi)發(fā)的算法所使用的分類(lèi)器為自適應(yīng) Spatialboost 算法,這是對(duì) Spatialboost
算法的一個(gè)改進(jìn)。使用這個(gè)分類(lèi)器是由二維條形碼的特點(diǎn)以及我們算法框架的特點(diǎn)所決定的。由于我們把原始輸入圖像分為若干大小固定的圖像子塊,屬于二維條形碼的圖像子塊在空間上有很強(qiáng)的關(guān)聯(lián)性,或者說(shuō)這些屬于二維條形碼的圖像子塊都是緊密相鄰的。同時(shí)由于圖像子塊的尺寸不大,它所包含的信息量相對(duì)較少,有的時(shí)候就很難把屬于二維條形碼的圖像子塊和屬于背景的圖像子塊區(qū)分開(kāi)(它們?cè)谔卣骺臻g上可能重疊)。如果我們可以利用子塊在空間上的聯(lián)系,把空間信息加入到分類(lèi)器中,將有利于提高分類(lèi)器的準(zhǔn)確率。
適應(yīng) Spatialboost
算法可以同時(shí)利用紋理特征以及子塊在空間上的聯(lián)系,在訓(xùn)練過(guò)程中,將紋理特征和空間信息自適應(yīng)的結(jié)合起來(lái)訓(xùn)練分類(lèi)器。這樣,當(dāng)前處理的子塊的分類(lèi)結(jié)果不僅依賴(lài)于它自己的紋理特征,還和它周?chē)訅K的分類(lèi)結(jié)果密切相關(guān)。當(dāng)屬于背景的圖像子塊的紋理特征很接近于屬于二維條形碼的圖像子塊時(shí),我們還是可以依靠和它相鄰的背景子塊來(lái)對(duì)它做出正確的分類(lèi)。
5 后處理
經(jīng)過(guò)特征提取和特征分類(lèi)兩個(gè)模塊后,我們得到了對(duì)圖像子塊的分類(lèi)結(jié)果,但最后我們期望得到的是對(duì)二維條形碼的包圍盒。在我們的設(shè)置下,自適應(yīng)Spatialboost
分類(lèi)器對(duì)背景子塊的分類(lèi)相當(dāng)嚴(yán)格,此時(shí)對(duì)屬于二維條形碼的圖像子塊會(huì)有部分漏檢發(fā)生,
因此在后處理模塊中,我們先使用一種自適應(yīng)聚類(lèi)算法,對(duì)分類(lèi)后的結(jié)果進(jìn)一步改進(jìn),來(lái)精確的覆蓋整個(gè)二維條形碼。特征分類(lèi)后定位到的子塊的大小為
25×25,我們把這些子塊再劃分為 10×10 的小方塊。接著以得到的 10×10 的子塊為種子,用子塊灰度值的方差為衡量標(biāo)準(zhǔn)往外聚類(lèi),聚類(lèi)時(shí)的閾值設(shè)定為:
其中 M 是聚類(lèi)開(kāi)始時(shí)作為種子的子塊的個(gè)數(shù),k 為調(diào)整系數(shù),在本文算法中 k設(shè)置為 0.5,Var 和 Mean
分別表示子塊灰度值的均值和方差。由公式(3-1)可知,每幅圖像的聚類(lèi)閾值是自適應(yīng)的計(jì)算得來(lái)的。聚類(lèi)開(kāi)始時(shí)首先從種子子塊出發(fā),計(jì)算它們周?chē)淖訅K的灰度值方差,如果大于聚類(lèi)閾值就把它標(biāo)識(shí)為屬于二維條形碼,重復(fù)這個(gè)過(guò)程直到周?chē)贈(zèng)]有子塊符合聚類(lèi)條件。圖
3-5
是聚類(lèi)算法的部分結(jié)果,第一行的圖像是特征分類(lèi)后的結(jié)果,準(zhǔn)確的定位到了一部分二維條形碼,但是沒(méi)有完全的覆蓋整個(gè)二維條形碼,不利于我們輸出最后的定位包圍盒。第二行為聚類(lèi)后的結(jié)果,可以看到小塊幾乎完全覆蓋了整個(gè)二維條形碼,此時(shí)再把這些小塊合并為一個(gè)平行四邊形就很方便了。
聚類(lèi)后定位出來(lái)的小塊基本上覆蓋了整個(gè)二維條形碼,最后我們只需要把定位出的小包圍盒合并為大包圍盒,并輸出最后的定位結(jié)果。整個(gè)后處理流程見(jiàn)圖
6 代碼實(shí)現(xiàn)
這里演示條形碼的檢測(cè)效果:
關(guān)鍵部分代碼實(shí)現(xiàn):
?
# import the necessary packages
import numpy as np
import argparse
import cv2
# construct the argument parse and parse the arguments
# ap = argparse.ArgumentParser()
# ap.add_argument("-i", "--image", required = True, help = "path to the image file")
# args = vars(ap.parse_args())
# load the image and convert it to grayscale
image = cv2.imread('./images/2.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# compute the Scharr gradient magnitude representation of the images
# in both the x and y direction
gradX = cv2.Sobel(gray, ddepth = cv2.CV_32F, dx = 1, dy = 0, ksize = -1)
gradY = cv2.Sobel(gray, ddepth = cv2.CV_32F, dx = 0, dy = 1, ksize = -1)
# subtract the y-gradient from the x-gradient
gradient = cv2.subtract(gradX, gradY)
gradient = cv2.convertScaleAbs(gradient)
# blur and threshold the image
blurred = cv2.blur(gradient, (9, 9))
(_, thresh) = cv2.threshold(blurred, 225, 255, cv2.THRESH_BINARY)
# construct a closing kernel and apply it to the thresholded image
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 7))
closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
# perform a series of erosions and dilations
closed = cv2.erode(closed, None, iterations = 4)
closed = cv2.dilate(closed, None, iterations = 4)
# find the contours in the thresholded image, then sort the contours
# by their area, keeping only the largest one
(cnts, _) = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
c = sorted(cnts, key = cv2.contourArea, reverse = True)[0]
# compute the rotated bounding box of the largest contour
rect = cv2.minAreaRect(c)
box = np.int0(cv2.boxPoints(rect))
?
5 最后
?? 更多資料, 項(xiàng)目分享:
https://gitee.com/dancheng-senior/postgraduate
到了這里,關(guān)于互聯(lián)網(wǎng)加競(jìng)賽 基于機(jī)器視覺(jué)的二維碼識(shí)別檢測(cè) - opencv 二維碼 識(shí)別檢測(cè) 機(jī)器視覺(jué)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!