【问题标题】:Detect textured background for contrasted images检测对比图像的纹理背景
【发布时间】:2022-01-11 06:55:07
【问题描述】:

我有两种类型的图像,它们都是对比鲜明的。

类型 1:(白色和干净的背景)

类型 2:(背景中有一些灰色纹理)

我可以应用高斯模糊和阈值来处理类型 2 图像以将其调整为类似于类型 1 的白色背景,如下代码:

type2_img = cv2.imread(type2.png)
# convert to grayscale
gray = cv2.cvtColor(type2_img , cv2.COLOR_BGR2GRAY)
# threshold the image using Otsu's thresholding
thresh = cv2.threshold(gray.copy(), 0, 255, cv2.THRESH_OTSU)[1]
# convert back to RGB
type2_img = cv2.cvtColor(thresh,cv2.COLOR_GRAY2RGB)

而且,我可以得到以下结果

但是,我不希望对类型 1 图像应用相同的方法,因为它已经满足条件。

那么,OpenCV 中是否有任何图像处理方法可以区分类型 2 和类型 1 的图像?

【问题讨论】:

标签: python opencv image-processing background-process noise-reduction


【解决方案1】:

您提供的type 1 图像是灰度图像,并非完全黑白图像。然而最后一个阈值输出图像是黑白的。

根据您的问题,我的理解是这两个都应归类为 type 1,而 type 2 图像示例应归类为类型 2。

如果类型 1 始终是黑白的,您可以计算图像中 0 和 1 的数量,并检查它们的总和是否等于图像的总像素数。

这里的一个选项是在不修改图像的情况下对两种类型的图像进行分类,即使用图像直方图的黑白像素百分比。

代码

import cv2
import numpy as np
from matplotlib import pyplot as plt
from skimage import exposure

#img_path = r'hist_imgs/1.png'
#img_path = r'hist_imgs/2.png'
img_path = r'hist_imgs/3.png'

img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
cv2.imshow('Image', img)

img_pixel_count = img.shape[0] * img.shape[1]
print(img.shape)
print(img_pixel_count)

h = np.array(exposure.histogram(img, nbins=256))

bw_count = h[0][0] + h[0][255]
other_count = img_pixel_count - bw_count

print('BW PIXEL COUNT: ',  bw_count)
print('OTHER PIXEL COUNT: ',  other_count)

bw_percentage = (bw_count * 100.0) / img_pixel_count
other_percentage = (other_count * 100.0) / img_pixel_count

print('BW PIXEL PERCENTAGE: ',  bw_percentage)
print('OTHER PIXEL PERCENTAGE: ',  other_percentage)

differentiate_threshold = 3.0
if other_percentage > differentiate_threshold:
    print('TYPE 2: GRAYSCALE')
else:
    print('TYPE 1: BLACK AND WHITE')

plt.hist(img.ravel(), 256, [0, 256])
plt.title('Histogram')
plt.show()

输入图像

图片 1:

图 2:

图 3:

代码输出

图片 1:

(154, 74)
11396
BW PIXEL COUNT:  11079
OTHER PIXEL COUNT:  317
BW PIXEL PERCENTAGE:  97.21832221832221
OTHER PIXEL PERCENTAGE:  2.781677781677782
TYPE 1: BLACK AND WHITE

图 2:

(38, 79)
3002
BW PIXEL COUNT:  1543
OTHER PIXEL COUNT:  1459
BW PIXEL PERCENTAGE:  51.39906728847435
OTHER PIXEL PERCENTAGE:  48.60093271152565
TYPE 2: GRAYSCALE

图 3:

(38, 79)
3002
BW PIXEL COUNT:  3002
OTHER PIXEL COUNT:  0
BW PIXEL PERCENTAGE:  100.0
OTHER PIXEL PERCENTAGE:  0.0
TYPE 1: BLACK AND WHITE

【讨论】:

  • 您好@B200011011,非常感谢您的回答。您的解决方案是迄今为止我正在寻找的最接近的方法。它确实帮助我制定了一个非常明确的阈值来区分这些图像。我会尝试更大的一组图像,并尽快让你知道结果。请问您能否详细解释一下“nbins=256”参数?我注意到在一些没有黑色的图像中,NumPy 数组长度不会是 256,并且 h[0][255] 会导致 IndexError: index 255 is out of bounds。是否有任何设置可以使 hist 数组的长度固定为 256?
  • 您可以尝试对h[0][255]h[0][0] 进行异常处理,以在求和之前查看这些值是否存在。如果不是,则根据此调整条件。您也可以完全跳过bw_count,将h[0][1]h[0][254] 的所有值相加,然后使用other_percentage 进行分类。
  • 您好@B200011011,谢谢您的建议。我添加了异常处理错误。到目前为止,您的解决方案为我提供了我想要的阈值,并且我正在对其余数据进行更多测试。再次,非常感谢。
  • 您好@B200011011,非常感谢您上次的回答。我已经实现了您的解决方案,但不幸的是,它无法完全解决我在这个原始问题here 中发布的所有案例。您还有其他建议我应该尝试吗?
  • 当然,如果我能给出任何想法,我会看看。
【解决方案2】:

要知道图像是否模糊,我会使用拉普拉斯算子的方差。

import cv2

im1 = cv2.imread("s1.png")
im2 = cv2.imread("s2.png")

print(f"Im1: {cv2.Laplacian(im1, cv2.CV_64F).var()}")
print(f"Im2: {cv2.Laplacian(im2, cv2.CV_64F).var()}")

输出:

Im1: 10493.1934011934
Im2: 17803.672073381236

我会在每节课的中间设置一个阈值,查看一些训练集或示例。

希望它有效!

【讨论】:

  • 非常感谢您的帮助。这似乎是我一直在寻找的答案。我会用我的数据尝试你的答案,并尽快让你知道结果。
  • 完美!如果您需要更多帮助,请告诉我它的工作原理。
  • 感谢您上次的回复。您的解决方案适用于我提供的示例,但不适用于我的其他数据。在一类图像上,我发现拉普拉斯方差的标准值非常大。我认为这是因为大量具有多种尺寸的图像。这使得很难根据拉普拉斯算子的方差找到阈值。
  • 嗨@TsunamiSerra,我已经更新了原始问题here。如果您有时间,非常欢迎任何其他建议。提前致谢。
  • 嗨,伙计,@NguyenHai,如果有时间我一定会去看看。
猜你喜欢
  • 2016-04-19
  • 1970-01-01
  • 2016-06-11
  • 2018-11-28
  • 1970-01-01
  • 2019-11-27
  • 2020-10-07
  • 2015-04-05
  • 2020-08-08
相关资源
最近更新 更多