web-dev-qa-db-ja.com

オーバーフローせずに画像の明るさを上げる

画像の明るさを上げようとすると問題が発生しました。

これがOriginの画像です:

enter image description here

私が手に入れたいと思った画像は次のようなものです:

enter image description here

次のコードで明るさを増やします。

    image = cv2.imread("/home/wni/vbshare/tmp/a4_index2.png",0)

    if sum(image[0])/len(image[0])<200:
        new = np.where((255-image)<image,255,image*2)
    else:
        new = image
    return new

そして、私は次の画像を得ました:

enter image description here

だから、いくつかの点の明るさがオーバーフローしたようです。

そして、しきい値を200から他の数値に変更しようとしました。 125、100、140など。ただし、画像の明るさはほぼ同じであるか、オーバーフローしています。

環境:

Python:2.7.10

Opencv:3.2.0

これについての提案はありがたいです。

ありがとう。

18
Wesley

これが、特定の画像をクリーンアップするための簡単なアルゴリズムでの私のショットです。自由に遊んで、さらに微調整して目的の結果を取得してください。

[〜#〜] nb [〜#〜]:示されているコードは、OpenCVの2.4.xブランチと3.xブランチの両方で機能するはずです。

ステップ0

入力画像をグレースケールとして読み込みます。

img = cv2.imread('paper.jpg',0)

ステップ1

テキストを取り除くために、画像を拡張します。この手順は、バーコードを保持するのに役立ちます。

dilated_img = cv2.dilate(img, np.ones((7,7), np.uint8)) 

Dilated

ステップ2

まともなサイズのカーネルで結果の中央値をぼかして、テキストをさらに抑制します。

これにより、すべての影や変色を含むかなり良い背景画像が得られます。

bg_img = cv2.medianBlur(dilated_img, 21)

Blurred

ステップ3

取得したオリジナルと背景の違いを計算します。同一のビットは黒(0の差に近い)、テキストは白(大きな差)になります。

白地に黒が必要なので、結果を逆にします。

diff_img = 255 - cv2.absdiff(img, bg_img)

Inverted Difference

ステップ4

画像を正規化して、ダイナミックレンジ全体を使用するようにします。

norm_img = diff_img.copy() # Needed for 3.x compatibility
cv2.normalize(diff_img, norm_img, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1)

Normalized

手順5

この時点ではまだ紙はやや灰色です。それを切り捨てて、画像を再正規化できます。

_, thr_img = cv2.threshold(norm_img, 230, 0, cv2.THRESH_TRUNC)
cv2.normalize(thr_img, thr_img, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1)

Gray Trimmed

完了...

まあ、少なくとも私にとっては;)あなたはおそらくそれをトリミングし、あなたが望む他の後処理を何でもしたいと思うでしょう。


注:繰り返される正規化での丸め誤差の蓄積を最小限に抑えるために、差分画像を取​​得した後、より高い精度(16ビットintまたはfloat)に切り替える価値があるかもしれません。

37
Dan Mašek

必要なのは thresholding です。これにより、非常に暗いものをすべて真っ白に設定し、非常に暗いものをまっすぐな黒(またはその他の色)に設定できます。これはあなたを始めるはずです:

cutoff_val = 100 # everything above this is set to set_color
set_color = 255 
ret,thresh_img = cv2.threshold(image,cutoff_val,set_color,cv2.THRESH_BINARY)

これをいじった後、 適応しきい値 を使用してより良い結果を得ることができます。

この素晴らしいチュートリアル 基本的にあなたが望むことを行う---そしておまけを参照してください。これには、紙の長方形の領域を取得するためのワーピングに関するチュートリアルも含まれています!

編集:しきい値処理と適応しきい値処理を組み合わせた画像でかなり良い結果が得られました。

cutoff_val = 150 # everything above this is set to the cutoff val
set_color = 255 # if 
ret,thresh_img = cv2.threshold(image,cutoff_val,set_color,cv2.THRESH_TRUNC)
window_sz = 3
thresh_img2 = cv2.adaptiveThreshold(thresh_img,set_color,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
            cv2.THRESH_BINARY,window_sz,2)
2
alkasm