OpenCVで複数の画像に一括で線を引いて、絵や写真の構図を効率的に分析する方法【Python】

プログラミング
当サイトの記事には、アフィリエイトリンクを含むものがあります。
アフィリエイトリンクは、ユーザー(あなた)がリンク経由で商品を購入すると、広告主などからサイトの運営者(わたし)に報酬が支払われる仕組みです。ユーザー側(あなた)に金銭的な利益や損失は発生しません。
リンク先の商品はわたしが実際に「良い」と思ったものであり、当サイトの記事の内容は広告主からの影響を受けていません。
何かご不明な点がございましたら、お手数をおかけしますがContactページよりお知らせください。

 

OpenCVで複数の画像に一括で線を引いて、絵や写真の構図を効率的に分析する方法」の忘備録です。

構図は補助線を引くと分かりやすい

構図」は、絵や写真の”良さ“に大きく関わる要素です。

たとえば、構図には

  • 三分割構図:画面を縦と横に3分割し、その交点に被写体を配置する構図。バランスが良くなる。
  • 日の丸構図:被写体を中心に据えた構図。分かりやすく、安定感が出る。
  • 対角線構図:被写体を画面の対角線上に配置する構図。画に躍動感が出る。

など様々な種類(他にも色々あります)と、期待される効果があります。

つまり、適切な「構図」を選択すると、作品の説得力が増すわけです。

 

たとえば、こちらの写真。

補助線を引いてみます。↓

だいたい、上部1/3暗めの空真ん中1/3下部1/3夕焼けになっています。
また、左上の交点が配置されていると分かります。

もうひとつ、こちらの写真。

補助線を引いてみます。↓

下の線に、湖と山との境界が重なっています。

どちらも「ある程度バランスの良い写真になっているのではないか」と思います。

そして、補助線があると「構図」が分かりやすいですよね。

 

――僕は、思いました。

他の人の作品にも手軽に補助線を引けたら、簡単に構図の分析がでるのにな…。

…でも、いちいちPhotoshopとかを使うのも面倒だなぁ…。

そうだ!Pythonにやらせよう!

ということで、複数の画像に一括で補助線を引くPythonのスクリプトを書いてみました。

具体的なやり方

Pythonをインストールする。

お使いのコンピューターにPythonがインストールされていない方は、インストールします。

Welcome to Python.org
The official home of the Python Programming Language

OpenCVをインストールする。

画像や動画を処理するためのライブラリである「OpenCV」をインストールします。

OpenCV: OpenCV Tutorials

以下のpipコマンドでインストールできるはずです。

pip install opencv-python
pip install opencv-contrib-python

プロジェクトフォルダを作る

以下の構成のフォルダを作ります。

adding_grid_lines
     ├ after_treatment ←変換した画像ファイルが出力されるフォルダ
     ├ image ←変換したい画像を入れるフォルダ
     │
     └ adding_grid_lines.py ←Pythonの実行ファイル

adding_grid_lines」の中身がこんな感じになるイメージです。

コード

adding_grid_lines.py」の中身です。

色々な書き方があると思いますけど…僕はこんな感じで書きました。

※パス(ファイルの位置)周りの記述は、ご自身の環境に合わせて書き換えてください。

# ライブラリをインポート
import cv2
import glob

# 画像の分割数を指定
division_number = 3
# 線の色(BGR値)を指定
color = (255, 255, 255)

# for文でimageフォルダ内にある全ての画像のパスを取得して処理していく。
for image_path in glob.glob('任意のパスを入力/image/*'):

    # 画像をオブジェクト「img」に代入
    img = cv2.imread(image_path)

    # 画像のサイズを取得
    height, width = img.shape[:2]
    y_step = int(height/division_number)  # 縦方向の線の間隔を決める
    x_step = int(width/division_number)  # 横方向の線の間隔を決める

    # ndarrayのスライシングで横線を引く。(始点:終点:間隔)= 線の色
    img[y_step:height:y_step, :, :] = color
    img[:, x_step:width:x_step, :] = color

    # 斜め線を引く。(対象オブジェクト,始点,終点,線の色,線の太さ)
    cv2.line(img, (0, 0), (width, height), color, 1)
    cv2.line(img, (width, 0), (0, height), color, 1)

    # 線を加えた画像を新しいファイル名で書き出す。
    export_name = image_path.replace('/image\\', '/after_treatment/GridLine_')
    cv2.imwrite(export_name, img)

分析したい画像を「image」フォルダの中に入れて「adding_grid_lines.py」を実行すれば、「after_treatment」フォルダの中に、線が加えられた画像が一気に書き出されるはずです。

線の色の設定などは適宜、変えてみてください。

結果: いくつか具体例を紹介

今月から、スタジオジブリ作品の場面写真の提供を開始します - スタジオジブリ|STUDIO GHIBLI
今月から、スタジオジブリ作品の場面写真の提供を開始します。 今月からスタジオジブリ全作品の場面写真を順次提供することになりました。今月は、新しい作品を中心に 8作品、合計400枚提供します。 常識の範囲でご自由にお使いください。 思い出のマ...

スタジオジブリが、作品の場面写真を「常識の範囲でご自由にお使いください。」と公開してくれているので、例として使わせていただきます。

©STUDIO GHIBLI Inc. – 千と千尋の神隠し

4人(?)のメインキャラクターが、真ん中の長方形に収まるよう配置されています。
また、座席と背もたれとの境界下の線と重なっていますね。

©STUDIO GHIBLI Inc. – 天空の城ラピュタ

シータ(寝ている方の人間)体幹が、ほぼ下の線と重なっていますね。
また、スカートのなびき方対角線を意識している気がします。

©STUDIO GHIBLI Inc. – 魔女の宅急便

キキ(リボンをつけた人間)が、真ん中の三角形の中にキレイに収まっているのが分かります。

他にも、カウンターの高さがほぼ下の線と重なっていたり、パン棚の仕切り右側の線とが重なっていたりしますね。

さいごに

やはり、印象に残る作品の「構図」には、色々な工夫があるようです。

もちろん、僕が気づいていないだけで他にも色々な意図が込められているのでしょう。

とにかく、今まで自分が「良いな」と思って保存していた絵や写真の画像数百枚に、ものの数秒で構図分析用の補助線を引けたので、新しい発見がたくさんありました!

参考にさせていただいたページ

PythonにおけるOpenCVのインストール方法について現役エンジニアが解説【初心者向け】 | TechAcademyマガジン
初心者向けにPythonにおけるOpenCVのインストール方法について現役エンジニアが解説しています。OpenCVとは、動画や画像を処理するのに必要な機能が実装されたライブラリで、画像処理や機械学習に使います。pipによるopencv-py...
Python, OpenCVで画像ファイルの読み込み、保存(imread, imwrite) | note.nkmk.me
PythonのOpenCVで画像ファイルを読み込み・保存するにはcv2.imread(), cv2.imwrite()を使う。NumPy配列ndarrayとして読み込まれ、ndarrayを画像として保存する。 ここでは、以下の内容について説...
タイトルとURLをコピーしました