LoginSignup
74
84

More than 5 years have passed since last update.

OpenCVを使って画像の射影変換をしてみるwithPython

Last updated at Posted at 2017-08-20

はじめに

OpenCVを使ったパターンマッチングで画像中の物体抽出 with Python

上記の記事を作成するにあたりOpenCVについて調べてみると、本当にいろいろなことができるみたいなので、とりあえず思いついたことを試してみることにしました。

...ということで、名刺をカメラで撮影した画像を正面から撮影したかのように補正する「射影変換」の手順を以下にまとめます。

動作環境

項目 内容
マシン MacBook Air (13-inch, Early 2015)
プロセッサ 2.2 GHz Intel Core i7
メモリ 8 GB 1600 MHz DDR3
Python 3.6.0 :: Anaconda 4.3.1 (x86_64)
Jupyter Notebook 4.2.1
OpenCV 3.3.0-rc

環境構築手順

いつもの手前味噌ですが、以下のURLをご参照下さい。

使用した写真

自分の名刺の裏側をiPhoneのカメラで撮影したものを使用します。(IMG_4778.JPG)

IMG_4778.jpg

ライブラリ読込

import cv2
import numpy as np

from IPython.display import display, Image

def display_cv_image(image, format='.png'):
    decoded_bytes = cv2.imencode(format, image)[1].tobytes()
    display(Image(data=decoded_bytes))

画像読込

img = cv2.imread("IMG_4778.JPG")
display_cv_image(img)

色の二値化と輪郭抽出

# グレイスケール化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 二値化
ret,th1 = cv2.threshold(gray,200,255,cv2.THRESH_BINARY)
display_cv_image(th1)

二値化した結果は以下のとおりです。

Unknown-1.png

# 輪郭抽出
image, contours, hierarchy = cv2.findContours(th1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 面積の大きいもののみ選別
areas = []
for cnt in contours:
    area = cv2.contourArea(cnt)
    if area > 10000:
        epsilon = 0.1*cv2.arcLength(cnt,True)
        approx = cv2.approxPolyDP(cnt,epsilon,True)
        areas.append(approx)

cv2.drawContours(img,areas,-1,(0,255,0),3)
display_cv_image(img)

正しく輪郭が抽出され、赤い枠で囲むことができました。

Unknown-2.png

射影変換

枠の各点を対応する座標にあわせて射影変換します。

img = cv2.imread("IMG_4778.JPG")

dst = []

pts1 = np.float32(areas[0])
pts2 = np.float32([[600,300],[600,0],[0,0],[0,300]])

M = cv2.getPerspectiveTransform(pts1,pts2)
dst = cv2.warpPerspective(img,M,(600,300))

display_cv_image(dst)

変換した結果は以下のとおり。

Unknown.png

できた!

おまけ

tesseract-ocrというライブラリを使用して、認識した名刺の文字をORCしてみました。

tesseract-oct

上述のソースコードに続けて以下のコードを追記します。

import pyocr
from PIL import Image
tools = pyocr.get_available_tools()
tool = tools[0]
print(tool.image_to_string(Image.fromarray(dst), lang="jpn"))

結果は...

〔保有賓格】
ヽ/寸 トゥェア開莞技術肴
惰報せ‡ュ‥ティ7ド
第三種電氣主任枝術者
乙穫鷺4顆危礦鞠取扱着
空手初段



二ス 卜 レ一タ

...改善の余地ありですね(汗)

74
84
3

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
74
84