はじめに
opencvのライブラリに用意されている非写実的レンダリング(ノンフォトリアリスティックレンダリング:以下NPR)を試してみました。
NPRは入力された画像や映像に対して手書きの絵画のような非写実的表現を目指します。下記で実際の変換結果を参考にイメージしてください。
こちらのサイトを参考に実装しました。
OpenCV Non-Photorealistic Rendering
Learn OpenCV
結果
先にNPRの実行結果を載せておきます。
入力はこちらの雪桜
NPR変換結果
※opencvのNPRは4種類あります。
edgePreservingFilter
detailEnhance
pencilSketch
stylization
実装
以下、Pythonのコードです。
NPR.py
import cv2
import argparse
from PIL import Image
def NPR(src):
epf = cv2.edgePreservingFilter(src, flags=1, sigma_s=60, sigma_r=0.4)
de = cv2.detailEnhance(src, sigma_s=10, sigma_r=0.15)
pen_gray, pen_col = cv2.pencilSketch(src, sigma_s=60, sigma_r=0.1, shade_factor=0.03)
style = cv2.stylization(src, sigma_s=60, sigma_r=0.07)
return epf, de, pen_col, style
def webcam_or_pic2npr(out,is_webcam,pic):
if is_webcam:
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
e,d,p,s = NPR(frame)
cv2.imshow('raw_input', frame)
cv2.imshow('edgePreservingFilter',e)
cv2.imshow('detailEnhance',d)
cv2.imshow('pencilSketch',p)
cv2.imshow('stylization',s)
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
elif key == ord('s'):
cv2.imwrite(out,frame)
cv2.imwrite(out,p)
cap.release()
cv2.destroyAllWindows()
else:
img = cv2.imread(pic, cv2.IMREAD_COLOR)
e,d,p,s = NPR(img)
cv2.imwrite(str(out)+'edgePreservingFilter.png',e)
cv2.imwrite(str(out)+'detailEnhance.png',d)
cv2.imwrite(str(out)+'pencilSketch.png',p)
cv2.imwrite(str(out)+'stylization.png',s)
def main():
parser = argparse.ArgumentParser(description='python+opencv_npr')
parser.add_argument('--in_pic','-i',default='sample.png',help='input_picture_name')
parser.add_argument('--out','-o',default='./',help='output_dir')
parser.add_argument('--is_webcam',action='store_true',help='use webwebcam_or_pic2npr')
args = parser.parse_args()
webcam_or_pic2npr(args.out, args.is_webcam, args.in_pic)
if __name__ == "__main__":
main()
実行コマンド(入力=画像)
python NPR.py -i picture_name -o output_dir
実行コマンド(入力=webカメラ)
python NPR.py --is_webcam
所感
pythonとopencvで簡易に実装できます。
ライブラリ4種類のロジックの詳細は時間があれば追加記述します。
色々試していただくと画像が鮮鋭になったりボケたりしていることが分かるかと思います。
まとめ
python + opencvで非写実的レンダリング4種類を試してみました。
ぜひ、手元の画像でお試しください。
ご一読ありがとうございました。
ソースコードの不正等、ご指摘あればよろしくお願いします。
LGTMも大歓迎です!