7

我正在下载这样的卫星图片 (来源:u0553130 at home.chpc.utah.edu卫星图像

由于有些图像大多是黑色的,比如这张,我不想保存它。

如何使用 python 检查图像是否超过 50% 黑色?

4

4 回答 4

11

您正在处理的 gif 图像从示例图像的外观来看大多是灰度的,因此您可能期望大多数 RGB 分量是相等的。

使用 PIL:

from PIL import Image
im = Image.open('im.gif')
pixels = im.getdata()          # get the pixels as a flattened sequence
black_thresh = 50
nblack = 0
for pixel in pixels:
    if pixel < black_thresh:
        nblack += 1
n = len(pixels)

if (nblack / float(n)) > 0.5:
    print("mostly black")

根据需要在 0(黑色)和 255(亮白色)之间调整“黑色”的阈值)。

于 2015-01-09T20:15:42.420 回答
4

彻底的方法是使用其他答案中给出的 PIL 之类的东西来计算像素。

但是,如果它们都是压缩图像,您可以检查文件大小,因为具有大量纯色区域的图像应该比云层等具有变化的图像压缩得更多。

通过一些测试,您至少可以找到一种启发式方法,您知道可以立即丢弃哪些具有大量云的图像,而无需在像素上进行昂贵的循环。其他接近 50% 的可以逐像素检查。

此外,在对像素进行迭代时,您不需要计算所有黑色像素,然后检查是否至少有 50% 是黑色的。相反,一旦你知道至少 50% 是黑色的,就停止计数并丢弃。

第二个优化:如果您知道图像通常大多是阴天而不是大部分是黑色的,那就另当别论了。计算非黑色像素的数量,并在超过 50% 时立即停止并保留图像。

于 2015-01-10T09:07:31.260 回答
0
  • 加载图像
  • 如果 pixel = (0,0,0) 则读取每个像素并增加结果
  • 如果结果 =< (image.width * image.height)/2
  • 保存图片

或者,例如,如果您的像素 ​​R(或 G 或 B)分量小于 15,则通过返回 true 来检查它是否几乎是黑色的。

于 2015-01-09T20:07:21.470 回答
0

利用您的测试图像,最常见的颜色的 RGB 值为 (1, 1, 1)。这是非常黑的,但不完全是黑色。我的答案利用了PIL 库webcolors和来自这个答案的大量代码帮助。

from PIL import Image
import webcolors

def closest_color(requested_color):
    min_colors = {}
    for key, name in webcolors.css3_hex_to_names.items():
        r_c, g_c, b_c = webcolors.hex_to_rgb(key)
        rd = (r_c - requested_color[0]) ** 2
        gd = (g_c - requested_color[1]) ** 2
        bd = (b_c - requested_color[2]) ** 2
        min_colors[(rd + gd + bd)] = name
    return min_colors[min(min_colors.keys())]

def get_color_name(requested_color):
    try:
        closest_name = actual_name = webcolors.rgb_to_name(requested_color)
    except ValueError:
        closest_name = closest_color(requested_color)
        actual_name = None
    return actual_name, closest_name

if __name__ == '__main__':
    lt = Image.open('test.gif').convert('RGB').getcolors()
    lt.sort(key=lambda tup:tup[0], reverse=True)
    actual_name, closest_name = get_color_name(lt[0][4])
    print lt[0], actual_name, closest_name

输出:

(531162, (1, 1, 1)) None black

在这种情况下,您会对closest_name变量感兴趣。第一个 ( lt[0]) 显示最常见的 RGB 值。这没有定义的网络颜色名称,因此Noneforactual_name


解释:

这是打开您提供的文件,将其转换为 RGB,然后getcolors在图像上运行 PIL 的方法。其结果是格式为 (count, RGB_color_value) 的元组列表。然后我对列表进行排序(以相反的顺序)。利用另一个答案中的函数,我传递了最常见的 RGB 颜色值(现在列表中的第一个元组,RBG 是元组中的第二个元素)。

于 2015-01-09T20:22:34.403 回答