Python OpenCV 检测二进制图像中的白色物体并裁剪

2024-05-16 11:27:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我的目标是从这张二值图像中检测出一张白纸,然后裁剪出这张白纸,并为这张白纸生成一个新的二值图像子集。 enter image description here

现在,我使用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)

Tags: theto代码图像imageimportasnp
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)

轮廓对象是包含检测到的对象的任意点向量(列表)。

实现这一点的一个简单的方法是在阈值后遍历所有像素,然后简单地复制白色像素。

我相信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)

相关问题 更多 >