这个问题可能是几年前的问题,但我最近有一个类似的任务。在这里分享我的答案可能会帮助其他遇到相同任务的人,我还可以通过让社区查看来改进我的答案。
import cv2 as cv
import numpy as np
THRESHOLD_INTENSITY = 230
def has_white_background(img):
# Read image into org_img variable
org_img = cv.imread(img, cv.IMREAD_GRAYSCALE)
# cv.imshow('Original Image', org_img)
# Create a black blank image for the mask
mask = np.zeros_like(org_img)
# Create a thresholded image, I set my threshold to 200 as this is the value
# I found most effective in identifying light colored object
_, thres_img = cv.threshold(org_img, 200, 255, cv.THRESH_BINARY_INV)
# Find the most significant contours
contours, hierarchy = cv.findContours(thres_img, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE)
# Get the outermost contours
outer_contours_img = max(contours, key=cv.contourArea)
# Get the bounding rectangle of the contours
x,y,w,h = cv.boundingRect(outer_contours_img)
# Draw a rectangle base on the bounding rectangle of the contours to our mask
cv.rectangle(mask,(x,y),(x+w,y+h),(255,255,255),-1)
# Invert the mask so that we create a hole for the detected object in our mask
mask = cv.bitwise_not(mask)
# Apply mask to the original image to subtract it and retain only the bg
img_bg = cv.bitwise_and(org_img, org_img, mask=mask)
# If the size of the mask is similar to the size of the image then the bg is not white
if h == org_img.shape[0] and w == org_img.shape[1]:
return False
# Create a np array of the
np_array = np.array(img_bg)
# Remove the zeroes from the "remaining bg image" so that we dont consider the black part,
# and find the average intensity of the remaining pixels
ave_intensity = np_array[np.nonzero(np_array)].mean()
if ave_intensity > THRESHOLD_INTENSITY:
return True
else:
return False
这些是上面代码中步骤的图像:
这是原始图像。无侵犯版权之意。
(无法从unsplash找到实际图像的url)
第一步是将图像转换为灰度。
对图像应用阈值。
获取“阈值”图像的轮廓并获取轮廓。绘制轮廓只是可选的。
从轮廓中,获取外轮廓的值并找到它的边界矩形。可以选择将矩形绘制到图像上,以便您查看假设的阈值是否适合矩形中的对象。
在边界矩形之外创建一个遮罩。
最后,将蒙版减去灰度图像。剩下的是背景图像减去蒙版。
要最后判断背景是否为白色,求除图像数组的0值之外的背景图像的平均强度值。并根据一定的阈值,判断是否为白色。
希望这会有所帮助。如果您认为它仍然可以改进,或者我的解决方案存在缺陷,请在下方评论。