LoginSignup
8
3

みなさんこんにちは!

SNSを利用していると、様々なアイコン画像が欲しくなりますね。
写真、アバター、似顔絵など様々な画像がありますが、今回は線画を作ってみようと思います。

便利なライブラリが豊富なので、Pythonを使います:grinning:

やりたいこと

カメラを通して線画の抽出をしたいので、以下の要件で進めます。

  • カメラを起動する
  • エッジを抽出して、線画を生成する

利用するライブラリ

opencv-python

OpenCVはインテル社が開発・公開しているオープンソースのライブラリで、画像処理や画像解析、機械学習向けの機能が集約されています。

今回利用するライブラリは、これだけです。

環境構築

今回はpythonの仮想環境を使うので、venvを使います。
venvについての詳細はドキュメントを参照してください。

python -m venv simple_illustration
source simple_illustration/bin/activate
cd simple_illustration

lsコマンドで確認すると、以下のようになります。

$ ls
bin/		include/	lib/		pyvenv.cfg

これで仮想環境ができたので、必要なライブラリをインストールします。

pip install opencv-python

ここまでで環境構築は完了です。

実装

それでは、実装していきましょう。

vi sample.py
sample.py
import cv2

def line_drawing_image(img):
    # 画像のコントラストを調整
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    gray = cv2.equalizeHist(gray)

    # ガウシアンブラーを適用
    gray_blurred = cv2.GaussianBlur(gray, (5, 5), 0)
    
    # エッジ検出で線画を生成
    edges = cv2.adaptiveThreshold(gray_blurred, 255,
                                  cv2.ADAPTIVE_THRESH_MEAN_C,
                                  cv2.THRESH_BINARY, 11, 7)
    
    return edges

# OpenCV(cv2)でカメラデバイスに接続し、ビデオキャプチャを開始
cap = cv2.VideoCapture(0)

if not cap.isOpened():
    print("カメラが開けません。")
    exit()

frame_count = 0
saved_images = 0

# カメラがオープンしている間、または4枚の画像を保存するまでループ
while saved_images < 4:
    # フレームをキャプチャ
    ret, frame = cap.read()
    if not ret:
        print("フレームの取得に失敗しました。")
        break

    # 線画風の画像を生成
    line_drawing = line_drawing_image(frame)

    # 生成した画像を表示する
    cv2.imshow('Line Drawing Camera', line_drawing)

    # 10フレームごとに画像を保存
    if frame_count % 10 == 0:
        cv2.imwrite(f'line_drawing_{frame_count}.jpg', line_drawing)
        print(f'line_drawing_{frame_count}.jpg を保存しました。')
        saved_images += 1

    frame_count += 1

    # 'q'が押されたらループを抜ける
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# カメラをリリースしてウィンドウを閉じる
cap.release()
cv2.destroyAllWindows()

コードは非常にシンプルですね。
ライブラリのありがたみを感じます。

実行

それでは、実行してみましょう!

python sample.py

実行すると、PCのカメラが起動します。
試しに本棚の方に向けてみました。
スクリーンショット 2023-11-30 13.41.04.png

カメラを通して、線画が表示されます。
子供のおもちゃ用に買った箱の文字(Hello Kitty)も見えます。

今回のコードでは、10フレームごとに画像として保存します。

生成された画像

画像を見てみましょう。
まずは本棚の画像
line_drawing_10.jpg
カメラを通して見たものと同じ画像が保存されてました。
10フレームごとに保存しているので、生成された画像ごとに多少のばらつきがあります。

続いて人物。
私が写り込んでみました。
line_drawing_20.jpg

いいですね!人物もきちんと線画になっているようです。メガネもくっきりですね!

どちらの画像も、500KB前後でした。

まとめ

今回はOpenCVを利用して、線画を作ってみました。
OpenCV自体はJavaやC++でも利用できますが、個人的には、Pythonの方が実装は楽だと思います。

画像の学習にも利用されるようなので、これを機に、様々な画像が作れるようになりたいと思います!

8
3
1

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
8
3