質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.60%

opencvを使って画像の切り抜き

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 4,242

yosutebito092

score 14

イメージ説明
例えばこういう小説の文章ページがあって、これの余白の部分だけを切り抜く方法ってないですか?
白い文字の部分だけを避けて下のいわゆる余白であるはずの黒い部分の画像を切り抜きたいです。ついでに文字の上の部分も切り取ってなくしたいです。
ちなみにこれは二値化した画像です。元の画像は普通の小説のページです。
これ見開きなんで片側のページだけでも大丈夫です。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • can110

    2018/11/10 08:22

    提示された画像は実際に処理する画像ですか?小さく、また2値画像ではなくグレイスケール画像に見えます。また、上部には罫線?下部には罫線+ひし形の背景画像がありますが。

    キャンセル

回答 1

checkベストアンサー

0

より単純な画像での処理コードを書いてみました。

  • findContoursで文字の輪郭を抽出
  • 文字の輪郭群を含む外接矩形を算出
  • 外接矩形で切り抜き

しています。

なお、実際の提示画像には罫線や背景画像がふくまれているようですので、それらを除去する前、中間処理が必要になってくるかと思います。

import cv2

# 輪郭に外接する矩形を返す
def get_bounding_rect(img,cnt,rc): # 画像,輪郭,初期矩形
    l,t,r,b = rc[0][0],rc[0][1],rc[1][0],rc[1][1]
    for pt in cnt:
        x,y = pt[0][0],pt[0][1]
        if x < l: l = x
        if y < t: t = y
        if x > r: r = x
        if y > b: b = y
    return [(l,t),(r,b)]

def main():
    img_src = cv2.imread('src.png')

    # 処理対象をモノクロ画像に
    img_bin = cv2.cvtColor(img_src, cv2.COLOR_BGR2GRAY)
    _,img_bin = cv2.threshold(img_bin, 100, 255, cv2.THRESH_BINARY)

    # 輪郭抽出
    _,cnts,_ = cv2.findContours(img_bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # 全文字を含む外接図形
    import copy
    rc0 = [[img_bin.shape[1],img_bin.shape[0]],[-1,-1]] # 初期矩形
    rect_img = copy.deepcopy(rc0)

    for cnt in cnts:    # cnt =文字毎の輪郭
        # 外接矩形を求める
        rect_img = get_bounding_rect(img_bin,cnt,rect_img)           # 全文字を含む
        rect_cnt = get_bounding_rect(img_bin,cnt,copy.deepcopy(rc0)) # 文字毎 ※チェック用

        cv2.rectangle(img_src, rect_cnt[0], rect_cnt[1], (255,0,0), thickness=1, lineType=cv2.LINE_4) # 文字毎。青

    cv2.rectangle(img_src, rect_img[0], rect_img[1], (0,0,255), thickness=1, lineType=cv2.LINE_4) # 全文字を含む。赤

    img_crop = img_bin[rect_img[0][1]:rect_img[1][1],rect_img[0][0]:rect_img[1][0]] # 抽出領域

    cv2.imwrite('check.png', img_src)
    cv2.imwrite('dst.png',img_crop)

if __name__ == "__main__":
    main()

元画像
イメージ説明
結果確認
イメージ説明
クロップ後
イメージ説明

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.60%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る