0

I'm trying to do some labs we were given to complete in Matlab for a video analysis module in python since I have already completed them in Matlab and I'm having an issue with brightening an image. I have got the image to read into a Numpy array with no problem but when I use the following code to try to brighten it then show it:

    def imageProcessing(self, imageLocation):
        image = numpy.array(Image.open(imageLocation))
        imageGreyScale = numpy.array(Image.open(imageLocation).convert('L'))
        imageReadable = Image.fromarray(imageGreyScale)
        imageReadable.show()
        matplotlib.pyplot.hist(imageGreyScale.ravel(), 256, [0, 256]);
        matplotlib.pyplot.show()

        imageGreyScale = imageGreyScale+50
        imageReadableBrighter = Image.fromarray(imageGreyScale)
        imageReadableBrighter.show()
        matplotlib.pyplot.hist(imageGreyScale.ravel(), 256, [0, 256]);
        matplotlib.pyplot.show()

For some reason instead of data within 50 of 255 (the max grey level) being clipped at 255, the pixel value seems to hit 255 then go back to 0 and increment by however much is left (see the graph attached, the bit in red was beside the bit in green before the processing, but instead of being clipped has been "looped back" so to speak) Graph of the histogram after adding 50 to every pixel value

Now I have tried adding conditional assignment statements like Numpy.where(), etc but can't seem to get them to work correctly. Can anyone explain what's going on or how to fix it? Thank you.

Using: Python version 3.5, Latest version of Numpy, Latest version of PIL, On latest version of MacOS

Daniel B
  • 7
  • 5
  • 1
    That is how integer addition works in languages like C and Fortran, which implement numpy, as well as on the CPU level. Once you increment past `FF`, you go back to `00`. It would be expensive for the CPU to always check for overflow, plus it does not even have to know where the overflow occurs (take signed numbers for example). If you want overflow checks, you have to implement them yourself. – zvone Oct 20 '20 at 22:50
  • 1
    Related https://stackoverflow.com/q/29611185/214671 – Matteo Italia Oct 20 '20 at 22:53
  • Thank you @zvone, I both didn't know Numpy was implemented in C and I just realised looking at the type of the data in the Numpy array it's an 8 bit int so that would make sense, – Daniel B Oct 20 '20 at 23:08

1 Answers1

1

Why 250 + 50 = 44?

On the level of bits, it is the simplest to implement it that way. In 8.bit addition, All 8 bits are calculated and the ninth bit is not stored anyway (300=100101100b, 44=101100b).

If CPUs were implemented in such way that they check for overflow and then replace the value with min or max valid value, the calculation would still be wrong, in some cases even worse, and it would be slower even in situations where there is no chance for an overflow.

How to make 250 + 50 = 255?

The CPU is not doing it for you automatically, but you can do it yourself.

What you want to do is replace y = x + 50 with:

if x < 205:
    y = x + 50
else:
    y = 255

To do that efficiently on a large numpy array, do this:

x = np.array([1, 2, 3, 100, 200, 220, 250], dtype=np.uint8)
y = x + 50
y[x > 205] = 255  # or y[y < 50] = 255

or, shorter, in your case:

imageGreyScale += 50
imageGreyScale[imageGreyScale < 50] = 255
zvone
  • 18,045
  • 3
  • 49
  • 77