2014-07-22 24 views
4

我的目標是從此二進制圖像中檢測一張白皮書,然後裁剪此白皮書併爲此白皮書創建一個新的子集二進制圖像。 enter image description herePython OpenCV從二進制圖像中檢測白色物體並對其進行裁剪

現在我的OpenCV Python代碼可以找到這個白皮書。第一步,我創建了一張用於查找此白皮書的蒙版: enter image description here

正如你們所看到的,小白噪聲和小碎片已被刪除。然後問題變成如何從這個二進制圖像裁剪這個白皮書對象來創建一個新的子集二進制圖像?

我當前的代碼是:

import cv2 
import numpy as np 

QR = cv2.imread('IMG_0352.TIF', 0) 
mask = np.zeros(QR.shape,np.uint8) 

contours, hierarchy = cv2.findContours(QR,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) 

for cnt in contours: 
    if cv2.contourArea(cnt)>1000000: 
     cv2.drawContours(mask,[cnt],0,255,-1) 

尋找的CNT VAR,有四個要素,但確是無稽之談給我。 我使用的代碼,以適應框:

x,y,w,h = cv2.boundingRect(cnt) 
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2) 

盒信息看起來不正確。

感謝您的任何建議。

跟進: 我已經想出了這個問題,這很容易。代碼如下:

import cv2 
import numpy as np 


QR_orig = cv2.imread('CamR_IMG_0352.TIF', 0) 
QR = cv2.imread('IMG_0352.TIF', 0) # read the QR code binary image as grayscale image to make sure only one layer 
mask = np.zeros(QR.shape,np.uint8) # mask image the final image without small pieces 

# using findContours func to find the none-zero pieces 
contours, hierarchy = cv2.findContours(QR,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) 

# draw the white paper and eliminate the small pieces (less than 1000000 px). This px count is the same as the QR code dectection 
for cnt in contours: 
    if cv2.contourArea(cnt)>1000000: 
     cv2.drawContours(mask,[cnt],0,255,-1) # the [] around cnt and 3rd argument 0 mean only the particular contour is drawn 

     # Build a ROI to crop the QR 
     x,y,w,h = cv2.boundingRect(cnt) 
     roi=mask[y:y+h,x:x+w] 
     # crop the original QR based on the ROI 
     QR_crop = QR_orig[y:y+h,x:x+w] 
     # use cropped mask image (roi) to get rid of all small pieces 
     QR_final = QR_crop * (roi/255) 

cv2.imwrite('QR_final.TIF', QR_final) 

回答

1

輪廓對象是包含檢測到的對象的點的任意矢量(列表)。

一個簡單的大腦實現這一點的死亡方式是通過你的閾值後,所有的像素走路,簡單地複製白色的。

我相信findContours()改變圖像(副作用),所以檢查QR。

但是,您需要(通常)獲得最大輪廓。 例子:

# Choose largest contour 
best = 0 
maxsize = 0 
count = 0 
for cnt in contours: 
    if cv2.contourArea(cnt) > maxsize : 
     maxsize = cv2.contourArea(cnt) 
     best = count 

    count = count + 1 

x,y,w,h = cv2.boundingRect(cnt[best]) 
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2) 
+0

是的,QR已更改爲原始圖像邊界的一組點。我真正想要做的是找到一個邊界框,這樣我可以使用這個邊界框來裁剪圖像。我想要一張只包含白皮書的圖像。 –

+0

我沒有包含裁剪/面具代碼,但也許上述將有所幫助。我相信你想從發現的輪廓中挑選出「最佳」輪廓,在這種情況下,我只選擇了最大的輪廓。 –

0

其實我想通了這個問題,這顯然是非常簡單的解決方案!

import cv2 
import numpy as np 


QR_orig = cv2.imread('CamR_IMG_0352.TIF', 0) 
QR = cv2.imread('IMG_0352.TIF', 0) # read the QR code binary image as grayscale image to make sure only one layer 
mask = np.zeros(QR.shape,np.uint8) # mask image the final image without small pieces 

# using findContours func to find the none-zero pieces 
contours, hierarchy = cv2.findContours(QR,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) 

# draw the white paper and eliminate the small pieces (less than 1000000 px). This px count is the same as the QR code dectection 
for cnt in contours: 
    if cv2.contourArea(cnt)>1000000: 
     cv2.drawContours(mask,[cnt],0,255,-1) # the [] around cnt and 3rd argument 0 mean only the particular contour is drawn 

     # Build a ROI to crop the QR 
     x,y,w,h = cv2.boundingRect(cnt) 
     roi=mask[y:y+h,x:x+w] 
     # crop the original QR based on the ROI 
     QR_crop = QR_orig[y:y+h,x:x+w] 
     # use cropped mask image (roi) to get rid of all small pieces 
     QR_final = QR_crop * (roi/255) 

cv2.imwrite('QR_final.TIF', QR_final)