# How to Darken Faint/Dim Gray Text

I have a scanned text document. After some pre-processing, I managed to get texts on a white background. However, some texts are in gray colour (faint/light gray) and some text in black. At least, the black text is darker than the gray text.

I tried using thresholding but the gray like didn't change much.

What is a good approach to make the gray text darker (or black) and not affecting the already black text and white surrounding.

I also attached a sample image. Basically I would like to make the string "This is a demonstration" in light gray darker or black will be ideal.

edit retag close merge delete

Sort by » oldest newest most voted

Use the so-called gamma correction. The formula is:

result = 255 * (image/255)^k


With different k exponent values you can have lighter (k<1) or darker (k>1) grays, while not affecting whites and blacks.

more

Thanks a lot.

Now I just need to tweak the K value to suit my use case.

( 2020-11-18 19:27:21 -0500 )edit

not affecting the already black text and white surrounding

thresholding would affect those. and so does gamma-mapping, brightness and contrast adjustments, ... load your picture up in an image editor, then play with curves, levels, or brightness and contrast.

if you threshold, pick a threshold above the gray text's gray value. that text will be thresholded to black.

you can come up with better approaches that leave the black text as is.

a "locally adaptive" method you could try:

• grayscale erode/dilate of some sufficient radius gives an estimate of how intense the text is, or where there is no text
• where there is text, you recalculate the pixel linearly (division, more or less)

let me know if you need more detail for this.

image gallery: https://imgur.com/a/IfutpMZ

#!/usr/bin/env python3

import os
import sys
import numpy as np
import cv2 as cv

impath = "1605707252792223.png"
if len(sys.argv) >= 2:
impath = sys.argv[1]

im = im.astype(np.float32)
im = im / 255 # rescale
im = 1 - im # inversion. ink is the signal, white paper isn't

# some "sensor noise" for demo, if you want to look at intermediate results
#im += np.random.normal(0.0, 0.02, size=im.shape)

# squares/rectangles
#morph_kernel = cv.getStructuringElement(shape=cv.MORPH_RECT, ksize=(5,5))
morph_kernel = np.ones((5,5))

# opencv's ellipses are ugly as sin
# alternative:
#import skimage.morphology
#morph_kernel = skimage.morphology.octagon(5,2)

# estimates intensity of text
dilated = cv.dilate(im, kernel=morph_kernel)

# tweak this threshold to catch faint text but not background
# 0.05 catches background noise of 0.02
# 0.25 loses some text

# rescale text pixel intensities
# this will obviously magnify noise around faint text
enhanced = im / dilated

# copy unmodified background back in
# (division magnified noise on background)

# invert again for output
output = 1 - enhanced

cv.namedWindow("output", cv.WINDOW_NORMAL)
cv.imshow("output", output)
cv.waitKey(-1)
cv.destroyAllWindows()

more

Would you be able to demonstrate it over some python script ?

( 2020-11-19 17:44:28 -0500 )edit

updated with code

( 2020-11-19 20:05:17 -0500 )edit

Official site

GitHub

Wiki

Documentation