1. aki0141

    Posted

    aki0141
Changes in title
+[Python, OpenCV]動画から検出した円をぴえんに変換する
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,103 @@
+ぴえんという顔文字をご存じでしょうか。
+2019年ぐらいからJKやJCの間で流行りはじめた顔文字で、2020年には上半期のインスタ流行語大賞に選ばれたらしいです。
+実際に見てもらった方が早いですね。
+
+<img width="110" alt="002・pien.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668610/e2fa378e-2bb0-e35d-d75f-767a49fc0915.png">
+
+いつからか誰かがこの顔文字と一緒に「ぴえん」という単語を使い始めて、それが定着してこの顔文字自体がぴえんと呼ばれるようになった・・・らしいです。
+
+なんというかカルト的な人気を博したこのぴえん🥺ですが、この顔をした八頭身に追いかけられるようなゲームが出たり、「ぴえんこえてぱおん」というまた新しいよくわからない単語が登場したりしています。
+
+さて、今回はこのぴえんをPythonとOpenCVを使ってカメラの映像に表示したいと思います。
+まだどちらも触って1,2ヶ月程度なのでおかしな部分があるかもしれませんが、よろしくお願いします。
+
+#開発環境
+- macOS Catalina(使っているのはMacBookPro Mid 2014)
+- Python 3.7.7
+- numpy 1.18.5
+- OpenCV 3.4.2
+
+Anacondaで仮想環境を作成しています。
+カメラはeMeetのNovaを使っています。
+
+#ソース
+```python:pien.py
+# -*- coding: utf-8 -*-
+import cv2
+import numpy as np
+
+#カメラの取得
+cap = cv2.VideoCapture(1)
+
+while True:
+ ret, frame = cap.read()
+ #ハフ変換用にリサイズし、グレーカラーに変更
+ frame = cv2.resize(frame, dsize=(640, 480))
+ gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)
+ gray = cv2.GaussianBlur(gray, (33, 33), 1)
+
+ #ハフ変換による円形の抽出
+ circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 60, param1=10, param2=85, minRadius=1, maxRadius=80)
+
+ #変換結果がある場合にぴえんの描写を行う
+ if circles is not None:
+ circles = np.uint16(np.around(circles))
+ for i in circles[0,:]:
+ #i[0]=x座標 i[1]=y座標 i[2]=半径
+ x = i[0]; y = i[1]; r = i[2]
+ #cv2.circleは円形 cv2.ellipseは楕円や楕円弧
+ #輪郭
+ cv2.circle(frame, (x, y), r, (0, 215, 255), -1)
+ #眉毛右
+ cv2.ellipse(frame, (x+int(r*2/3), y-int(r*2/3)), (int(r/3), int(r/4)), 0, 90, 165, (19, 69, 139), 3)
+ #眉毛左
+ cv2.ellipse(frame, (x-int(r*2/3), y-int(r*2/3)), (int(r/3), int(r/4)), 0, 15, 90, (19, 69, 139), 3)
+ #涙右
+ cv2.circle(frame, (x+int(r*2/5), y), int(r*3/10), (255, 255, 255), -1)
+ #涙左
+ cv2.circle(frame, (x-int(r*2/5), y), int(r*3/10), (255, 255, 255), -1)
+ #黒目右
+ cv2.circle(frame, (x+int(r*2/5), y-int(r/15)), int(r*3/10), (0, 0, 0), -1)
+ #黒目左
+ cv2.circle(frame, (x-int(r*2/5), y-int(r/15)), int(r*3/10), (0, 0, 0), -1)
+ #白目大右
+ cv2.ellipse(frame, ((x+int(r/3), y-int(r/6)), (int(r/3), int(r/4)), 135), (255, 255, 255), -1)
+ #白目大左
+ cv2.ellipse(frame, ((x-int(r/2), y-int(r/6)), (int(r/3), int(r/4)), 135), (255, 255, 255), -1)
+ #白目小右
+ cv2.ellipse(frame, ((x+int(r/2), y), (int(r/10), int(r/15)), 135), (255, 255, 255), -1)
+ #白目小左
+ cv2.ellipse(frame, ((x-int(r/3), y), (int(r/10), int(r/15)), 135), (255, 255, 255), -1)
+ #口
+ cv2.ellipse(frame, (x, y+r), (int(r/4), int(r/2)), 0, 245, 295, (19, 69, 139), 5)
+
+ #ウィンドウにカメラの映像を表示 この時点でframeにはぴえんが描写されている
+ cv2.imshow("frame", frame)
+
+ #qキーを押したら終了する
+ if cv2.waitKey(1)&0xff == ord("q"):
+ break
+
+cap.release()
+cv2.destroyAllWindows()
+```
+コードの説明はそのままコメントで残しました。
+重要なのは中程のハフ変換による円形の検出部分と、検出した円の座標・半径をもとにぴえんを作成する部分です。
+ぴえんは画像を貼り付けているわけではなく、全て円と線で描画しているので、どんな大きさにも対応できるようになっています。
+文字列も描写できるので🥺をそのまま使えないかと思ったのですがダメでした。
+
+#やってみた結果
+仮想環境をconda activateした上でpien.pyを実行すると、カメラからの映像がウィンドウで表示されるかと思います。
+そこでカメラを丸いものに向けてみましょう。
+
+![001・pien.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668610/057d52ce-cf41-2a27-249e-3d36353c74f0.gif)
+
+ぴえんになりました🥺
+しっかり大きさが違ってもそれに合わせて変換されていますね。
+今回は円を検出指定いるので、円の中に何が入っているかは特に関係ありません。時計でもキャップでもメガネでもぴえんになります。
+コードを丸くすればそれもぴえんになります。
+ちなみに瞳もぴえんになりました。(🥺ω🥺)みたいな感じです。
+
+OpenCVを使えば円だけでなく例えば人の顔も検出できます。
+つまりカメラに移った顔を全て🥺にすることができるということです。
+そこら辺はそのうち試してみたいと思います。