1. ホーム
  2. python

OpenCVによる用紙のカラー写真のコントラストと明るさの自動調整

2023-09-14 23:54:50

質問

携帯電話のカメラなどで紙を撮影すると、次のような結果になります(左の画像)(jpgダウンロード ここで ). 望ましい結果(画像編集ソフトで手動処理したもの)は右の通りです。

元画像をopenCVで加工して明るさ・コントラストを良くしたい を自動的に (背景がより白くなるように)。 .

前提: 画像は A4 縦長形式 (このトピックではパースペクティブ ワープは必要ありません)、用紙は白で、テキスト/画像は黒またはカラーである可能性があります。

これまでに試したこと。

  1. いろいろ 適応的閾値処理 Gaussian, OTSU などの手法があります(OpenCV のドキュメントを参照してください). 画像の閾値処理 ). 通常,OTSUと一緒に使うとうまくいきます.

    ret, gray = cv2.threshold(img, 0, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY)
    
    

    が、これはグレースケール画像にしか使えない であり、カラー画像には直接使えない。さらに の出力はバイナリ(白か黒)ですが、これは私が望まないものです。 : 私は出力としてカラーノンバイナリ画像を保持することを好む

  2. ヒストグラムの均等化

    • Y に適用 (RGB => YUV 変換後)
    • またはVに適用(RGB => HSV変換後)。

    で提案されているように 答え ( カラー画像でヒストグラム等化が機能しない - OpenCV ) または、この 一つ ( OpenCV Python EqualizeHist カラー画像 ):

    img3 = cv2.imread(f)
    img_transf = cv2.cvtColor(img3, cv2.COLOR_BGR2YUV)
    img_transf[:,:,0] = cv2.equalizeHist(img_transf[:,:,0])
    img4 = cv2.cvtColor(img_transf, cv2.COLOR_YUV2BGR)
    cv2.imwrite('test.jpg', img4)
    
    

    またはHSVで。

    img_transf = cv2.cvtColor(img3, cv2.COLOR_BGR2HSV)
    img_transf[:,:,2] = cv2.equalizeHist(img_transf[:,:,2])
    img4 = cv2.cvtColor(img_transf, cv2.COLOR_HSV2BGR)
    
    

    残念ながら、局所的にひどい微小コントラストが生じるため、結果はかなり悪い(?)

    また、代わりにYCbCrを試してみましたが、似たような感じでした。

  3. も試してみましたが CLAHE (Contrast Limited Adaptive Histogram Equalization) (コントラスト制限付きアダプティブヒストグラム等化) を様々な tileGridSize から 1 から 1000 :

    img3 = cv2.imread(f)
    img_transf = cv2.cvtColor(img3, cv2.COLOR_BGR2HSV)
    clahe = cv2.createCLAHE(tileGridSize=(100,100))
    img_transf[:,:,2] = clahe.apply(img_transf[:,:,2])
    img4 = cv2.cvtColor(img_transf, cv2.COLOR_HSV2BGR)
    cv2.imwrite('test.jpg', img4)
    
    

    が、その結果も同様にひどいものでした。

  4. 質問で提案されたように、LAB色空間でこのCLAHEメソッドを実行すると RGBカラー画像にCLAHEを適用する方法 :

    import cv2, numpy as np
    bgr = cv2.imread('_example.jpg')
    lab = cv2.cvtColor(bgr, cv2.COLOR_BGR2LAB)
    lab_planes = cv2.split(lab)
    clahe = cv2.createCLAHE(clipLimit=2.0,tileGridSize=(100,100))
    lab_planes[0] = clahe.apply(lab_planes[0])
    lab = cv2.merge(lab_planes)
    bgr = cv2.cvtColor(lab, cv2.COLOR_LAB2BGR)
    cv2.imwrite('_example111.jpg', bgr)
    
    

    も悪い結果になりました。出力画像です。

  5. 適応的な閾値処理またはヒストグラム等化を行う 各チャンネルで個別に (R, G, B) は、カラーバランスを崩すので、オプションではありません。 ここで .

  6. コントラスト・ストリーチング。 メソッドと scikit-image のチュートリアルにある ヒストグラム均等化 :

    2%および98%に収まるすべての強度を含むように画像が再スケーリングされます。

    は少し良くなりましたが、まだ望ましい結果には程遠いです(この質問の上の画像を参照)。


TL;DR: OpenCV/Pythonで用紙のカラー写真の明るさ/コントラストの自動最適化を得るには? どのような閾値/ヒストグラム均等化/他の技術を使用することができますか?

どのように解決するのですか?

この方法は、あなたのアプリケーションでうまく機能するはずです。まず、強度ヒストグラムで分布モードをうまく分離する閾値を見つけ、その値を使用して強度を再スケールします。

from skimage.filters import threshold_yen
from skimage.exposure import rescale_intensity
from skimage.io import imread, imsave

img = imread('mY7ep.jpg')

yen_threshold = threshold_yen(img)
bright = rescale_intensity(img, (0, yen_threshold), (0, 255))

imsave('out.jpg', bright)

ここではYenのメソッドを使用しています。このメソッドについて詳しくは このページ .