於就想找找python+opencv關於這方面的code
第一步當然是先找出barcode囉
參考的是這一篇文章
其實他說明的已經很清楚了,但cv2的很多參數我仍是不清楚
且和之前學的影像處理連不太起來,還是memo一下的好
image = cv2.imread(args["image"])
讀圖進來,這沒問題
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
轉灰階,查opencv的說明為「Converts an image from one color space to another.」
因此cvtColor是用來轉換不同color space的函式
在python中長這樣
Python: cv2.cvtColor(src, code[, dst[, dstCn]]) → dst
Python: cv.CvtColor(src, dst, code) → None -->若是有給dst就會回None
最原本長這樣
C: void cvCvtColor(const CvArr* src, CvArr* dst, int code)
--> code – color space conversion code (see the description below)
常用的有:「CV_RGB2GRAY」、「CV_BGR2HSV」
gradX = cv2.Sobel(gray, ddepth = cv2.cv.CV_32F, dx = 1, dy = 0, ksize = -1)
gradY = cv2.Sobel(gray, ddepth = cv2.cv.CV_32F, dx = 0, dy = 1, ksize = -1)
接著對圖做sobel運算,來找出x向和y向邊界 --> 這邊找了一下之前還有學到Prewitt operator,但在cv2中好像沒看到…
而以前學的sobel長這樣,不知道cv2中的是不是一樣的 (一篇論文人人實作不同丫,還是抱著懷疑的好)
由cv2.Sobel的說明來看,所謂的「kernel of size 3*3」應該是指之前學過的3x3的mask
預設的ksize=3
ddepth = cv2.cv.CV_32F --> 32=2^5,這邊的CV_32F即為5
dx = 1 --> x向的差值為1
且說明中也有提到「xorder = 0, yorder = 1, ksize = 3」、「xorder = 1, yorder = 0, ksize = 3」即為之前學的(上圖)中的y向和x向的maskgradient = cv2.subtract(gradX, gradY)
把gradX和gradY的每一個元素相減
gradient = cv2.convertScaleAbs(gradient)
取abs,把負的變正數
blurred = cv2.blur(gradient, (9, 9))
說明文件提到「Blurs an image using the normalized box filter.」
因此是用9x9的matrix,其中每個元素都是1,讓影像模糊
(_, thresh) = cv2.threshold(blurred, 225, 255, cv2.THRESH_BINARY)
用threshold處理影像,225為threshold value,255為達到的輸出值,
而cv2.THRESH_BINARY為thresholdType,看說明文件會更清楚
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 7))
取得型態學中膨脹與腐蝕的運算mask
這個function得到的如下:
array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]], dtype=uint8)
換個shape
>>> cv2.getStructuringElement(cv2.MORPH_CROSS, (21, 7))
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
對剛剛thresh的結果進行 MORPH_CLOSE操作
一般基本操作為侵蝕、膨脹(erode、dilate) --> 進一步Close操作為先dilate再erode,這樣可以把斷掉的東西連起來,因此稱為close,反之為open
可參考這邊的說明
closed = cv2.erode(closed, None, iterations = 4)
closed = cv2.dilate(closed, None, iterations = 4)
先連續進行4次erode,再連續4次dilate運算
[未完…寫累了…晚點再寫]
沒有留言:
張貼留言