ISHAN JAISWAL
ISHAN JAISWAL

Reputation: 66

How to auto adjust contrast and brightness of a scanned Image with opencv python

I want to auto adjust the brightness and contrast of a color image taken from phone under different lighting conditions. Please help me I am new to OpenCV.

Source: Input Image

Result: result

What I am looking for is more of a localized transformation. In essence, I want the shadow to get as light as possible completely gone if possible and get darker pixels of the image to get darker, more in contrast and the light pixels to get more white but not to a point where it gets overexposed or anything like that.

I have tried CLAHE, Histogram Equalization, Binary Thresholding, Adaptive Thresholding, etc But nothing has worked.

My initials thoughts are that I need to neutralize Highlights and bring darker pixels more towards the average value while keeping the text and lines as dark as possible. And then maybe do a contrast filter. But I am unable to Get the result please help me.

Upvotes: 1

Views: 8319

Answers (2)

fmw42
fmw42

Reputation: 53081

Here is one way to do that in Python/OpenCV.

  • Read the input
  • Increase contrast
  • Convert original to grayscale
  • Adaptive threshold
  • Use the thresholded image to make the background white on the contrast increased image
  • Save results

Input:

enter image description here

import cv2
import numpy as np

# read image
img = cv2.imread("math_diagram.jpg")

# convert img to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# do adaptive threshold on gray image
thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 21, 15)

# make background of input white where thresh is white
result = img.copy()
result[thresh==255] = (255,255,255)

# write results to disk
cv2.imwrite("math_diagram_threshold.jpg", thresh)
cv2.imwrite("math_diagram_processed.jpg", result)

# display it
cv2.imshow("THRESHOLD", thresh)
cv2.imshow("RESULT", result)
cv2.waitKey(0)

Threshold image:

enter image description here

Result:

enter image description here

Upvotes: 10

amras
amras

Reputation: 1599

You can use any local binarization method. In OpenCV there is one such method called Wolf-Julion local binarization which can be applied to the input image. Below is code snippet as an example:

import cv2

image = cv2.imread('input.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)[:,:,2]

T = cv2.ximgproc.niBlackThreshold(gray, maxValue=255, type=cv2.THRESH_BINARY_INV, blockSize=81, k=0.1, binarizationMethod=cv2.ximgproc.BINARIZATION_WOLF)
grayb = (gray > T).astype("uint8") * 255

cv2.imshow("Binary", grayb)
cv2.waitKey(0)

The output result from above code is below. Please note that to use ximgproc module you need to install opencv contrib package.

enter image description here

Upvotes: 4

Related Questions