みなさんこんにちは!
SNSを利用していると、様々なアイコン画像が欲しくなりますね。
写真、アバター、似顔絵など様々な画像がありますが、今回は線画を作ってみようと思います。
便利なライブラリが豊富なので、Pythonを使います
やりたいこと
カメラを通して線画の抽出をしたいので、以下の要件で進めます。
- カメラを起動する
- エッジを抽出して、線画を生成する
利用するライブラリ
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
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のカメラが起動します。
試しに本棚の方に向けてみました。
カメラを通して、線画が表示されます。
子供のおもちゃ用に買った箱の文字(Hello Kitty)も見えます。
今回のコードでは、10フレームごとに画像として保存します。
生成された画像
画像を見てみましょう。
まずは本棚の画像
カメラを通して見たものと同じ画像が保存されてました。
10フレームごとに保存しているので、生成された画像ごとに多少のばらつきがあります。
いいですね!人物もきちんと線画になっているようです。メガネもくっきりですね!
どちらの画像も、500KB前後でした。
まとめ
今回はOpenCVを利用して、線画を作ってみました。
OpenCV自体はJavaやC++でも利用できますが、個人的には、Pythonの方が実装は楽だと思います。
画像の学習にも利用されるようなので、これを機に、様々な画像が作れるようになりたいと思います!