2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

OpenCVでレシート画像を切り抜き (射影変換)その2

Last updated at Posted at 2022-03-14

目的

  • レシートと背景が写った写真からレシートをくりぬきたい
  • OpenCVの理解
  • なんか画像処理っぽいことしたい

前回のあらすじ

写真の中からレシート部分を認識。線で囲う、まで行った。
今回は射影変換をやってみたいと思いました。

環境

  • Windows11 Home
  • VSCode
  • Python3.9
  • pip
    opencv-python 4.5.5.62

本編

射影変換をやってみたいと思いました。
参考:

輪郭抽出から

前回の輪郭抽出の結果はこんな感じ

20220303_084409.jpg3.jpg

射影変換

これを射影変換します。


    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))
    save_image(filename+"4", dst)

なんか90度回転してしまいました。

20220303_084409.jpg4.jpg

頂点はどのように出てくるのだろうと思い printしてみました。

print(areas[0])

輪郭抽出の頂点ですがどうやら
 右上→左上→左下→右下
となっているようです。
多分一筆書きで方向は順不同?

で、設定した射影側の頂点は
 右下→左下→左上→右上
なのでヘンテコになるのはそりゃそうですね。

[[[1947  348]]

 [[ 856  360]]

 [[ 853 3849]]

 [[1961 3790]]]

改善点

これを踏まえて以下の改善を行う。

  • 輪郭抽出の頂点をソートし頂点の固定化
     レシート画像なので縦位置で縦長レシートと仮定する。
  • 縦横の比率をもとのレシートになるだけ合わせる。

ちょっと冗長なプログラムになってしまいましたが何とかなりました。

    # 重心を求める
    cx=cy=0
    for i in areas[0]:
        cx += i[0][0]
        cy += i[0][1]
    cx /=len(areas[0])
    cy /=len(areas[0])

    # 切り取り画像サイズを求める
    h=w=0
    for i in areas[0]:
        if i[0][0]>cx :
            w +=i[0][0]
        else:
            w -=i[0][0]
        #右側
        if i[0][1]>cy:
            #右下
            h += i[0][1]
        else:
            #右上
            h -= i[0][1]

    # 点の順番を求める tmp
    tmp = []
    for i in areas[0]:
        if i[0][0]>cx :
            #右側
            if i[0][1]>cy:
                #右下
                tmp.append([w,h])
            else:
                #右上
                tmp.append([w,0])
        else:
            #左側
            if i[0][1]>cy:
                #左下
                tmp.append([0,h])
            else:
                #左上
                tmp.append([0,0])
    # 射影変換
    dst = []
    pts1 = np.float32(areas[0])
    pts2 = np.float32([tmp])

    M = cv2.getPerspectiveTransform(pts1,pts2)
    dst = cv2.warpPerspective(img,M,(w,h))
    save_image(filename+"4", dst)

改良―射影変換の結果

これが
20220303_084409.jpg3.jpg

こういう風に
20220303_084409.jpg4.jpg

これも
20170104_090657.jpg3.jpg
こうなりました
20170104_090657.jpg4.jpg

2
2
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
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?