LoginSignup
3
5

More than 3 years have passed since last update.

Python x OpenCVで透視補正

Last updated at Posted at 2019-09-02

Perspective Correction

昔のブログから出てきたので供養
透視補正:Perspective Correction 台形歪補正とも言う?
何に使えるかは微妙ですがしゅごい!と当時の私は興奮していました。
Photoshopで何ができるか知らないお子様だったのです。今もうっかり解約忘れという諸事情で契約中ですが全然使いこなせていません。
当時試したOCRの精度がいまいちだったので、歪み画像でもこれ使って補正掛けてからOCR通せばええんちゃう?レシート読めるんちゃう?とか思っていた気もしますがやってきた時代に殴り飛ばされました。

結果

Before

image1.jpg

補正をかける部分確認

スクリーンショット 2019-09-04 8.59.44.png

After

image2.jpg

HOW

事前準備

pip install numpy
pip install opencv-python
pip install pytesseract

コード

手動で補正したい部分の座標を入力していますが、四角形検出で自動的にいちばん大きいものの座標を取ってくるようにするとまたいい感じに使い勝手があるのかもしれません。
参考にしたStackOverflowのコードをPythonで書いてみた感じです。

perspective_correction.py
#! /usr/bin/env python
# -*- coding: utf-8 -*-

import numpy as np
import cv2
from PIL import Image
import pytesseract
import sys
import math

if __name__ == '__main__':

    ## 画像読み込み
    filename = 'traff3.jpg'
    img = cv2.imread(filename, cv2.IMREAD_COLOR)

    # 補正したい画像中の台形の四隅の座標
    # upper left
    Q1 = np.array([int(192), int(136)])
    # upper right
    Q2 = np.array([int(607), int(115)])
    # lower right
    Q3 = np.array([int(658), int(382)])
    # lower left
    Q4 = np.array([int(230), int(408)])

    ratio = 1.6
    # 補正後の長方形の高さと幅
    newRecHeihgt = int(math.sqrt((Q3[0]-Q2[0])*(Q3[0]-Q2[0]) + (Q3[1]-Q2[1])*(Q3[1]-Q2[1])))
    newRecWidth = int(ratio * newRecHeihgt)

    # 補正後の新しい四隅の座標
    R1 = Q1
    R2 = np.array([R1[0]+newRecWidth, R1[1]])
    R3 = np.array([R1[0]+newRecWidth, R1[1]+newRecHeihgt])
    R4 = np.array([R1[0], R1[1]+newRecHeihgt])

    # 補正後の長方形の形を赤線で表示
    rec = cv2.imread(filename, cv2.IMREAD_COLOR)
    cv2.rectangle(rec, (R1[0],R1[1]), (R3[0],R3[1]), (0, 0, 255), 3)
    cv2.imshow('rectangle', rec)
    cv2.waitKey()

    # それぞれの座標をnumpyのarrayへ
    src = np.array([Q1,Q2,Q3,Q4], np.float32)
    dst = np.array([R1,R2,R3,R4], np.float32)
    print(src)
    print(dst)

    # Perspective Correction
    # 透視変換の行列を求める
    transmtx = cv2.getPerspectiveTransform(src,dst)
    offsetSize = int(250)
    # 変換行列を用いて画像の透視変換
    warp = cv2.warpPerspective(img, transmtx, (newRecWidth+offsetSize, newRecHeihgt+offsetSize))

    # 変換後の画像表示
    cv2.imshow('warp', warp) 
    cv2.waitKey()

    # 画像を保存
    cv2.imwrite('warp.jpg', warp)

    cv2.waitKey(0)
    cv2.destroyAllWindows()   

thanks

Automatic perspective correction OpenCV

3
5
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
3
5