3

I have a video downloaded from youtube, where there is present only black or white color. It is obviously compressed, so instead of (255, 255, 255) or (0, 0, 0) RGB I got some entries like (128, 128, 128) I have searched the internet and found this equation Y = 0.2126*R + 0.7152*G + 0.0722*B However when I coded this in python it sometimes gives me the wrong value. How can I determine by given RGB tuple whether it is closer to white or black? I have also coded the equation from Formula to determine perceived brightness of RGB color but it still gives me the wrong value(that the color is more black than white)

def rgb_percent(r, g, b):
    sR = r
    sG = g
    sB = b

    vR = sR / 255
    vG = sG / 255
    vB = sB / 255

    def sRGBtoLin(colorChannel):
        if colorChannel <= 0.04045:
            return colorChannel / 12.92
        else:
            return pow(((colorChannel + 0.055) / 1.055), 2.4)

    Rlin = sRGBtoLin(vR)
    Glin = sRGBtoLin(vG)
    Blin = sRGBtoLin(vB)

    y = (0.2126 * Rlin + 0.7152 * Glin + 0.0722 * Blin)

    def YtoLstar(Y):
        if Y <= (216 / 24389):
            return Y * (24389 / 27)
        else:
            return pow(Y, (1 / 3)) * 116 - 16
    return YtoLstar(y)

print(rgb_percent(3, 3,3))
martineau
  • 119,623
  • 25
  • 170
  • 301
Aleksander Ikleiw
  • 2,549
  • 1
  • 8
  • 26
  • "where there is present only black or white " -- Is it really pure black and white or is it grayscale? Are you trying to convert gray into B&W for some reason? Also in your title do you mean "closer" not "closed"? – Dave S Apr 25 '21 at 18:23
  • @DaveS I am trying to determine whether the gray is more black(in the original frame of the video it was pure black) or white(in original frame of the video it was pure white) – Aleksander Ikleiw Apr 25 '21 at 18:24
  • 1
    Ah, the gray is entirely from compression artifacts. – Dave S Apr 25 '21 at 18:25
  • Did you define a function on another? Is it possible? – Soroosh Noorzad Apr 25 '21 at 18:26
  • @DaveS is it possible if the every frame of the video is coded from either pure black or pure white? – Aleksander Ikleiw Apr 25 '21 at 18:27
  • 1
    `(128, 128, 128)` is exactly in the middle between black and white, what are you expecting? – xjcl Apr 25 '21 at 19:27
  • Can you specify why the equation `Y = 0.2126*R + 0.7152*G + 0.0722*B` did not work for you? Did you check if Y was above or below 0.5? – xjcl Apr 25 '21 at 19:30
  • @xjcl yes I have checked. It was giving me false results for some entries – Aleksander Ikleiw Apr 25 '21 at 19:31
  • 2
    @AleksanderIkleiw can you give an example where you get a "false" result? – xjcl Apr 25 '21 at 19:35
  • 3
    The equation is irrelevant. If R=G=B, your image is already greyscale, so you can discard 2 of the 3 channels without loss of information. So just take any single channel and see if it is nearer 0 or 255 and that's the best you can do. – Mark Setchell Apr 25 '21 at 21:14

1 Answers1

0

Without sample input we can only guess ...

However as mentioned (128,128,128) is gray "exactly" in middle between B/W that may hint not a lossy compression issue (that would produce different much smaller noise) but interpolation issue instead ... There are two common cases:

  1. Video source was at some resolution but has been encoded in different one

    If true the gray pixels will form grid like pattern (individual pixels) where black and white pixels neighbor. This can be restored back to original values like this:

  2. Video was rendered with subpixel precision and border pixels positions where off by 0.5 pixel

    In this case the gray pixels will not create a grid but can form grouped pixels (chunk of curve) on B/W objects border parts that do not align to pixel grid exactly.

    This is not possible to restore without having any info about the objects ... If you know what shape and size it should be you can fit it and re-render ...

    Cheap remedy is to set such colors to black or white (depends on if you want to shrink or enlarge objects)

Lossy compression

In case your gray pixels are not appearing only on B/W borders then it could really be lossy compression but as I wrote before that will most likely result in many different colors much more closer to (0,0,0) and (255,255,255) ...

Also The formula:

I = 0.2126 * Rlin + 0.7152 * Glin + 0.0722 * Blin

will not work for normalized RGB. For such:

I = R + G + B

As R == G == B produce gray scale colors...

So I would do something like this (assuming 8 bit normalized RGB channels):

if (R+G+B<383) { R=G=B=  0; }
 else          { R=G=B=255; }

However to get rid of the exact half problem I would do (weighted) average with 4 or 8 neighboring pixels along with the center pixel and compare the result.

Spektre
  • 49,595
  • 11
  • 110
  • 380