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



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

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

![GridLine_chihiro042-1024x554.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486558/e4c45aa1-bfe8-f732-820b-48824b4bdcc6.jpeg)

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

たとえば、構図には

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

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

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

　


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

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486558/5ab11143-14a9-ffdc-f4e8-853b9f71a0d5.jpeg" width="380">

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

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486558/3544508d-c66d-0404-0720-c50b1531ae87.jpeg" width="380">

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

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

![DSC05897-1-768x432.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486558/2ebfed95-ef93-f23f-72bf-05e2b6eefd6d.jpeg)

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

![GridLine_DSC05897-768x432.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486558/824ac347-7e9b-270c-e24c-c1cc762ecfe7.jpeg)

**下の線**に、**湖と山との境界**が重なっています。
どちらも「ある程度バランスの良い写真になっているのではないか」と思います。

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

　

――僕は、思いました。

他の人の作品にも手軽に補助線を引けたら、簡単に構図の分析がでるのにな…。
…でも、いちいちPhotoshopとかを使うのも面倒だなぁ…。

…**そうだ！Pythonにやらせよう！**

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


##具体的なやり方
### **Python**をインストールする。

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

https://www.python.org/

### **OpenCV**をインストールする。

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

https://docs.opencv.org/master/d9/df8/tutorial_root.html

以下の**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.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486558/f4381360-70f7-4120-03d0-757ce3845315.png)

###コード

「**adding_grid_lines.py**」の中身です。

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

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

```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**」フォルダの中に、線が加えられた画像が一気に書き出されるはずです。

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

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

https://www.ghibli.jp/info/013344/

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

![GridLine_chihiro042-1024x554.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486558/e4c45aa1-bfe8-f732-820b-48824b4bdcc6.jpeg)

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

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

![GridLine_laputa003-1024x554.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486558/854bd52b-0dea-56ba-6128-5e16225557d5.jpeg)

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

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

![GridLine_majo.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486558/459a0fa2-24ef-89a5-1853-ae5513c94c16.jpeg)

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

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

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

##さいごに

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

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

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

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

https://tat-pytone.hatenablog.com/entry/2019/03/28/233413

https://techacademy.jp/magazine/51404

https://note.nkmk.me/python-opencv-imread-imwrite/