としおの読書生活

田舎に住む社会人の読書記録を綴ります。 主に小説や新書の内容紹介と感想を書きます。 読書の他にもワイン、紅茶、パソコン関係などの趣味を詰め込んだブログにしたいです。

タグ:python

本記事ではVSCodeでターミナル起動時に自動的にconda activateを行う方法を紹介していきます。




ターミナル起動時にconda activateさせる


VSCodeを起動して左下にある歯車アイコン→設定の順でクリックしていきます。

キャプチャ

キャプチャ2

設定画面が開けたらユーザの検索ボックスにterminal.integrated.profiles.windowsと入力して検索を行います。

見つかったらsetting.jsonで編集をクリックします。

キャプチャ

Command Promptのargsを以下のように設定してください。

Anaconda3までのパスは各自の環境によって合わせましょう。

"terminal.integrated.profiles.windows": {

        "PowerShell": {
            "source""PowerShell",
            "icon""terminal-powershell",
        },
        "Command Prompt": {
            "path": [
                "${env:windir}\\Sysnative\\cmd.exe",
                "${env:windir}\\System32\\cmd.exe"
            ],
            "args": [
                "/K",
                "~\\Anaconda3\\Scripts\\activate.bat",
                "\\Anaconda3"
            ],
            "icon""terminal-cmd"
        },
        "Git Bash": {
            "source""Git Bash"
        }
    },

書き換えれたら、settings.jsonを保存してVSCodeを再起動します。

これでPythonコードを開いている状態で新しいターミナルを起動すれば自動的にActivateされるようになります。





4267000_s

自然言語処理関連のソフトを作る機会があり、最近のメジャーな日本語自然言語処理ライブラリとしてGiNZAというものがあるという話を聞いたので試しに使ってみました。


GiNZAとは


GiNZAとはリクルートが国立国語研究所との共同研究成果をもとに開発した日本語自然言語処理ライブ来です。

形態素解析器であるSudachiPyと機械学習部分であるspaCyを合わせたライブラリのようです。

特徴は従来のspaCyは日本語に対してはMeCabをバックエンドに形態素解析ができる程度でした。

しかし。GiNZAの登場により最先端の機械学習技術を用いた日本語自然言語処理が簡単にできるようになったようです。



GiNZAのインストール


今回は2021年9月現在GiNZAの最新バージョンであるGiNZA v5.0をインストールしていきます。

GiNZA v5はインストール時に解析モデルのパッケージを指定する必要があるようで、解析度重視の場合は以下のコマンドでインストールしましょう。

pip install -U ginza ja-ginza-electra

速度重視の場合は以下のコマンドでインストールしてください。

pip install -U ginza ja-ginza

両方使い分けたい場合は、両コマンドとも実行してください。

インストールができたら動作を確認してみましょう。

ginza
すもももももももものうち。

# text = すもももももももものうち。
1       すもも  すもも  NOUN    名詞-普通名詞-一般      _       3       nsubj   _       SpaceAfter=No|BunsetuBILabel=B|BunsetuPositionType=SEM_HEAD|NP_B|Reading=スモモ|NE=B-OTHERS|ENE=B-Flora
2       も      も      ADP     助詞-係助詞     _       1       case    _       SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=SYN_HEAD|Reading=モ
3       もも    もも    NOUN    名詞-普通名詞-一般      _       5       nsubj   _       SpaceAfter=No|BunsetuBILabel=B|BunsetuPositionType=SEM_HEAD|NP_B|Reading=モモ|NE=B-OTHERS|ENE=B-Animal_Part
4       も      も      ADP     助詞-係助詞     _       3       case    _       SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=SYN_HEAD|Reading=モ
5       もも    もも    NOUN    名詞-普通名詞-一般      _       7       nmod    _       SpaceAfter=No|BunsetuBILabel=B|BunsetuPositionType=SEM_HEAD|NP_B|Reading=モモ|NE=B-OTHERS|ENE=B-Color_Other
6       の      の      ADP     助詞-格助詞     _       5       case    _       SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=SYN_HEAD|Reading=ノ
7       うち    うち    NOUN    名詞-普通名詞-副詞可能  _       0       root    _       SpaceAfter=No|BunsetuBILabel=B|BunsetuPositionType=ROOT|NP_B|Reading=ウチ
8       。      。      PUNCT   補助記号-句点   _       7       punct   _       SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=CONT|Reading=。




PythonでGiNZAを操作する


インストールができたろころでPythonでGiNZAを操作していきましょう。

1.文境界解析


文境界解析は文章から文の境界を検出する処理です。

import spacy

nlp = spacy.load('ja_ginza_electra')
doc = nlp('銀座でランチをご一緒しましょう今度の日曜日はどうですか。')

# 文境界解析
for sent in doc.sents:
    print(sent)

銀座でランチをご一緒しましょう
今度の日曜日はどうですか。

"。"がなくても文の境界が判断できていますね。


2.形態素解析


形態素解析は文章を単語に分割すると同時に単語の品詞などを推測する処理です。

import spacy

nlp = spacy.load('ja_ginza_electra')
doc = nlp('銀座でランチをご一緒しましょう。')
for sent in doc.sents:
    for token in sent:
        print(token.i, token.orth_, token.lemma_, token.pos_, token.tag_, token.dep_, token.head.i)
    print('EOS')

0 銀座 銀座 PROPN 名詞-固有名詞-地名-一般 obl 5
1 で で ADP 助詞-格助詞 case 0
2 ランチ ランチ NOUN 名詞-普通名詞-一般 obj 5
3 を を ADP 助詞-格助詞 case 2
4 ご ご NOUN 接頭辞 compound 5
5 一緒 一緒 VERB 名詞-普通名詞-サ変可能 ROOT 5
6 し する AUX 動詞-非自立可能 aux 5
7 ましょう ます AUX 助動詞 aux 5
8 。 。 PUNCT 補助記号-句点 punct 5
EOS






3.係り受け解析


係り受け解析は単語間の関係を解析する処理です。

以下のサンプルは係り受け木をSVG形式で保存しています。

# -*- coding: utf-8 -*-
# 文境界解析

import spacy
from spacy import displacy
from pathlib import Path

nlp = spacy.load('ja_ginza_electra')
doc = nlp("銀座でランチをご一緒しましょう。")
for sent in doc.sents:
    svg = displacy.render(sentstyle="dep")
    file_name = "kakari.svg"
    output_path = Path("./" + file_name)
    output_path.open("w"encoding="utf-8").write(svg)

キャプチャ


4.固有表現抽出


固有表現抽出は国名、人名などの固有表現を抽出する処理です。

import spacy
from spacy import displacy

nlp = spacy.load('ja_ginza_electra')
doc = nlp("山田さんと銀座でランチをご一緒しましょう。")
for ent in doc.ents:
   print(
       ent.text+','# テキスト
       ent.label_+','# ラベル
       str(ent.start_char)+','# 開始位置
       str(ent.end_char)) # 終了位置

山田,Person,0,2
さん,Title_Other,2,4
銀座,City,5,7



5.単語の分散表現


GiNZAでは学習済みの単語分散表現(word2vec)も使用できるみたいです。

分散表現は300次元ですが今回は最初の2次元だけ表示します。分散表現が学習されていない単語はALL 0になるみたいですね。

また、L2ノルムも取得することができます。

分散表現はja_ginza_electraでは学習済みモデルがないみたいなので、ja_ginzaを使用しています。

import spacy

nlp = spacy.load('ja_ginza')  
doc = nlp("銀座でランチをご一緒しましょう。")
for token in doc:
    print(token.text, token.vector[:2], token.has_vector, token.vector_norm)

銀座 [ 0.55935055 -0.02516028True 3.8992517
で [-0.09195102 -0.10327693True 1.8796002
ランチ [ 0.23565347 -0.08456942True 3.8218849
を [-0.19509408 -0.13202968True 2.0958433
ご [0.33537257 0.21526141True 2.8017106
一緒 [-0.1381576  -0.10699644True 2.5291438
し [ 0.00739705 -0.32393304True 2.2611105
ましょう [0. 0.] False 0.0
。 [ 0.12551211 -0.1708449 ] True 2.4466825

また、以下のように書くことで文のベクトル表現なども簡単に表現できます(各単語のベクトルを足して平均を求めている)。

import spacy

nlp = spacy.load('ja_ginza')  
doc = nlp("銀座でランチをご一緒しましょう。")
print(doc.vector[:2]) 

0.09312034 -0.08128325]





まとめ


GiNZAの基本的な処理について一通り触れてみましたが正直むちゃくちゃ便利です。

spaCyに関する知識が少ないのでGiNZAを有効活用できるようにそのあたりも勉強していこうと思います。





以前、OpenCVを使って顔認識をしたのですが、dlibというライブラリを使うと顔の細かいパーツのランドマークが検出できると聞いたので試しに動かしてみました。




dlibのインストール


まずは事前準備をしていきます。

dlibのインストールは以下のコマンドで行うことができます。

pip install dlib

dlibのインストールができたら、dlibの公式サイトから学習済みモデルをダウンロードしましょう。



「shape_predictor_68_face_landmarks.dat.bz2 」というファイルが顔から68個のランドマークを検出する学習済みモデルです。

また、上記の物の他に処理が軽い学習済みモデルとし「shape_predictor_5_face_landmarks.dat.bz2 」という顔から68個のランドマークを検出するモデルがあります。

今回は「shape_predictor_68_face_landmarks.dat.bz2 」を使用していきます。





写真から顔のランドマークを検出する


dlibの準備ができたところで顔のランドマークを検出してみましょう。

今回学習済みモデルは実行ファイルと同じパスにおいています。

import dlib
from imutils import face_utils
import cv2

# 顔検出ツールの呼び出し
faceDetector = dlib.get_frontal_face_detector()

# 顔のランドマーク検出ツールの呼び出し
facePredictor = dlib.shape_predictor('shape_predictor_5_face_landmarks.dat')

# 検出対象の画像の呼び込み
img = cv2.imread('検出したい画像のパス')

# 顔検出
faces = faceDetector(img1)

# 検出した全顔に対して処理
for face in faces:
    # 顔のランドマーク検出
    landmark = facePredictor(imgface)
    # 処理高速化のためランドマーク群をNumPy配列に変換(必須)
    landmark = face_utils.shape_to_np(landmark)

    # ランドマーク描画
    for (i, (xy)) in enumerate(landmark):
        cv2.circle(img, (xy), 1, (25500), -1)

# 顔検出ファイルを出力
cv2.imwrite("dLibSample-output.PNG"img)

以下の画像を今回は入れてみました。

woman-1274056_1280

分かりにくいので顔部分をアップしますが確かにランドマークが検出されていますね。

キャプチャ

顔のランドマークの番号は以下のように1~68番まで割り当てられているみたいです。

figure_68_markup

https://ibug.doc.ic.ac.uk/resources/facial-point-annotations/より


ちなみに「shape_predictor_5_face_landmarks.dat.bz2 」のモデルを使用した場合は以下のような出力になりました。

キャプチャ



まとめ


dlibを使って顔のランドマークを検出してみました。

ランドマーク検出って論文など見ていたら難しそうだというイメージがあったのですが今はこんなに便利なライブラリがあるんですね。

せっかくだからこのdlibを使ってなにかおもしろいソフトを作ってみたいですね。

OpenCVではうまくいかなかったface swapでも試してみようかな。






4267000_s

今回はPythonとOpenCVを使って写真の顔部分に自動的にモザイクをつけていきます。

これができればブログを書くときにモザイクをかける手間が減って便利そうです。


顔認識するプログラム


まずはモザイクをかける部分を決めるために顔認識を行うプログラムを作ってみます。

OpenCVには顔認識用の学習済みのカスケードファイルがあるのでそちらを使っていきます。

カスケードファイルは環境にもよりますがAnacondaを使っている場合、

~\Anaconda3\\envs\\python3.6\\Lib\\site-packages\\cv2\\data

の中に顔を認識させるものや目を認識させるものなどが入っています。

今回は、haarcascade_frontalface_alt.xmlというファイルを使います。

顔認識を行うサンプルプログラムは以下の通りです。

import cv2
import sys

# 識別したい画像を読み込む
imageFile = "画像ファイル名"
image = cv2.imread(imageFile)
imageGs = cv2.cvtColor(imagecv2.COLOR_BGR2GRAY)

# 顔認識ファイルを読み込む
cascadeFile = "~\\Anaconda3\\envs\\python3.6\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_alt.xml"
cascade = cv2.CascadeClassifier(cascadeFile)

# 顔認識を実行
faces = cascade.detectMultiScale(
    imageGs,
    scaleFactor=1.1,
    minNeighbors=1,
    minSize=(150150)
)

if len(faces) > 0:
    # 顔部分を赤枠で囲む
    color = (00255)
    for face in faces:
        xywh = face
        cv2.rectangle(image, (xy), (x+wy+h), colorthickness=8)
    cv2.imwrite("facedetect-output1.PNG"image)
else:
    print("No Face")

OpenCVのカスケードファイルは白黒画像に対してのみ顔認識を行うことができるため、一度画像をグレースケールに変換しています。

以下の画像を入力として与えると、

woman-1274056_1280

以下のように顔周りが赤枠で囲われた画像が出力されています。

facedetect-output1

画像を見て分かる通り顔認識ができていますね。





顔にモザイクをかける


次に顔にモザイクをかけていきます。

先ほど赤枠で囲っていた領域内にモザイクをかけるように先ほどのプログラムを改造していきましょう。

if len(faces) > 0:

以降の顔を赤枠で囲っていた処理を以下のように変えてください。

    # 顔部分にモザイクをかける
    mosaic_rate = 30
    for(xywhin faces:
        # 顔を切り抜く
        face = image[y:y+hx:x+w]
        # モザイクをかける
        face = cv2.resize(face, (w//mosaic_rateh//mosaic_rate))
        face = cv2.resize(face, (wh), interpolation=cv2.INTER_AREA)
        # 元の画像に張り付ける
        image[y:y+hx:x+w] = face
    cv2.imwrite("facedetect-output2.PNG"image)

モザイクをかける処理はコードを見て分かる通り、元画像を縮小した後に元の大きさにもどしてモザイクをかけています。

mosaic_rateの値が大きいほどモザイクが荒く、小さいほど細かくなります。

mosai_rateが30の場合は以下のような画像が出力されます。

facedetect-output2




まとめ


顔認識って難しいのかなとか思っていたのですがOpenCVを使えば簡単に実装することができました。

この機会にOpenCVの顔認識を使って色々と遊んでみようと思います。






Raspberry Piを使って定点カメラを作ってみました。

コマンドで定点カメラを使っても良かったのですが今後Pythonを使って色々やっていきたいと思っていたので今回はPythonを使って定点カメラを作っています。

カメラモジュールは『Raspberry Pi カメラモジュール v2』を使用しています。





Pythonで写真を撮る


ラズパイでPythonを使って写真を撮るのにはPiCameraというライブラリを使用します。

以下のコードでは5秒間カメラのプレビュー画面が表示されます。

from picamera import PiCamera
from time import sleep

camera = PiCamera()
camera.start_preview()
sleep(5)
camera.stop_preview()

実際に写真を撮るのにはPiCamera().caputureメソッドをコールします

また、とりたい写真のサイズをPiCamera().resolutionメソッドで設定することができます。

以下のコードの場合、プログラム起動して5秒後に写真が撮影されデスクトップにimage.pngという1920×1080のファイルが保存されます。

from picamera import PiCamera
from time import sleep

camera = PiCamera()
camera.resolution = (19201080)
camera.start_preview()
sleep(5)
camera.capture("/home/pi/Desktop/image.png")
camera.stop_preview()






定点カメラを作成する


写真の撮り方が分かったところで定点カメラを作成していきましょう。

今回は、5分に1回写真を撮るようにしていきます。

from picamera import PiCamera
from time import sleep
import datetime

camera = PiCamera()
camera.resolution = (19201080)
camera.start_preview()

while(True):
    sleep(300# 300秒待機
    camera.capture("/home/pi/Desktop/Image.png")

上記のコードで5分に1回写真を撮るという要件は満たせたのですが、このままだと同じファイルに写真が上書きして保存されてしまいます。

そこでファイル名をユニークな名前にするために今回は、ファイル名に現在時刻を付けていきます。

sleepの後を以下のように改造してください。

now = datetime.datetime.now()
filename = '/home/pi/Desktop/Image/' + now.strftime('%Y%m%d_%H%M%S') + '.png'
camera.capture(filename)

これで写真を撮るたびに別のファイル名がつくようになりました。

定点カメラの完成です。



まとめ


今回はラズパイ + Pythonで簡単な定点カメラを作ってみました。

写真を撮る頻度など対象によって変えていったら面白そうですね。





↑このページのトップヘ