Python - find out which part of the image is black

I upload satellite images like this satellite_image
(source: u0553130 at home.chpc.utah.edu )

Since some images are mostly black, for example, I do not want to save them.

How can I use python to check if an image is more than 50% black?

+6
source share
4 answers

You are dealing with gifs that mostly look like grayscale in your image, so you can expect most of the RGB components to be equal.

Using 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") 

Adjust the threshold for black between 0 (black) and 255 (bright white) if necessary).

+8
source

A careful way is to count the pixels using something like PIL, as indicated in other answers.

However, if they are all compressed images, you can check the file size, since images with a large number of areas with a normal color should compress much more than with a change, such as a cloud.

With some tests, you could at least find a heuristic with images with lots of clouds that, as you know, you can instantly drop without an expensive loop over your pixels. Others, closer to 50%, can be checked for pixels.

Also, when iterating over pixels, you don’t need to count all black pixels, and then check at least 50% black. Instead, stop counting and discard as soon as you know that at least 50% are black.

Second optimization: if you know that images, as a rule, are mostly cloudy and not mostly black, go the other way. Count the number of non-black pixels and stop and save the images as soon as it passes 50%.

+3
source
  • Upload image
  • Read each pixel and the result of the increment if pixel = (0,0,0)
  • If the result = <(image.width * image.height) / 2
  • Save image

Or check if it is almost black by returning true if your R (or G or B) component of the pixel is less than 15.

0
source

Using a test image, the most common color is RGB (1, 1, 1). It is very black, but not completely black. My answer uses the PIL library , webcolors and the generous help code from this answer.

 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 

Conclusion:

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

In this case, you will be interested in the variable closest_name . The first ( lt[0] ) shows you the most common RGB value. This does not have a specific web color name, so None for actual_name


Explanation:

This opens the file you provided by converting it to RGB and then running the PIL getcolors method on the image. The result is a list of tuples in the format (count, RGB_color_value). Then I sort the list (in reverse order). Using functions from another answer , I pass in the most common RGB color value (now the first tuple in the list, and RBG the second element in the tuple).

0
source

Source: https://habr.com/ru/post/1210763/


All Articles