基於opencv的圖像數字識別:opencv二維碼識別算法

計算機視覺,我們前期文章分享了很多關於類似這方面的文章,包括人臉識別三部曲,目標檢測,目標追蹤等,本期文章,我們介紹一下如何使用opencv來進行條形碼的檢測,畢竟超市裡面的物品都是有價格條形碼,如何進行opencv條形碼的檢測,便成了無人超市需要重點關注並需要解決的問題計算機視覺—opencv條形碼的檢測,助力無人超市

opencv條形碼的檢測

opencv條形碼的檢測

import numpy as np
import cv2
image = cv2.imread("11.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

首先我們導入需要進行檢測的圖片,並把RGB顏色空間的圖片轉換成灰度照片計算機視覺—opencv條形碼的檢測,助力無人超市

代碼截圖

ddepth =  cv2.CV_32F
gradX = cv2.Sobel(gray, ddepth=ddepth, dx=1, dy=0, ksize=-1)
gradY = cv2.Sobel(gray, ddepth=ddepth, dx=0, dy=1, ksize=-1)
gradient = cv2.subtract(gradX, gradY)
gradient = cv2.convertScaleAbs(gradient)
blurred = cv2.blur(gradient, (9, 9))
(_, thresh) = cv2.threshold(blurred, 225, 255, cv2.THRESH_BINARY)

然後,我們使用cv.sobel算子進行圖片的X Y 軸的邊緣檢測,並使用cv2.subtract(gradX, gradY)計算圖片的梯度,以Sobel算子計算x,y方向上的梯度,之後在x方向上減去y方向上的梯度,通過這個減法,我們留下具有高水平梯度和低垂直梯度的圖像區域,然後cv2.convertScaleAbs返回圖片的unit8格式,參考圖片如下。計算機視覺—opencv條形碼的檢測,助力無人超市

高水平梯度和低垂直梯度的圖像區域

函數原型:
dst = cv2.Sobel(src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]])

函數參數

  1. src – 需要處理的圖像

  2. ddepth – 圖像的深度,-1表示採用的是與原圖像相同的深度。目標圖像的深度必須大於等於原圖像的深度

  3. dx – 對x軸方向求導的階數,一般為0、1、2,其中0表示這個方向上沒有求導

  4. dy – 對y軸方向求導的階數,一般為0、1、2,其中0表示這個方向上沒有求導

  5. dst – 目標圖像

  6. ksize – Sobel算子的大小,必須為1、3、5、7

  7. scale – 縮放導數的比例常數,默認情況下沒有伸縮係數

  8. delta – 可選增量, 將會加到最終的dst中,同樣,默認情況下沒有額外的值加到dst中

  9. borderType – 圖像邊界的模式。這個參數默認值為cv2.BORDER_DEFAUL

在經過處理後,需要用convertScaleAbs()函數將其轉回原來的uint8形式,否則將無法顯示圖像,而只是一副灰色的窗口。

函數原型:dst = cv2.convertScaleAbs(src[, dst[, alpha[, beta]]])   
其中可選參數alpha是伸縮係數,beta是加到結果上的一個值,結果返回uint8類型的圖片
# absX=cv2.convertScaleAbs(x)   # 轉回uint8
# absY=cv2.convertScaleAbs(y)

計算機視覺—opencv條形碼的檢測,助力無人超市

代碼截圖

在圖像的讀取中,會存在一些噪噪聲點,如一些白噪聲,因此我們需要進行去噪操作

opencv4種去噪操作

1. cv2.blur(均值濾波) 
2.cv2.boxfilter(方框濾波)
3. cv2.Guassiannblur(進行高斯濾波)
4. cv2.medianBlur(進行中值濾波)
1.cv2.blur(img, (3, 3))  進行均值濾波
參數說明:img表示輸入的圖片, (3, 3) 表示進行均值濾波的方框大小
2. cv2.boxfilter(img, -1, (3, 3), normalize=True) 表示進行方框濾波,
參數說明當normalize=True時,與均值濾波結果相同, normalize=False,
表示對加和後的結果不進行平均操作,大於255的使用255表示
3. cv2.Guassianblur(img, (3, 3), 1) 表示進行高斯濾波, 
參數說明: 1表示σ, x表示與當前值得距離,計算出的G(x)表示權重值
4. cv2.medianBlur(img, 3) #中值濾波,相當於將9個值進行排序,取中值作為當前值
參數說明:img表示當前的圖片,3表示當前的方框尺寸

計算機視覺—opencv條形碼的檢測,助力無人超市

閾值處理(cv2.threshold) 後圖片

opencv: 閾值處理(cv2.threshold)

cv2.threshold (src, thresh, maxval, type)
src:源圖片,必須是單通道
thresh:閾值,取值範圍0~255
maxval:填充色,取值範圍0~255
type:閾值類型,具體見下表

計算機視覺—opencv條形碼的檢測,助力無人超市

閾值類型

圖片形態學

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 7))
closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

closed = cv2.erode(closed, None, iterations = 4)
closed = cv2.dilate(closed, None, iterations = 4)

計算機視覺—opencv條形碼的檢測,助力無人超市

代碼截圖

通過以上操作,我們已經檢測到了條形碼的大致位置,然後使用內核函數獲取圖片外形的形態學,並分別執行4次形態學腐蝕與膨脹,獲取更精確的圖片形狀位置

kernel = cv2.getStructuringElement這個函數的第一個參數表示內核的形狀,
有三種形狀可以選擇
矩形:MORPH_RECT;
交叉形:MORPH_CROSS;
橢圓形:MORPH_ELLIPSE;

第二和第三個參數分別是內核的尺寸以及錨點的位置。一般在調用erode以及dilate函數之前,先定義一個Mat類型的變量來獲得

getStructuringElement函數的返回值: 對於錨點的位置,有默認值Point(-1,-1),表示錨點位於中心點。element形狀唯一依賴錨點位置,其他情況下,錨點只是影響了形態學運算結果的偏移。

cv2.morphologyEx(src, op, kernel) 進行各類形態學的變化
參數說明:
src傳入的圖片
op進行變化的方式
kernel表示方框的大小
2.op =  cv2.MORPH_OPEN 進行開運算,指的是先進行腐蝕操作,再進行膨脹操作
3. op = cv2.MORPH_CLOSE 進行閉運算, 指的是先進行膨脹操作,再進行腐蝕操作
開運算:表示的是先進行腐蝕,再進行膨脹操作
閉運算:表示先進行膨脹操作,再進行腐蝕操作

計算機視覺—opencv條形碼的檢測,助力無人超市

cv2.morphologyEx後圖片

形態學圖片轉換完成後,進行圖片的腐蝕與膨脹,這裡主要是獲取更精確的外形。

腐蝕與膨脹屬於形態學操作,所謂的形態學,就是改變物體的形狀,形象理解一些:腐蝕=變瘦 膨脹=變胖,主要是採用 cv2.erode()cv2.dilate(),需要注意一點的是,腐蝕和膨脹主要針對二值化圖像的白色部分計算機視覺—opencv條形碼的檢測,助力無人超市

腐蝕與膨脹後圖片

圖片外輪廓的繪製

cnts = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL,
	cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0]
c = sorted(cnts, key = cv2.contourArea, reverse = True)[0]
rect = cv2.minAreaRect(c)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(image, [box], -1, (0, 255, 0), 3)
cv2.imshow("Image", image)
cv2.waitKey(0)

計算機視覺—opencv條形碼的檢測,助力無人超市

代碼截圖

我們通過以上的步驟,已經成功鎖定圖片條形碼的位置,然後使用cv2.findContours函數找到圖片的外形,並畫出圖片的外形。


(_, cnts, _) = cv2.findContours(
    參數一: 二值化圖像
    closed.copy(),
    參數二:輪廓類型
    # cv2.RETR_EXTERNAL,             #表示只檢測外輪廓
    # cv2.RETR_CCOMP,                #建立兩個等級的輪廓,上一層是邊界
    # cv2.RETR_LIST,                 #檢測的輪廓不建立等級關係
    # cv2.RETR_TREE,                 #建立一個等級樹結構的輪廓
    # cv2.CHAIN_APPROX_NONE,         #存儲所有的輪廓點,相鄰的兩個點的像素位置差不超過1
    參數三:處理近似方法
    # cv2.CHAIN_APPROX_SIMPLE,         #例如一個矩形輪廓只需4個點來保存輪廓信息
    # cv2.CHAIN_APPROX_TC89_L1,
    # cv2.CHAIN_APPROX_TC89_KCOS
    )

然後對找到的所有輪廓點進行重新排序

sorted(iterable, key=None, reverse=False)  
參數說明:
iterable -- 可迭代對象。
key -- 主要是用來進行比較的元素,只有一個參數,具體的函數的參數就是取自於可迭代對象中,
指定可迭代對象中的一個元素來進行排序。
reverse -- 排序規則,reverse = True 降序 , reverse = False 升序(默認)。
返回值
返回重新排序的列表。

排序完成後的list傳遞給cv2.minAreaRect(Points)函數

其中points是點集,數據類型為ndarray,array((x1,y1),(x2,y2),….,(xn,yn))

而minAreaRect就是求出在上述點集下的最小面積矩形

rect[0]返回矩形的中心,(x,y),實際上為y行x列的像素點

利用cv2.boxPoints(rect)可以返回矩形四個點的值,
其中cv2.boxPoints(rect)[0]為point[0],
cv2.boxPoints(rect)[1]為point[1].
 rect[1]返回矩形的長和寬
rect[2]返回矩形的旋轉角度

有了box的外形4個圖形點,便可以使用cv2.drawContours函數把4個點連接起來,形成一個矩形輪廓,最後顯示圖片計算機視覺—opencv條形碼的檢測,助力無人超市

opencv條形碼的檢測

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/223281.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
投稿專員的頭像投稿專員
上一篇 2024-12-09 14:15
下一篇 2024-12-09 14:15

相關推薦

發表回復

登錄後才能評論