LoginSignup
14
13

More than 5 years have passed since last update.

OpenCVでかすんでる文字をクッキリさせる方法

Posted at

光学文字識別(OCR)を実装する際、ソース画像の文字がかすんでると識別精度が著しく落ちてしまう事がよく見られる。今回かすんでる文字のサンプルを使って、OpenCVで色々な画像処理アルゴリズムを試してみました。

ソースコードが下記になります:

import cv2, os
import urllib.request as url
import numpy as np
from matplotlib import pyplot as plt

def main():
    # Load sample image from URL
    req = url.urlopen('https://i.pinimg.com/originals/d3/1b/31/d31b31653d7cc0d672fc72fb1de9bf7a.png')
    arr = np.asarray(bytearray(req.read()), dtype=np.uint8)
    img = cv2.imdecode(arr, -1) # 'Load it as it is'
    h, w, ch = img.shape

    print('Width: {}'.format(w))
    print('Height: {}'.format(h))
    print('Channel: {}'.format(ch))


    # If reading local image, use below:
    # img = cv2.imread('local_image.jpg')

    #### (1) Effect - Gamma Adjustment ####

    # Convert from RGB to gray scale
    gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
    gamma = 0.4 # r<1 will increase bright contrast ratio

    # Gamma adjustment
    pic1 = gray.max() * (gray/gray.max()) ** (1/gamma)
    cv2.imwrite(os.path.join('output_image','1_gamma_adjusted.png'), pic1)

    #### (2) Effect - Adaptive Binary Thresholding ####
    pic2 = cv2.adaptiveThreshold(gray,20,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,67,2)
    cv2.imwrite(os.path.join('output_image','2_binary_thresholding.png'), pic2)

    pic3 = cv2.adaptiveThreshold(gray,20,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,33,2)
    cv2.imwrite(os.path.join('output_image','3_binary_thresholding_gaussian.png'), pic3)

    #### (3) Effect - Laplacian Filter ####
    pic4 = cv2.Laplacian(gray,cv2.CV_16SC1, ksize=29)
    cv2.imwrite(os.path.join('output_image','4_laplacian_filter.png'), pic4)

    ### Plot results
    titles = ['Original (Blurry Word)', 'Gamma Adjusted (r=0.4)','Adaptive Mean Thresholding (blocksize=67)', 
                'Adaptive Gaussian Thresholding', 'Laplacian (kernel size=29)']
    images = [img, pic1, pic2, pic3, pic4]

    for i in range(len(images)):
        plt.subplot(-(-len(images)//2),2,i+1),plt.imshow(images[i],'gray')
        plt.title(titles[i])
        plt.xticks([]),plt.yticks([])
    plt.show()

if __name__ == '__main__':
    main()

[Python 3.5+で実行]

実行すると、左上のオリジナル画像と変換処理した結果が表示されます。

image.png

パラメータの調整は試行錯誤とある程度の経験にもよりますが、シンプルなコードで割とオーライな結果だと思います。

14
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
13