頭圖 | 下載于視覺中國
校園卡目標檢測
1.1 環境要求本次環境使用的是.6.5+平臺,主要用的庫是圖像處理庫,包括用來目標檢測和圖像處理等操作。1.2 數據集處理其中數據集由自己利用手機攝像頭拍照獲得,因為要使用的分類算的是SVM算法,故需要定義兩種類別,一種是需要尋找的目標圖片,即校園卡圖片存儲在文件夾下,如圖1可見;第二種類別是干擾的其它圖片,存放在文件夾下,如圖2所示。
圖文件夾數據集
圖2 文件夾數據集通過os模塊加載本地文件夾中的圖片,分別以,和變量用來存儲正樣本數據、負樣本數據和測試集數據。具體代碼如下:
1pwd?=?os.getcwd()
2logger.info('Current?path?is:{}'.format(pwd))
3#?提取正樣本
4pos_dir?=?os.path.join(pwd,?'Positive')
5if?os.path.exists(pos_dir):
6????logger.info('Positive?data?path?is:{}'.format(pos_dir))
7????pos?=?os.listdir(pos_dir)
8????logger.info('Positive?samples?number:{}'.format(len(pos)))
9#?提取負樣本
10neg_dir?=?os.path.join(pwd,?'Negative')
11if?os.path.exists(neg_dir):
12????logger.info('Negative?data?path?is:{}'.format(neg_dir))
13????neg?=?os.listdir(neg_dir)
14????logger.info('Negative?samples?number:{}'.format(len(neg)))
15#?提取測試集
16test_dir?=?os.path.join(pwd,?'TestData')
17if?os.path.exists(test_dir):
18????logger.info('Test?data?path?is:{}'.format(test_dir))
19????test?=?os.listdir(test_dir)
20????logger.info('Test?samples?number:{}'.format(len(test)))
其中訓練的數據需要將訓練集和測試室合在一起,同時定義標簽數組與之對應,即屬于正樣本時標簽就是為1;屬于負樣本數據時標簽就是變為-1。具體代碼如下:
1pwd?=?os.getcwd()
2pos_dir?=?os.path.join(pwd,?'Positive')
3neg_dir?=?os.path.join(pwd,?'Negative')
4samples?=?[]
5labels?=?[]
6for?f?in?pos:
7????file_path?=?os.path.join(pos_dir,?f)
8????if?os.path.exists(file_path):
9????????samples.append(file_path)
10????????labels.append(1.)
11for?f?in?neg:
12????file_path?=?os.path.join(neg_dir,?f)
13????if?os.path.exists(file_path):
14????????samples.append(file_path)
15????????labels.append(-1.)
16#?labels?要轉換成numpy數組,類型為np.int32
17labels?=?np.int32(labels)
18labels_len?=?len(pos)?+?len(neg)
19labels?=?np.resize(labels,?(labels_len,?1))
1.3 特征提取
其中特征的提取主要通過從訓練數據集中提取HOG特征作為訓練特征,其中函數一共有4個構造函數,其中分別是參數(64,128), (16,16), (8,8), (8,8), nbins(9)。這些都是的成員變量,括號里的數值是它們的默認值表格文字識別系統,它們反應了HOG描述子的參數。其中指的是窗口大小 ,指的是塊大小 ,指的是胞元大小 ,nbins指的是梯度方向數表格文字識別系統,nBins表示在一個胞元(cell)中統計梯度的方向數目,例如nBins=9時,在一個胞元內統計9個方向的梯度直方圖,每個方向為180/9=20度。具體代碼如下:
1train?=?[]
2logger.info('Extracting?HOG?Descriptors...')
3num?=?0.
4total?=?len(samples)
5for?f?in?samples:
6????num?+=?1.
7????logger.info('Processing?{}?{:2.1f}%'.format(f,?num/total*100))
8????hog?=?cv2.HOGDescriptor((64,128),?(16,16),?(8,8),?(8,8),?9)
9????#?hog?=?cv2.HOGDescriptor()
10????img?=?cv2.imread(f,?-1)
11????img?=?cv2.resize(img,?(64,128))
12????descriptors?=?hog.compute(img)
13????logger.info('hog?feature?descriptor?size:?{}'.format(descriptors.shape))????#?(3780,?1)
14????train.append(descriptors)
15train?=?np.float32(train)
16train?=?np.resize(train,?(total,?3780))
1.4 SVM分類
通過使用SVM函數cv2.ml.()建立SVM分類器,其中所使用的核函數為cv2.ml.線性核函數。并在訓練完成后保存成svm模型。
圖3不同SVM對比效果代碼如下:
1logger.info('Configuring?SVM?classifier.')
2svm?=?cv2.ml.SVM_create()
3svm.setCoef0(0.0)
4svm.setDegree(3)
5criteria?=?(cv2.TERM_CRITERIA_MAX_ITER?+?cv2.TERM_CRITERIA_EPS,?1000,?1e-3)
6svm.setTermCriteria(criteria)
7svm.setGamma(0)
8svm.setKernel(cv2.ml.SVM_LINEAR)
9svm.setNu(0.5)
10svm.setP(0.1)??#?for?EPSILON_SVR,?epsilon?in?loss?function?
11svm.setC(0.01)??#?From?paper,?soft?classifier
12svm.setType(cv2.ml.SVM_EPS_SVR)
13logger.info('Starting?training?svm.')
14svm.train(train,?cv2.ml.ROW_SAMPLE,?labels)
15logger.info('Training?done.')
16pwd?=?os.getcwd()
17model_path?=?os.path.join(pwd,?'svm.xml')
18svm.save(model_path)
19logger.info('Trained?SVM?classifier?is?saved?as:?{}'.format(model_path))
20
1.5 模型測試
通過IP攝像頭讀入數據,然后利用模型檢測輸入的視頻流。
1hog?=?cv2.HOGDescriptor()
2hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
3pwd?=?os.getcwd()
4test_dir?=?os.path.join(pwd,?'TestData')
5cap=cv2.VideoCapture("http://admin:admin@192.168.137.124:8081/")
6while?True:
7????_,?frame?=?cap.read()
8????rects,?_?=?hog.detectMultiScale(frame,?winStride=(4,?4),?padding=(8,?8),?scale=1.05)
9????for?(x,?y,?w,?h)?in?rects:
10????????cv2.rectangle(frame,?(x,?y),?(x?+?w,?y?+?h),?(0,?0,?255),?2)
11????cv2.imshow('Detect',?frame)
12????c?=?cv2.waitKey(1)?&?0xff
13????if?c?==?27:
14????????break
最終達成的測試效果如下圖所見:
圖4模型測試效果圖
校園卡信息提取
在得到視頻檢測到校園卡的位置之后,對校園卡進行圖像處理操作。操作流程如下可見:(1)讀入圖片,并設定成一定尺寸
1img=cv2.imread("TestData/0.jpg")
2img=cv2.resize(img,(400,300))
(2)初始化幾個結構化內核,構造了兩個這樣的內核 - 一個矩形和一個正方形。我們將使用矩形的一個用于Top-hat形態運算符,將方形一個用于關閉操作。
1rectKernel=cv2.getStructuringElement(cv2.MORPH_RECT,(12,12))
2sqKernel=cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
(3)將圖片就行灰度化操作,然后執行Top-hat形態操作,將結果存儲為,Top-hat操作顯示了深色背景下的亮區。
1gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
2#執行Top-hat形態操作,將結果存儲為?tophat,Top-hat操作顯示了深色背景下的亮區
3tophat=cv2.morphologyEx(gray,cv2.MORPH_TOPHAT,rectKernel)
(4)計算沿x方向的漸變在計算gradX 數組中每個元素的絕對值之后 ,我們采取一些步驟將值縮放到范圍[0-255](因為圖像當前是浮點數據類型)。要做到這一點,我們計算 和 的gradX,然后由我們的縮放方程上顯示(即,最小/最大歸一化)。最后一步是將gradX轉換為 uint8,其范圍為[0-255]。然后執行gradX 圖像的Otsu和二進制閾值,然后是另一個關閉操作,對數字分段
1gradx=cv2.Sobel(tophat,ddepth=cv2.CV_32F,dx=1,dy=0,ksize=-1)
2gradx=np.absolute(gradx)
3(minval,maxval)=(np.min(gradx),np.max(gradx))
4gradx=(255*((gradx-minval)/(maxval-minval)))
5gradx=gradx.astype("uint8")
6#執行gradX?圖像的Otsu和二進制閾值,然后是另一個關閉操作,對數字分段
7gradx=cv2.morphologyEx(gradx,cv2.MORPH_CLOSE,rectKernel)
圖5 執行關閉操作圖片效果
(5)圖像閾值處理,二值化操作
1thresh=cv2.threshold(gradx,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)[1]
圖6 執行二值化操作圖片效果(6)執行膨脹操作,擴大噪音或者連接物體
1kernel=np.ones((7,7),np.uint8)
2dilate=cv2.dilate(thresh,kernel,iterations=1)
圖7 執行膨脹操作圖片效果(7)找到輪廓并初始化數字分組位置列表。然后循環遍歷輪廓,同時根據每個的寬高比進行過濾,允許我們從信用卡的其他不相關區域修剪數字組位置,其中我們需要提取的區域長寬比是大于1,去除雜項。然后從左到右對分組進行排序,并初始化信用卡數字列表。接著利用for循環依次顯示和識別。其中文字識別使用的是百度接口。
1#找到輪廓并初始化數字分組位置列表
2cnts=cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
3cnts=imutils.grab_contours(cnts)
4locs?=?[]
5#循環遍歷輪廓,同時根據每個的寬高比進行過濾,允許我們從信用卡的其他不相關區域修剪數字組位置
6for?(i,?c)?in?enumerate(cnts):
7????(x,?y,?w,?h)?=?cv2.boundingRect(c)
8????#我們需要提取的區域長寬比是大于1,去除雜項
9????ar?=?w/h
10????if?ar?>?1:
11????????locs.append((x,?y,?w,?h))
12#從左到右對分組進行排序,并初始化信用卡數字列表
13locs?=?sorted(locs,?key=lambda?x:x[0])
14print(locs)
15for?i?in?locs:
16????print(i)
17????image=gray[i[1]:i[1]+i[3],i[0]:i[0]+i[2]]
18????cv2.imwrite("temp.jpg",image)
19????APP_ID?=?'23109663'??#?剛才獲取的?ID,下同
20????API_KEY?=?'4rWRc7ensuq0Bf8NGs8cGuaz'
21????SECRECT_KEY?=?'bWWS8ugAs2wGGx78yTUiMccpQpWt0UlY'
22????client?=?AipOcr(APP_ID,?API_KEY,?SECRECT_KEY)
23????tt?=?open("temp.jpg",?'rb')
24????img?=?tt.read()
25????message?=?client.basicGeneral(img)??#通用文字識別
26????print(message)
27????cv2.imshow(str(i)+"2",image)
28????cv2.waitKey(1)
29cv2.waitKey(0)
圖8 識別提取效果圖
總結與討論
此次校園卡目標檢測和圖像處理信息提取的功能設計,使用的是傳統的模式識別方法進行圖像識別,其中涉及到的知識主要是hog特征+SVM分類,以及圖片處理的一些常規操作和百度API文字識別的調用。作者簡介:李秋鍵,CSDN博客專家,CSDN達人課作者。碩士在讀于中國礦業大學,開發有競賽獲獎等。
更多精彩推薦 ?一口一個,超靈活的Python迷你項目
?疫情期間網絡攻擊花樣翻新,全年 81748 起安全事件背后暗藏規律
?用數據分析《你好,李煥英》“斐媽”爆紅的真相
?最低售價17999元,華為發布新一代折疊屏手機Mate X2
點分享 點收藏 點點贊 點在看