Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
402 views
in Technique[技术] by (71.8m points)

python - Increase image brightness without overflow

I got a problem when trying to increase image brightness.

Here is the origin image:

enter image description here

The image I wanted to get is like this:

enter image description here

Now to increase the brightness with the following code:

    image = cv2.imread("/home/wni/vbshare/tmp/a4_index2.png",0)

    if sum(image[0])/len(image[0])<200:
        new = np.where((255-image)<image,255,image*2)
    else:
        new = image
    return new

And, I got the following image:

enter image description here

So, seems brightness of some points overflowed.

And I tried to change the threshold from 200 to some other number, e.g. 125, 100, 140 .etc However, the image brightness stays either almost same dark or overflow.

Env:

Python: 2.7.10

Opencv: 3.2.0

Any suggestion for this is appreciated.

Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here's my shot at a simple algorithm for cleaning up that particular image. Feel free to play with it and tweak it further to get the desired result.

NB: The code shown should work both with the 2.4.x and 3.x branches of OpenCV.

Step 0

Load the input image as grayscale.

img = cv2.imread('paper.jpg',0)

Step 1

Dilate the image, in order to get rid of the text. This step somewhat helps to preserve the bar code.

dilated_img = cv2.dilate(img, np.ones((7,7), np.uint8)) 

Dilated

Step 2

Median blur the result with a decent sized kernel to further suppress any text.

This should get us a fairly good background image that contains all the shadows and/or discoloration.

bg_img = cv2.medianBlur(dilated_img, 21)

Blurred

Step 3

Calculate the difference between the original and the background we just obtained. The bits that are identical will be black (close to 0 difference), the text will be white (large difference).

Since we want black on white, we invert the result.

diff_img = 255 - cv2.absdiff(img, bg_img)

Inverted Difference

Step 4

Normalize the image, so that we use the full dynamic range.

norm_img = diff_img.copy() # Needed for 3.x compatibility
cv2.normalize(diff_img, norm_img, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1)

Normalized

Step 5

At this point we still have the paper somewhat gray. We can truncate that away, and re-normalize the image.

_, thr_img = cv2.threshold(norm_img, 230, 0, cv2.THRESH_TRUNC)
cv2.normalize(thr_img, thr_img, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1)

Gray Trimmed

Done...

Well, at least for me ;) You will probably want to crop it, and do whatever other post-processing you desire.


Note: It might be worth switching to higher precision (16+ bit int or float) after you get the difference image, in order to minimize accumulating rounding errors in the repeated normalizations.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...