如何快速高效地检查一张图片是否主要为背景?

3

我有巨大的千兆像素大小的癌症组织全切片图像,我正在从中采样补丁以训练卷积神经网络(CNN)。以下是其中一个补丁的外观:

目前,我正在使用下面的代码来尝试滤除超过30%空白的背景补丁,但似乎不起作用。

   i = random.randint(0, x - patch_size/(2**level))
   j = random.randint(0, y - patch_size/(2**level))
   grey = cv2.cvtColor(img[j:j+patch_size/(2**level), i:i+patch_size/(2**level)], cv2.COLOR_RGB2GRAY)    
   ret, thresh = cv2.threshold(grey, 80, 255, cv2.THRESH_BINARY)
   if numpy.sum(thresh <= 10) >= 0.3*(patch_size**2):
       arr.append((i, j))

我正在生成的许多补丁仍然是空白的,我认为这可能是因为图像的灰白色部分没有被过滤掉。无论如何,我不认为我的方法将补丁转换为灰度图像,然后阈值处理以计算白色像素的数量是非常有效的。我想到了通过文件大小进行比较,因为我注意到所有空白图像都具有较低的文件大小,但保存一个补丁,计算文件大小,然后删除它似乎也不是非常有效的。对于快速和高效地过滤掉非组织补丁,您有什么想法吗?
编辑:我在评论中发布了一些附加信息。 除了粉色或紫色之外的任何内容都是背景。我的补丁是256x256的图像,可以超过1,000,000x1,000,000。我通过随机生成代表下采样宽度和高度内一个补丁左上角的坐标点来选择补丁,检查补丁是否主要由组织构成,然后将坐标保存到数组中。我有指出感兴趣区域的轮廓,但我选择其中的补丁的代码很好用。我只需要选择ROIs之外的正常组织区域,而不是大部分为空白空间的区域。

补丁有多大?如何选择补丁?如果我假设你裁剪出了补丁,那么你可以将标准差值与某个阈值进行比较。如果太低,则图像是平坦的颜色并将其丢弃。如果足够高,则具有纹理变化和可能的图像内容。 - fmw42
你如何定义“背景”?这个定义适用于你所有的图像吗? - Micka
任何不是粉色或紫色的都是背景。我的补丁是256x256的图像,可以超过1,000,000x1,000,000。我通过随机生成代表下采样宽度和高度内贴片左上角的坐标点来选择贴片,检查贴片是否主要为组织,然后将坐标保存到数组中。我有指出感兴趣区域的轮廓,但我选择其中的补丁的代码运行良好。我只需要选择ROIs之外的区域,这些区域具有正常的组织并且不是大部分为空白空间。 - 2fly2try
尝试使用OpenCV的meanStdDev()函数,并检查标准差是否较低 - 这意味着您正在查看的256x256区域中没有太多变化,因此它是平坦且没有变化的。 - Mark Setchell
我尝试了这个,但不幸的是现在我只能捕捉到沿边缘的黑线。我无法保证这些线条延伸到图像的深处,也不知道实际组织在图像中的位置,因此我不能仅仅剪切图像的边缘。 - 2fly2try
你可以尝试使用动态阈值技术,如Otsu的阈值或自适应阈值图像处理,这样就不必计算阈值。从这里开始,您可以使用np.nonzero找到非零像素,然后使用它来确定背景是否为空。 - coffeewin
1个回答

2
一种方法是使用Otsu的阈值,使得像素值为255表示白色或者0表示黑色,然后应用cv2.countNonZero()函数。该函数将计算所有非白色像素,如果该值小于预定阈值(图像面积的一半),则大部分为空白背景。以下是二值化后的图像:

我们计算白色像素与黑色像素的比率,然后使用此比率来确定结果,使用最小背景阈值。
Pixel ratio: 9.88%
Mostly Background

代码

import cv2

image = cv2.imread('1.png')
h, w, _ = image.shape
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY_INV)[1]

pixels = cv2.countNonZero(thresh)
ratio = (pixels/(h * w)) * 100
print('Pixel ratio: {:.2f}%'.format(ratio))

if ratio < 50:
    print('Mostly Background')
else:
    print('Not Mostly Background')

cv2.imshow('thresh', thresh)
cv2.waitKey()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接