-3

I would like to invert an image when it only has a dark background or theme. For example, when I have a GUI window with a dark theme, I would like to invert its colors to make it light. However, when it has a light theme, just keep it as is.

I mean by dark theme not only black but also any other dark color (dark blue for example). I found some solutions that suggest counting zeros but I think this will work only for black backgrounds/themes.

AKMalkadi
  • 782
  • 1
  • 5
  • 18
  • Then what do you consider dark? If you don't have any strict mathematical definition on what's "dark" for your situation, then it's not possible to answer. – Ted Klein Bergman Jun 30 '21 at 15:24
  • @TedKleinBergman like when you use night theme / dark themes in your system. If we have scaled from 0 (black) to 255 (white). I would consider less than 50% as dark and others as light – AKMalkadi Jun 30 '21 at 15:27
  • Different applications have different night themes and therefore different colors. You need to define what is an appropriate threshold before dark becomes light. My guess would be that you want any RGB color where all colors components under 127 to be considered dark and all above are light, but that would very a very fragile definition. – Ted Klein Bergman Jun 30 '21 at 15:31
  • https://learnopencv.com/opencv-threshold-python-cpp/ Image Thresholding in OpenCV, you could try a way to sample your image and apply thresholding accordinly to the sampling result.... think is a long way but you'll get rewarded – pippo1980 Jun 30 '21 at 15:32
  • 1
    see if this is relevant https://stackoverflow.com/questions/52505906/find-if-image-is-bright-or-dark Find If Image Is Bright Or Dark – pippo1980 Jun 30 '21 at 15:36
  • Thanks @pippo1980 for the hints. I formed my solution. I will write the answer here – AKMalkadi Jun 30 '21 at 15:59

1 Answers1

0

Inspired by these post1 post2, I found the solution I need, and I tested on my data to get 100% accuracy.

The following is the code I used:

import cv2

def is_img_dark(img):
    #blur = cv2.blur(img, (5, 5))  # With kernel size depending upon image size # You could skip the blur and get exactly the same result

    if cv2.mean(img)[0] > 127:  # The range for a pixel's value in grayscale is (0-255), 127 lies midway
        return False # (127 - 255) denotes light image
    else:
        return True # (0 - 127) denotes dark image

img_file = "THE PATH OF THE IMAGE"
im = cv2.imread(img_file,0) # 0 here to gray the image
if is_img_dark(im):
    im = ~im # invert colors
AKMalkadi
  • 782
  • 1
  • 5
  • 18
  • 1
    any way to make it work reading images as color_images ?? – pippo1980 Jun 30 '21 at 17:44
  • @pippo1980 I would use another object (im2) : im2 = cv2.imread(img_file). Another way is to keep the first image as color without converting it to gray, and inside the is_img_dark function we convert the image to gray. – AKMalkadi Jun 30 '21 at 18:31
  • 1
    blaring an image doesn't affect its mean value. You could skip the blur and get exactly the same result. – Cris Luengo Jun 30 '21 at 18:50
  • does it makes sense for a three channel RGB image use the mean of the means (of each channel) to consider image dark or light ? (>127) like: if statistics.mean(cv2.mean(img)) > 127 – pippo1980 Jun 30 '21 at 22:01