Histogram equalisation (on its own) is not likely to work here because it corrects the brightness levels of the image as a whole.
What you are dealing with here is a uniform reduction in brightness akin to the effect of an optical filter.
What is really required is the correction of the mean brightness level over the "patch" that appears darker. Therefore, the problem now is to find the patch and correct it.
I am going to use Octave for the rest of this post but as you will see too it is not too difficult to transpose the idea to Python.
Let's have a look at the damage:
%Load the image and plot its average values by column.
a = imread('SomeImage.jpg');
imshow(a); %This should simply depict the image
%Let's take the cross section of the image by "squashing" all of its columns into their average.
q = mean(a);
This comes out like:
The most striking feature in this image is the sharp drop of the brightness level, about a third of the image width from the left.
Let's now look at the vertical cross section by "squashing" all of the image's rows into a mean column. All you have to add is:
And this comes out like:
In fact, if you have MATLAB somewhere handy, you might want to try to
surf(a) and that will show you the "basin(s)" very clearly. For some reason, Octave's surf is getting its triangles tangled when I try to do it.
Right, so, what do we observe from this?
The image on either side of the discontinuities is predictable. It looks as if you simply took part of the waveform and slide it downwards...similar to the effect of a neutral density filter. There's simply a dip in the brightness that has a rectangular shape.
The problem on the first image is worse than the problem on the second image. On the second image we observe a sharp discontinuity which is approximately 4 pixels wide but it is very very sharp. On the first image, the discontinuity is about 8 pixels wide. Whatever data there was in those pixels has been "swallowed" by the gradient.
Working in 1 dimension (at first) you can see that just by either adding a value to the dip or subtracting a value from the "step", you can more or less match the means of the two regions on either side of the discontinuity. But for those pixels in the transition band, you are going to have to do something else (e.g. interpolation) to remedy the problem. The data in that region has been lost.
Where is the (big) patch? It starts approximately at 85,78 and extends all the way to the margins of the image. The X point is found by squashing all columns into one row and then looking at where the discontinuity starts and the Y point is found by doing the same but this time squashing all rows into one column.
Let's try to correct the X direction. First of all, we are going to get rid of the transition gradient. This is between pixels 85-93 (not across the whole image though, remember that this was a patch and that here we are trying to correct for the one dimensional case).
Q = q;
Q(85:93) = 0;
Now, correct for the brightness. The difference is approximately 36. All I am doing here is to add a "step" (a constant value) from pixel 93 onwards, like so:
Q2 = Q+36*[zeros(1,m),ones(1,length(Q)-m)];
This now looks like this:
What can you do for that gap of 8 values? You can fill it in with a constant value but that is going to show up as a "band" of 8 pixels and it will definitely be visible. The other thing you can do is to fill it with some Gaussian noise that has approximately pixel value 36 mean and enough variance so that you cannot distinguish it from the surrounding pixels. Unfortunately, because in this case the noise would be uncorrelated that would show up as banding again but this time much more "fuzzy". And finally, the other thing you could do is to train a model that would "generate" realistic values from the surrounding areas so that you "heal" the bands gracefully.
This is the basic idea. To automatically find the gradients you can either extract the gradient of the image with
imgradient or do a similar calculation in a loop with a threshold on the local slope.
Your problems are not over here. As you can see in all images, there are more than 1 "basins" in the image. Your first image has a light band on the top right part which goes right into the darkness right below it.
Hopefully they are all rectangular so you can simply repeat the exact same process as many times as it is required until the image contains "no basins".
Hope this helps.