Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

はじめに

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顆危礦鞠取扱着
空手初段



二ス 卜 レ一タ

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

mix_dvd
ExcelのマクロやWebアプリケーション、iOSアプリを作っています。 また、しまねソフト研究開発センター専門研究員の業務を受託しています。http://www.s-itoc.jp
http://blueomega.jp
s-itoc
しまねソフト研究開発センター(ITOC)はITを活用する企業の支援と研究開発の拠点です。
http://www.s-itoc.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした