Ask Your Question
0

How to Darken Faint/Dim Gray Text

asked 2020-11-18 07:49:51 -0600

kst gravatar image

updated 2020-11-18 08:10:29 -0600

berak gravatar image

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.

C:\fakepath\image.png

edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
1

answered 2020-11-18 08:33:12 -0600

kbarni gravatar image

updated 2020-11-18 08:35:35 -0600

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.

image description

edit flag offensive delete link more

Comments

Thanks a lot.

Your formula helps.

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

kst gravatar imagekst ( 2020-11-18 19:27:21 -0600 )edit
0

answered 2020-11-19 15:32:16 -0600

crackwitz gravatar image

updated 2020-11-19 20:07:38 -0600

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

your input intermediate result my output

#!/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 = cv.imread(impath, cv.IMREAD_GRAYSCALE)
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
textmask = (dilated >= 0.15)
# 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)
enhanced[~textmask] = im[~textmask]

# invert again for output
output = 1 - enhanced

cv.namedWindow("output", cv.WINDOW_NORMAL)
cv.imshow("output", output)
cv.waitKey(-1)
cv.destroyAllWindows()
edit flag offensive delete link more

Comments

I would like to know more about the "locally adaptive" method.

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

kst gravatar imagekst ( 2020-11-19 17:44:28 -0600 )edit

updated with code

crackwitz gravatar imagecrackwitz ( 2020-11-19 20:05:17 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2020-11-18 07:49:51 -0600

Seen: 4,975 times

Last updated: Nov 19 '20