【问题标题】:How can I determine the average tone of a given area in a grayscale image using OpenCV?如何使用 OpenCV 确定灰度图像中给定区域的平均色调?
【发布时间】:2020-11-05 22:11:52
【问题描述】:

我有一张灰度图像,我需要确定其背景的平均色调。问题是,该图像有一些黑点,因此,如果我试图找到整个图像的平均色调,我最终会得到与我想要的色调不同的色调。通过手动放大背景,我发现像素色调在 180-195 之间波动。

我想解决这个问题的方法是确定给定区域的平均色调,其中没有黑点(在图片中,由我知道坐标的黑色矩形包围的区域)。问题是我不知道我会怎么做。在网上搜索后,我发现了一些关于确定彩色图像的平均颜色的文章,但与灰度图像无关,也与预定区域的平均色调无关。

我在余下的图像处理工作中使用 OpenCV 库,如果可能的话,我更愿意使用该库来解决这个问题,但是非常感谢任何关于这个问题的帮助。

.

【问题讨论】:

  • result = im[y0:y1, x0:x1].mean()
  • 您选择的区域的平均灰度级别与图像右下角的平均值有很大不同。你希望用你获得的平均值做什么?
  • @beaker 我需要对具有不同背景色调的图像进行阈值处理。这些图像包含需要突出显示并通过阈值处理带到前景的粒子。不同的背景需要对自适应阈值参数进行微调。我希望做的是通过使用具有不同色调的示例背景来找出这些调整。然后,我希望找到一种方法来识别带有粒子的已确定图像的背景色调,并让算法使用适合其背景色调的阈值参数。

标签: opencv image-processing


【解决方案1】:

我不能 100% 确定您在这里实际尝试做什么,但我认为您想确定背景的色调并减去它或根据它做一些事情来确定您的粒子在哪里。如果我完全错了,无需投入太多精力,如果您喜欢,您/我们可以采用这种方法来适应 OpenCV。

将图像分成 10x10 的规则网格。计算得到的 100 个矩形中的每一个内的方差或标准差。选择方差最小的那个——因为它是最恒定的那个,并且其中最不可能有任何粒子——然后得到那个矩形的平均值并将其用作你的图像平均值。

所以,我只是在终端中使用 ImageMagick 做到了这一点。这里我使用 5x5 网格而不是 10x10 来使输出更小:

magick image.png -crop 5x5@ -format "%[standard-deviation] %[mean] %X %Y\n" info: | sort -n

输出

835.2 49706.8 +410 +613
835.915 50146.3 +614 +153
845.005 49458 +819 +613
850.8 49997.2 +410 +460
852.937 50198 +614 +306
854.049 49577.4 +205 +460
857.193 50051.1 +614 +460
858.613 49752.5 +614 +613
859.179 49557.4 +819 +460
870.186 49298.2 +819 +0
872.404 48692.2 +205 +0
877.883 49439.4 +205 +613
878.972 49458.6 +205 +306
880.427 49391.9 +410 +0
882.476 47767.1 +0 +0
887.067 49180.4 +205 +153
897.929 48872.3 +0 +613
921.144 49753.9 +819 +153
932.777 48344.7 +0 +153
956.651 48550.5 +0 +306
987.255 48661.6 +0 +460
988.145 49776.3 +819 +306
1005.76 49909 +410 +153
1009.17 49685.2 +614 +0
1272.57 50062.4 +410 +306

因此,有 25 条线 - 5x5 网格中的每个矩形对应一条线。每行的第一个字段是该矩形的标准偏差,第二个是平均值,第三个是矩形左上角的 x 偏移量,第四个是左上角的 y 偏移量矩形。

按照标准差排序,第一行是方差最小的矩形,其平均灰度值为 49706,比例为 0..65535。即 193,比例为 0..255。该矩形的左上角位于 [410,613]


您可能对“局部区域阈值”感兴趣,请参阅here。例如,在您的图像上,您可以突出显示比周围 100x100 区域暗 6% 的像素,如下所示:

magick image.png -negate -lat 100x100+6%  result.png

【讨论】:

  • 是的!这正是我所需要的,无论粒子位于我的图像中的什么位置,它现在都应该可以工作。感谢您回答我的问题。
【解决方案2】:

这是在 Python/OpenCV 中执行此操作的一种方法。通过阈值化创建蒙版图像。然后得到mask中白色像素对应的像素的平均值。

输入:

import cv2
import numpy as np

# read image
img = cv2.imread('gray_with_spots.png')

# convert to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# threshold
thresh = cv2.threshold(gray, 180, 255, cv2.THRESH_BINARY)[1]

# count number of white pixels
mean = np.mean(img)
print("mean =",mean)

mean_masked = np.mean(img[np.where(thresh == 255)])
print("masked mean =",mean_masked)

# write thresh to disk
cv2.imwrite("gray_with_spots_thresh.png", thresh)

# display it
cv2.imshow("THRESH", thresh)
cv2.waitKey(0)

面具:

平均值:

平均值 = 191.81259179177545 掩蔽均值 = 192.3657402342317


【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    • 1970-01-01
    • 2012-05-28
    • 2014-11-29
    • 2012-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多