1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Python × OpenCV で画像中心から16方位などの線を放射状に描画するツールを作った

Posted at

概要

指定ディレクトリ内の画像ファイルに対して、画像の中心点を起点に放射状の直線(4, 8, 16方位)を描画するPythonツール。

  • OpenCVで線を描画
  • サブディレクトリも再帰的に処理可能
  • 出力先は元の構造を保ったまま別フォルダに保存
  • ラベル(N, NE, …)の表示もオプションで可能
  • ファイル名には _drawn{方向数} のサフィックスを付加

フォルダ構成例

input_images/
├── a.jpg
└── sub/
    └── b.png

→ 実行後:

output_images/
├── a_drawn8.jpg
└── sub/
    └── b_drawn8.png

Pythonスクリプト:draw_dirs.py

import cv2
import numpy as np
import math
import argparse
from pathlib import Path

DIRECTION_LABELS = {
    4:  ['E', 'N', 'W', 'S'],
    8:  ['E', 'NE', 'N', 'NW', 'W', 'SW', 'S', 'SE'],
    16: ['E', 'ENE', 'NE', 'NNE', 'N', 'NNW', 'NW', 'WNW',
         'W', 'WSW', 'SW', 'SSW', 'S', 'SSE', 'SE', 'ESE']
}

def draw_directions(img, n_directions=16, thickness=2, with_label=False):
    height, width = img.shape[:2]
    center_x, center_y = width // 2, height // 2
    length = int(np.hypot(width, height))
    color = (0, 0, 255)
    angle_step = 360 / n_directions
    font = cv2.FONT_HERSHEY_SIMPLEX
    font_scale = 0.6
    font_thickness = 1

    for i in range(n_directions):
        theta_deg = i * angle_step
        theta_rad = math.radians(theta_deg)
        dx = int(length * math.cos(theta_rad))
        dy = int(length * math.sin(theta_rad))
        x1, y1 = center_x - dx, center_y - dy
        x2, y2 = center_x + dx, center_y + dy
        cv2.line(img, (x1, y1), (x2, y2), color, thickness)
        if with_label:
            label = DIRECTION_LABELS[n_directions][i]
            label_offset = 30
            lx = int(center_x + (length + label_offset) * math.cos(theta_rad))
            ly = int(center_y + (length + label_offset) * math.sin(theta_rad))
            cv2.putText(img, label, (lx, ly), font, font_scale, color, font_thickness, cv2.LINE_AA)
    return img

def is_image_file(filename):
    return filename.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp', '.tif', '.tiff'))

def process_directory(input_dir, output_dir, n_directions=16, thickness=2, with_label=False):
    input_dir = Path(input_dir)
    output_dir = Path(output_dir)
    for img_path in input_dir.rglob("*"):
        if img_path.is_file() and is_image_file(img_path.name):
            img = cv2.imread(str(img_path))
            if img is None:
                print(f"読み込み失敗: {img_path}")
                continue
            processed = draw_directions(img, n_directions, thickness, with_label)
            rel_path = img_path.relative_to(input_dir)
            stem = rel_path.stem
            suffix = rel_path.suffix
            parent = rel_path.parent
            new_name = f"{stem}_drawn{n_directions}{suffix}"
            out_path = output_dir / parent / new_name
            out_path.parent.mkdir(parents=True, exist_ok=True)
            cv2.imwrite(str(out_path), processed)
            print(f"保存: {out_path}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="画像中心から放射状に線を描画します(再帰対応)")
    parser.add_argument("input_dir", help="入力ディレクトリ")
    parser.add_argument("output_dir", help="出力ディレクトリ")
    parser.add_argument("-d", "--directions", type=int, choices=[4, 8, 16], default=16,
                        help="線の本数(4, 8, 16 のいずれか)")
    parser.add_argument("-t", "--thickness", type=int, default=2,
                        help="線の太さ(ピクセル)")
    parser.add_argument("-l", "--label", action="store_true",
                        help="各方位にラベルを表示する(例:N, NEなど)")
    args = parser.parse_args()
    process_directory(args.input_dir, args.output_dir, args.directions, args.thickness, args.label)

実行方法

python3 draw_dirs.py ./input_images ./output_images -d 8 -t 2 -l
オプション 意味
-d または --directions 描画する線の本数(4, 8, 16)
-t または --thickness 線の太さ(ピクセル)
-l または --label 方位ラベル(N, NE, など)を表示する

必要なライブラリ

pip install opencv-python numpy

補足

  • ファイル名には自動的に _drawn{方位数} が追加される(例:sample.jpgsample_drawn16.jpg
  • 出力フォルダには、入力と同じディレクトリ構造が再現される

メモ

画像中心から放射状に線を描く処理を簡単に済ませたくて書いたスクリプト。
サブフォルダ対応、ファイル名自動命名、ラベル表示も一応入れた。
備忘録です。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?