背景ムラの除去 - 2値化の前処理として

照明にムラがあるような画像の2値化は大域的な閾値では処理しきれない。
原画像
https://kakasi.skr.jp/images/uneven-sample.jpg

大津の法を適用
https://kakasi.skr.jp/images/uneven-otsu.jpg

適応的閾値処理(adaptiveThreshold)にするか、あらかじめムラを取り除いておく。

ムラを取り除くには
不均一な明るさの補正 - MATLAB & Simulink - MathWorks 日本(モルフォロジー演算)や
シェーディング画像に良好なしきい値を設定できる変動しきい値式2値化処理法(凹凸係数)
がある。

以下、白地に黒の文章画像を想定。

import cv2
import numpy as np

def blackhat(img, kernel_size=15):	# モルフォロジー演算
    kernel = np.ones((kernel_size, kernel_size), np.uint8)
    img = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
    img = cv2.bitwise_not(img)
    return img

def unevenness(img, kernel_size=63):	# 凹凸係数
    blur = cv2.blur(img, (kernel_size, kernel_size))
    img = img/blur
    img = np.clip(img*255, 0, 255).astype(np.uint8)
    return img

img = cv2.imread("uneven-sample.jpg", 0)
img1 = blackhat(img)
cv2.imwrite("blackhat.jpg", img1)
img2 = unevenness(img)
cv2.imwrite("unevenness.jpg", img2)

モルフォロジー演算
https://kakasi.skr.jp/images/blackhat.jpg

凹凸係数
https://kakasi.skr.jp/images/unevenness.jpg