機械系エンジニアの備忘録

20代独身社会人。仕事では機械・機構の研究開発を行っているエンジニアが、自分の専門分野ではないpythonを扱って楽しむブログです。

MENU

PythonとOpenCVで簡単にKuwaharaフィルターを適用する方法

Kuwaharaフィルター(白黒)をPythonで自作する

上がKuwaharaフィルター適用後、下がオリジナル画像です。

 

1. はじめに

Kuwaharaフィルターはノイズを除去しながらエッジを保持することができるため、私が知っている例ではSEM画像の3値化処理などに使われている画像処理フィルターです。また油絵っぽくなるためすごく面白いフィルターです。Kuwaharaフィルターは画像の各画素に対して任意に設定した周囲の領域の平均値を計算し、その領域の標準偏差が最も小さい値を新しい画素値として適用することで画像の平滑化を行います。詳細はSection 3で説明します。

非常に面白い画像フィルターですがopencvにデフォルトで入っていないため、今回はPythonOpenCVを使ってKuwaharaフィルターを自作する方法を紹介します。pythoコードはコピペで使用OKです。

 

 2. コード

以下が、画像にKuwaharaフィルターを適用するPythonコードです。

import cv2
import numpy as np
import time

start = time.perf_counter()

# 画像の読み込み
img = cv2.imread('/Users/xxxxx/Desktop/haibiscas.jpg', 0)
img_kuwahara = img.copy()

# 画像の縦横の画素数を取得
height, width = img.shape
print(height, width)

# Kuwaharaフィルター
a = 5  # フィルターの直径
n = int((a - 1) / 2)

for i in range(n, height - n):
    for j in range(n, width - n):
        top_left = img[i - n:i, j - n:j]
        top_right = img[i:i + n, j - n:j]
        bottom_left = img[i - n:i, j:j + n]
        bottom_right = img[i:i + n, j:j + n]
        trim_mean = [top_left.mean(), top_right.mean(), bottom_left.mean(), bottom_right.mean()]
        trim_std = [np.std(top_left), np.std(top_right), np.std(bottom_left), np.std(bottom_right)]
        img_kuwahara[i, j] = trim_mean[trim_std.index(min(trim_std))]

end = time.perf_counter()
print('{:.2f}'.format((end - start) / 60))

cv2.startWindowThread()
cv2.imshow('test', img_kuwahara)
cv2.imshow("original", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.waitKey(0)

 

3. コードの解説

ライブラリのインポート

最初に必要なライブラリをインポートします。cv2はOpenCVのライブラリで画像処理に使います。numpyは数値計算用、timeはプログラムの実行時間を測るために使います。

import cv2
import numpy as np
import time

 

開始時間の計測(任意)

プログラムの開始時間を記録します。ここは任意なのでプログラムの実行時間を測る必要がなければ飛ばして下さい。

start = time.perf_counter()

 

画像の読み込み

指定したパスから画像をグレースケールで読み込み、Kuwaharaフィルター適用後の画像のコピーを作成します。ファイルパスはお使いのPCに適した名前にしてください。

img = cv2.imread('/Users/xxxxx/Desktop/haibiscas.jpg', 0)
img_kuwahara = img.copy()

 

Kuwaharaフィルターの処理

フィルター径を設定し、各画素に対して四つの領域を定義します。それぞれの領域の平均値と標準偏差を計算し、標準偏差が最も小さい領域の平均値を新しい画素の値とします。

a = 5  # フィルターの直径
n = int((a - 1) / 2)

for i in range(n, height - n):
    for j in range(n, width - n):
        top_left = img[i - n:i, j - n:j]
        top_right = img[i:i + n, j - n:j]
        bottom_left = img[i - n:i, j:j + n]
        bottom_right = img[i:i + n, j:j + n]
        trim_mean = [top_left.mean(), top_right.mean(), bottom_left.mean(), bottom_right.mean()]
        trim_std = [np.std(top_left), np.std(top_right), np.std(bottom_left), np.std(bottom_right)]
        img_kuwahara[i, j] = trim_mean[trim_std.index(min(trim_std))]

詳細は以下の図になります。

例えば71のセルを中心にフィルター径3でKuwaharaフィルターを実施する場合、左上、右上、左下、右下の4つの9×9の四角形に注目します。

それぞれの四角形において分散を計算すると右下の紫色の四角が分散=18.21で他の3つの四角形より小さいです。よって中央の71は、右下の最も分散が小さい紫色の四角の平均41に書き換えられます。これを画像全体で繰り返し行うのがKuwaharaフィルターです。

実行時間の計測と表示(任意)

プログラムの終了時間を記録し、実行時間を分単位で表示します。

ここは任意ですので必要ない人は飛ばしてください。

end = time.perf_counter()
print('{:.2f}'.format((end - start) / 60))

 

画像の表示

OpenCVを使って、元の画像とフィルター適用後の画像を表示します。

cv2.startWindowThread()
cv2.imshow('test', img_kuwahara)
cv2.imshow("original", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.waitKey(0)

 

4. おすすめ参考書

PyAutoGUIやOpenCVの使用方法が載っている書籍を紹介します。

この3つは非常に丁寧に書かれているのでお勧めです。

Pythonで始めるOpenCV入門

Pythonで始めるOpenCV入門

 

Pythonで始めるOpenCV入門」と 「PythonGUI自動化しよう」については、Amazonの月額読み放題サービス「Kindle unlimited」に加入していれば読み放題です。

 

 5. おわりに

このコードを使うことで簡単にKuwaharaフィルターを画像に適用することができます。今回は白黒画像に対してKuwaharaフィルターを適用する方法を紹介しました、次回はカラー画像でのKuwaharaフィルターについて紹介します。

ToDoリスト作成を通じて簡単に学べるExcelの条件付き書式の使い方

 

1. はじめに

Excelには「条件付き書式」という、とても便利な機能があります。これは、特定のセルの状態(例えば色や文字)が変わったときに、他のセルの状態を自動的に設定された状態に変更できる機能です。非常に役立つ機能ですが、Excelに慣れていないと使い方がわかりにくいかもしれません。そこで今回は簡単なToDoリストを作成しながら、この条件付き書式の使い方をわかりやすくご紹介します。

 

2. 条件付き書式の使い方

それでは、画像付きで条件付き書式を利用した簡易ToDoリストの作り方を紹介します。画像内の赤枠で囲った部分が作業する場所です。

1. まず、C列にToDoリストを入力します。

2. 次に、C列を選択します。

3.「条件付き書式」から「新しいルール」をクリックします。

4. 「新しい書式ルール」ウインドウの上部で「クラシック」を選択します。

5. 表示される画面で、中央のプルダウンから「数式を使用して、書式設定するセルを決定」を選びます。

6. 下の記入欄に「=FIND("完了",D1)」と入力し、書式のプルダウンをクリックします。これは隣のD列のセルの値が「完了」になった際に、自動で処理を行うという意味です。

7. 「セルの書式設定」ウインドウが表示されるので、「塗りつぶし」タブで背景色をグレーに設定し、OKを押します。

8. 設定が完了したら、もう一度OKを押します。

9. 完了したら、タスク横のD列に「完了」と入力してみてください。セルの色がグレーに変わるのが確認できます。

10. 次に、同じ手順を繰り返して、D列に「緊急」と入力されたときに文字を赤くするルールを追加してみましょう。完了すると、緊急タスクが赤文字でハイライトされるようになります。

12. またD列に「完了」や「緊急」という文字を毎回入力するのは手間がかかるため、入力規則を使ってプルダウンから選択できるように設定しましょう。

12-1.「データ」タブから「入力規則」を選択します。

12-2. 「データの入力規則」ウインドウが表示されるので「リスト」を選択し、元の値の欄に「完了,緊急」と入力してOKを押します。

12-3. D列を選択すると、プルダウンメニューが表示され、マウスクリックで「完了」と「緊急」を選択できるようになります。

13. 最後に、タスクの番号について説明します。B列に「=IF(C4<>”", ROW()-3,””)」と入力します。これはタスクが記入されている場合に4行目をNo.1として番号を付ける数式です。

これで簡易ToDoリストが完成しました。ぜひ試してみてください。

 

3. 条件付き書式の応用編

条件付き書式は他にもさまざまな使い方ができます。以下にいくつかの便利な使用例を紹介します。

 
3-1. 条件付き書式の応用編

例えば、期限が近づいているタスク(締切の3日以内)を強調表示するために、次のような条件付き書式を設定できます。

  • 「条件付き書式」→「新しいルール」→「数式を使用して、書式設定するセルを決定」
  • =TODAY()>=DATE(YEAR($B1),MONTH($B1),DAY($B1)-3) と入力し、セルの背景色を赤に設定します。

こうすると以下のようにB列に締切日を記入すると、今日(6/18)から3日以内に期限が来るタスクが赤く表示されます。

 

3-2. 重複値のハイライト

リスト内の重複する値を強調表示するには、次の手順を行います。

  • C列を選択し、「条件付き書式」→「新しいルール」→「重複する値」
  • 書式を設定してOKを押します。

これにより、C列内で重複している値が強調表示されます。

 

3-3. 数値の範囲に基づく書式設定

例えば、売上データが一定の範囲内に収まっているかを視覚的に確認するために、次のような条件付き書式を設定できます。

  • 売上データが入力されている列を選択し、「条件付き書式」→「新しいルール」→「セルの値が」
  • 「次の値の間」に設定し、範囲を入力して、書式を設定します。

これにより、指定した範囲内の値が強調表示されます。

 

4. おすすめの参考書

Excelについて以下の参考書がよかったです。

 

5. 最後に

これらのテクニックを駆使することで、Excelの条件付き書式をさらに効果的に活用できます。日々の業務がより効率的になることでしょう。

 

 

 

 

 

Pythonの進行度をバーで表示するためのtqdmの使い方

Python tqdmでプログラムの進行度をバーで確認する

 

1. はじめに

以前、Tkinterプログレスバーを表示する方法を紹介しました。しかしこの方法はTkinterでウィンドウを作らなければ行けないという面倒さがあります。

www.stjun.com

そこで今回は簡易的に進行度を把握するために、tqdmを用いてコンソールに直接プログレスバーを表示する方法を紹介します。

 

2. 前準備

tqdmは標準モジュールではないのでダウンロードする必要があります。

コンソール画面で以下のようにpip(またはconda)でtqdmをインストールしてください。

pip install tqdm
conda install tqdm

 

3. 基本的な使い方

for文のin の後ろにtqdmをつけます。descはプログレスバーの名前になります。

import time
from tqdm import tqdm

for i in tqdm('mechanical engineering', desc="進捗"):
    time.sleep(0.2)

すると以下のようにfor文でループするごとにプログレスバーが進捗していきます。

軽いプログラムではあまり便利さを感じませんが、for文が多く計算量が大きいプログラムでは非常に役立ちます。例えば3DデザインソフトのBlenderpythonスクリプトを用いてモデルを作る場合などに現在の進行度をざっくり把握するためにtqdmを使っています。

 

4. おすすめ参考書

PyAutoGUIやOpenCVの使用方法が載っている書籍を紹介します。

この2つは非常に丁寧に書かれているのでお勧めです。

Pythonで始めるOpenCV入門

Pythonで始めるOpenCV入門

 

Pythonで始めるOpenCV入門」については、Amazonの月額読み放題サービス「Kindle unlimited」に加入していれば読み放題です。

初回30日間は無料、退会も簡単なので試しに読んでみてもよさそうです。

【Blender】Pythonを使ってパーティクルヘアーの設定を自動化する

Pythonを使ってBlenderのパーティクルヘアーを操作する

プログラムを実行すると「ヘアー生成」というタブが現れ、ボタンをクリックすると事前に設定済のパーティクルヘアーが適用されます。

 

1. はじめに

前回、BlenderPythonを使う方法を紹介しました。

www.stjun.com

今回はその応用編としてパーティクルヘアーの設定を自動化しましたので紹介します。毎回パーティクルの設定を行うのが面倒だったため結構役立っています。

 

2. コード

コードはこちらになります。

import bpy
  
# 視点をカメラにするボタン
class Camera_viewpoint_Panel(bpy.types.Panel):
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = 'ヘアー生成'
    bl_label = 'ヘアー生成'
    def draw(self, context):
       layout = self.layout
       row = layout.row()
       row.operator('hair.add')
class Camera_viewpoint_btn(bpy.types.Operator):
   bl_idname = 'hair.add'
   bl_label = 'ヘアーを生成する'
   bl_description = 'ヘアーを生成する'
   
   
   def execute(self,context):
       obj=bpy.context.active_object
       if len(obj.particle_systems)==0:
           obj.modifiers.new("part", type="PARTICLE_SYSTEM")
           part = obj.particle_systems[0]
           settings=part.settings
           settings.type="HAIR"
           settings.count=50
           settings.hair_length=4
           settings.use_hair_bspline = True
           settings.render_step = 8
           settings.display_step = 8
           settings.child_type = 'SIMPLE'
           settings.child_nbr = 200
           settings.rendered_child_count = 200
           settings.child_radius = 0.03
           settings.use_clump_curve = True
           settings.radius_scale = 0.001
       return{'FINISHED'}
       
bpy.utils.register_class(Camera_viewpoint_Panel)
bpy.utils.register_class(Camera_viewpoint_btn)

なお集結カーブだけはpythonから設定することができなそうなので手作業が必要です、ご注意ください。

 

3. 説明

パーティクルの設定に関わるコードは以下の部分になります。UIの説明は別の機会に紹介するため今回は省きます。

       obj=bpy.context.active_object
       if len(obj.particle_systems)==0:
           obj.modifiers.new("part", type="PARTICLE_SYSTEM")
           part = obj.particle_systems[0]
           settings=part.settings
           settings.type="HAIR"
           settings.count=50
           settings.hair_length=4
           settings.use_hair_bspline = True
           settings.render_step = 8
           settings.display_step = 8
           settings.child_type = 'SIMPLE'
           settings.child_nbr = 200
           settings.rendered_child_count = 200
           settings.child_radius = 0.03
           settings.use_clump_curve = True
           settings.radius_scale = 0.001

 

3.1 パーティクルシステムを作る

以下5文でパーティクルシステムを新規に作成しています。まず「obj=~~」で洗濯中のオブジェクトをアクティブにし、「if len~~」で既にパーティクルシステムがあるか調べます。既にパーティクルシステムがある場合はそこでプログラムは終了です、ない場合は3〜5行目の文で新しく作ります。

       obj=bpy.context.active_object
       if len(obj.particle_systems)==0:
           obj.modifiers.new("part", type="PARTICLE_SYSTEM")
           part = obj.particle_systems[0]
           settings=part.settings

以下画像の赤枠の設定と同義です。

 

3.2 親パーティクルの設定

以下の文で親の設定をしています。

settings.typeでエミッターかヘアーかを選日ます。

countは数です。lengthは髪の長さです。use_hair_bsplineをTrueにすることでBスプラインにチェックを入れます。またレンダーもビューもステップは8程度に設定しています。

          settings.type="HAIR"
           settings.count=50
           settings.hair_length=4
           settings.use_hair_bspline = True
           settings.render_step = 8
           settings.display_step = 8

上のコードは以下画像の赤枠に値します。

 

3.3 子パーティクルの設定

子の設定は以下の文になります。

           settings.child_type = 'SIMPLE'
           settings.child_nbr = 200
           settings.rendered_child_count = 200
           settings.child_radius = 0.03
           settings.use_clump_curve = True
           settings.radius_scale = 0.001

上のコードは以下の赤枠に対応します。

 

4. おすすめ

以下の本はお勧めです。

【初心者向け】BlenderでPythonを実行する方法

Pythonを使ってBlenderの作業を効率化

こんな感じでPythonを使ってオブジェクトを作ったり操作することができます。上の画像はpythonを使って四角の領域内に赤と緑の球をランダムに生成した例です。

 

1. はじめに

Blenderにはプログラミング言語であるPythonが標準搭載されています。Pythonを使えばオブジェクト、メッシュ、マテリアルといったBlender内のほぼ全ての要素を操作・自動化することができ非常に便利です。そこで今回は初心者向けとしてまずBlenderPythonを実行する方法を紹介します。

 

2. BlenderPythonを実行する方法

今回はMac版のver3.2.0を使っていますがWindowsでも操作は同じなためご安心ください。

2.1 Scriptingのタブを開く

まずBlenderを開くと以下のような画面が現れますので、上のタブの赤枠「Scripting」を選択してください。

以下のような画面が現れます。コードを複数まとめて実行する場合は緑枠に、1行1行対話形式で実行していく場合は青枠(コンソール)にコードを記載していきます。どちらも重要ですが今回は緑枠にコードを書いていきます。

 

2.2 コードを書く、実行する方法

以下赤枠の「新規」を選択します。

今回プログラムの名前は「test」としました。これでコードが書けるようになります。また赤枠の右矢印をクリックするとプログラムを実行することができます。

 

3. 実施例)任意の空間に球をランダムに500個出現させるプログラム

Pythonの実行方法がわかったので、試しにプログラムを書いてみましょう。今回は例として決められた空間内にランダムで球を500個出現させるプログラムを作ります。

 

3.1 ライブラリのimport

まず必要なライブラリをimportします。今回はbpyとnumpyというライブラリをimportします。bpyはBlenderのオブジェクトやマテリアルを操作するのに必須なライブラリで、numpyは数値計算に便利なライブラリです。

import bpy
import numpy as np

 

3.2 ランダムな値を生成する関数

次にランダムな値を生成する関数を作ります。名前はfunc_random_locとしました。

def func_random_loc(min,max):
    s=(max - min) * np.random.rand(3) + min
    return s

np.random.rand(3)は0~1の範囲でランダムに数字(小数点あり)を3つ生成します。それに(max-min)をかけminの和を取ることで、好きな範囲でランダムな数字を生成することができます。例えば、def func_random(0.1,1)としたら以下のように0.1~1の範囲でランダムな数字が3つ生成されます。

>>> print(func_random(0.1,1))
[0.23767973 0.64538955 0.3735291 ]

この値を球のx,y,z座標として用います。

また球のサイズは正規分布に沿うように以下のようにnumpyのrandom.normalを使います。meanは中央値で、stv標準偏差です。

def func_random_siz(mean,stv):
    t=np.random.normal(mean, stv)
    return t

 

3.3 球を生成する

準備が整ったので球を作っていきます。今回は500個作るのでfor文を使います。

for s in range(0,num):
    random_location = func_random_loc(min,max)
    random_size = func_random_siz(mean,stv)
    bpy.ops.mesh.primitive_ico_sphere_add(radius=random_size/2, location = random_location, subdivisions=5)
    r=bpy.context.object

Blenderで球を生成する場合はbpyライブラリを使って以下のように書きます。

bpy.ops.mesh.primitive_ico_sphere_add(radius, location, subdivisions)

radiusは半径で球の大きさで、x,y,zの3つの値が必要です。例えば半径1の真球を作りたい場合は[1,1,1]とします。楕円を作りたい場合は例えば[1,0.5,0.5]などです。

locationは球の位置です、こちらもx,y,zに対応する3つの値が必要です。

最後のsubdivisionsは分割数で値を大きくするほどメッシュ数が増えて綺麗な球になります。概ね5あたりが良いと思います。

 

3.4 完成と実行

完成したプログラムはこちらです。今回は大きさが一辺5(-2.5~2.5)の立方体の領域に、中央値0.4、標準偏差0.2の粒径分布を500個の球を生成してみました。

import bpy
import numpy as np
def func_random_loc(min,max):
    s=(max - min) * np.random.rand(3) + min
    return s
def func_random_siz(mean,stv):
    t=np.random.normal(mean, stv)
    return t
min=-2.5
max=2.5
num=500
mean=0.4
stv=0.2
for s in range(0,num):
    random_location = func_random_loc(min,max)
    random_size = func_random_siz(mean,stv)
    bpy.ops.mesh.primitive_ico_sphere_add(radius=random_size/2, location = random_location, subdivisions=5)

 

4. おすすめ

以下の本はお勧めです。

 

5. 最後に

今回はBlenderPythonを使う方法を紹介しました。これを利用すれば自作アドオンを作ることも可能です、興味ある方はぜひ。

Blender#63:Windowsの標準機能を使ってBlenderの作業画面を録画する

1. はじめに

最近Blender界隈が賑わっていますね。私が初めてBlenderに触れた2010年代はYoutubeも参考書も英語ばっかりでしたが、最近は日本語のTutorial動画が増えてきて嬉しいです。このブログを見てくれた方の中にもYoutubetwitterへの投稿を考えている方がいるかもしれません。ただWindowsの標準キャプチャ機能を普通に使うだけだとなぜかBlenderの作業画面を録画することができません。そこで今回はWindowsの標準キャプチャ機能を使ってBlenderの作業画面を録画する小技を紹介します。

 

2. 何が問題なのか

Windowsには標準で画面キャプチャ機能が付いており、Windowsキー+Gキーを押すと以下のような画面が現れます。この左上の赤枠を押すと画面の録画が始まります。

しかし、なぜかBlenderではこの方法で画面録画ができません。具体的には画面録画はできるのですが、以下のようにBlenderのレンダービューの操作ができなくなります。

 

3. 解決方法

録画を開始したら、一旦仮想デスクトップ画面を開き、何もせず元のデスクトップに戻るとBlenderの操作ができるようになります。例えばWindows11の方は以下画像の赤枠をクリックしてください。するとデスクトップの選択画面が現れます。

この状態でBlenderを開いている元のデスクトップ(上の画像だとデスクトップ1)に戻ります。すると以下のようにBlenderのレンダービューが動かせるようになります。

 

4. 最後に

ちょっとした小技の紹介でした。有料のキャプチャソフトを使わなくても、Windowsの標準機能で無料で画面録画できるのでぜひ試してみてください。

Blender#62:テクスチャを使った簡単な肌のマテリアルの作り方

手軽に作れるフォトリアルな肌マテリアルの作り方を紹介します

こちらが作例です。今回は簡単なフォトリアル系の肌の作り方を紹介します。

 

1. はじめに

キャラクターの完成度を上げるためには肌のマテリアルが重要です。特に私はフォトリアル寄りのマテリアルが欲しかったのですが、過去私が調べた時はあまり参考にできる情報がありませんでした。自分で試行錯誤した結果、ある程度使えそうな見栄えになってきたので紹介します。

 

2. 作り方

2.1 ベースのカラーを作る

まず画像テクスチャや頂点カラーを用意して、頬、鼻、唇などをブラシで塗っていきます。全体的に肌色に塗りつつ、目頭付近や唇の下などに少し影をつけていきます。個人的に、影に少し深緑を足すと良い感じになる気がします。※私は頂点カラーを使いましたが、画像テクスチャを推奨します。

次にHSVノードを使って色味を調整します。少し明るい肌にしたかったので、彩度と値(明るさ)を上げました。

次にAOとカラーランプで使って陰影を作ります。影もテクスチャを塗った方が良いのですが今回AOを使って楽をします。またAOを使うと環境光を考慮した陰影を作れるといったメリットもあります。

カラーミックスノードの乗算を使って肌のテクスチャとAOの陰影を重ね合わせた結果がこちらです。肌の色に良い感じに陰影をつけることができています。

またHSVノードで明るさや彩度の最終調整を行いましょう。

最後にプリンシプルBSDFノードのカラーに接続します。これだけでも結構いい感じです。

 

2.2 顔にテカリをつける(粗さマップ)

次に画像テクスチャとカラーランプを用意して、肌のテカリ具合を調整していきます。私はこれを粗さマップと呼んでいます、具体的なブラシの塗り方、使い方は過去記事をご覧ください。白いほどマット、黒いほどテカテカの質感になります。人の顔は、鼻先、唇、眉間などが特に皮脂でテカリやすいので、それを再現するためにテカテカさせたい部分を黒く塗っていきます。

そしたらプリンシプルBSDFの粗さに繋いでください。これで黒く塗った部分がテカテカしてリアルさが増します。

 

2.3 肌に凹凸をつける(ノーマルマップ)

最後に肌の凹凸感を作っていきます。というのは人の肌は角質で多少ブツブツしているので、この細かいブツブツを再現することでリアルさが増します。先程作った粗さマップを利用し、ノイズテクスチャとミックスカラーで乗算します。

それをバンプノードに繋いで、プリンシプルBSDFのノーマルに繋げます。ノイズテクスチャの値は大きく、バンプの値は小さくしてください。これで肌の角質のような小さいブツブツが表現できます。見た目的には微妙な差ですが...笑

これで簡単な肌のマテリアルの完成です。一度作ってしまえば、あとはテクスチャを変えるだけで色々なver.を作れるのでぜひ試してみてください。

 

2.4 おまけ

HSVノードの彩度を落とすとモノトーンにもできます。

3. おすすめ

以下の本はお勧めです。

 

m20xbtは初めてのヘッドホンに最適

audiotechnicaのm20xbtをレビュー

audiotechnicaのmシリーズは有名アーティストも使っている人気ヘッドホンシリーズです。2022年2月、本シリーズのエントリーモデルであるm20xbtが発売され2ヶ月ほど使用しましたのでレビューしてみます。

 

1. 良いところ

1.1 有線、無線の両方使える

基本は扱いが楽な無線で、電池が切れたら有線でといった使い方もできます。

 

1.2 装着感が良い

私は普通の大きさのヘッドホンだと耳が痛くなってしまうのですが、m20xbtは頭の形に合わせて長さを無段階調節できるし軽いので長時間付けていても頭や耳が痛くなりません。快適でした。

 

1.3 無線で2台同時接続ができる

すごく便利でした。普段使っているイヤホンは同時接続が出来ないので、端末を切り替える時は毎回Bluetooth接続の設定が必要でした。このヘッドホンは同時に複数台接続できるので、たとえばスマホで音楽聴いてて、急にタブレットで動画を流しても自動でスマホからタブレットに音声が切り替わってくれます。bluetoothを切り替える手間から解放されるのは思った以上に快適でした。

 

1.4 音質と価格のコスパが良い

BOSE quitconfort:約3万

Apple  airpods Pro:約2万

私が普段使っていた上二つのイヤホンと比較してみました。音質に関して個人的にはbose>audiotechnica>>airpodsと感じました。

この中では1番安いのに音質が良くコスパは高いと思います。また有線と無線を聴き比べましたがほとんど違いは感じなかったので、無線でも十分楽しめると思います。

→追記

イコライザー設定をロックにしてみたところ更に良くなりました。

 

1.5 マイクの音質が意外と良い

マイクも搭載されていて、無線状態でweb会議で使用してみましたが十分な音質でした。テレワークでも使えます。

 

2. 悪かった点

2.1 使用中に側面のランプが光り続ける

少し残念だったのは、使用中にヘッドホン側面のランプが光り続けることです。動作中であることが一目でわかるので自宅使用の場合は便利なのですが、外で使用する時は少し目立って嫌です。

 

2.2 ノイズキャンセリング機能がない

わかっていたことですが、ノイズキャンセリング機能はありません。飛行機や電車で使おうと思ってる人は、sonyboseノイズキャンセリングが搭載されているヘッドホンの方が良いかもしれません。

 

2.3 音漏れする

例えばリビングとかで使っていると家族が気づくレベルの音漏れです。電車や職場で使うのは少し厳しい気がします。

 

3. 結論

ワイヤレスで扱いやすく、音質も良い、マイクも付いているので自宅で使うヘッドフォンとしてはかなりコスパが良いと思います。

一方、外で使うことを想定している場合は、本製品は避けてBoseSonyといったノイキャン付きの密閉型ヘッドホンを買うのが良いと思います。

 

PythonのPlotlyでカッコいい3次元グラフを描く

Plotlyで動かせる、数値を表示できる、2次元と3次元を切り替えられるグラフを作る

 

1. はじめに

これまでPythonでグラフを作るときはMatplotlibを利用していましたが、最近はPlotlyというライブラリを利用する事が多くなりました。PlotlyはMatplotlibと比べて、

・そこまで有名でないため日本語の情報量が少ない

Tkinterなど他ライブラリとの連携が劣っている

などのデメリットがありますが、

・マウスで自由に動かせる3次元グラフが作れる

・グラフにマウスを近づけるとその点の値をリアルタイムで表示できる

・ボタンやスライダーを使ってグラフの種類やスタイルを瞬時に変えることができる

などMatplotlibには無い機能も揃えており、分かりやすいグラフが描けます。ということで、Plotlyの使い方を簡単に紹介します。

今回紹介するコード以外にもPlotlyの公式HPに多くサンプルコードが載っていますのでぜひチェックしてみてください。

plotly.com

 

2. コード

import numpy as np
import pandas as pd
import plotly.graph_objects as go

# データを用意する
x = np.arange(-10, 10, 0.1) # x軸を作成
y = np.arange(-10, 10, 0.1) # y軸を作成
X, Y = np.meshgrid(x, y)    # グリッドデータの作成
Z=np.sqrt((np.square(X)+np.square(Y))) #Z軸を作成

# 図を入れる入れ物の作成
fig = go.Figure()

# Surface図を作る
fig = go.Figure(data=go.Surface(
                   z=Z,
                   x=x,
                   y=y,
                   colorscale='jet',
                   ))

# 図のレイアウトの調整
fig.update_layout(
    width=800,
    height=700,
    #autosize=True,
    margin=dict(t=0, b=0, l=0, r=0),
    template="plotly_white",
)

# 3次元図のアスペクト比
fig.update_scenes(
    aspectratio=dict(x=1, y=1, z=1),
    aspectmode="manual"
)

# ボタンの設定と図の種類
fig.update_layout(
    updatemenus=[
        dict(
            type = "buttons",
            direction = "left",
            buttons=list([
                dict(
                    args=["type", "surface"],
                    label="3D Surface",
                    method="restyle"
                ),
                dict(
                    args=["type", "heatmap"],
                    label="Heatmap",
                    method="restyle"
                ),
                dict(
                    args=["type", "contour"],
                    label="Contour",
                    method="restyle"
                ),
                dict(
                    args=["colorscale", "Viridis"],
                    label="Viridis",
                    method="restyle"
                ),
                dict(
                    args=["colorscale", "Cividis"],
                    label="Cividis",
                    method="restyle"
                )
            
            ]),
            pad={"r": 10, "t": 10},
            showactive=True,
            x=0.1,
            xanchor="left",
            y=1.1,
            yanchor="top"
        ),
    ]
)

# 左上のテキスト
fig.update_layout(
    annotations=[
        dict(text="Trace type:", showarrow=False,
                             x=0, y=1.08, yref="paper", align="left")
    ]
)

fig.show()

上記を実行すると記事冒頭のように3Dグラフを動かしたり、2Dと3Dを切り替えたりできます。

 

3. 説明

3.1 前準備

Plotlyをインストールしておいてください。私は、M1 macでMiniforgeを使っているので、ターミナルから以下コマンドを打ってインストールしました。

conda install plotly

また"import ~~"の部分と、"#データを用意する"の以下部分は省略します。

 

3.2 グラフの作成

グラフは以下コード部分で作成しています。"Surface"は面のある3Dグラフのことです。またcolorscaleは赤と青のグラデーションの"jet"を使っています。それ以外は、図の大きさをwidthやheightで調整したり、図のアスペクトを指定しています。

# 図を入れる入れ物の作成
fig = go.Figure()

# Surface図を作る
fig = go.Figure(data=go.Surface(
                   z=Z,
                   x=x,
                   y=y,
                   colorscale='jet',
                   ))

# 図のレイアウトの調整
fig.update_layout(
    width=800,
    height=700,
    #autosize=True,
    margin=dict(t=0, b=0, l=0, r=0),
    template="plotly_white",
)

# 3次元図のアスペクト比
fig.update_scenes(
    aspectratio=dict(x=1, y=1, z=1),
    aspectmode="manual"
)

 

3.2 図の変更
                dict(
                    args=["type", "surface"],
                    label="3D Surface",
                    method="restyle"
                ),

このdictの部分でグラフを追加しています。args=["type", "(グラフ種類)"]のグラフ種類のところに例えば、

surface→面付きの3Dグラフ

heatmap→3DグラフをZ方向に(上から)見た2Dグラフ、色がZ値になる

contor→heatmapに更にコンター(データー内で同じ値に沿って結んだ線)をつけた図

と指定すれば様々なグラフを作ることができます。まだまだ種類があるのでぜひ公式HPをご確認ください。

 

3.3 色の変更
                dict(
                    args=["colorscale", "Viridis"],
                    label="Viridis",
                    method="restyle"
                ),

argsの中を"colorscale"にすると色を変えることもできます。例えばjetからViridisにすると暗い色になります。

 

4. おすすめ参考書

PyAutoGUIやOpenCVの使用方法が載っている書籍を紹介します。

この3つは非常に丁寧に書かれているのでお勧めです。

Pythonで始めるOpenCV入門

Pythonで始めるOpenCV入門

 

Pythonで始めるOpenCV入門」については、Amazonの月額読み放題サービス「Kindle unlimited」に加入していれば読み放題です。

初回30日間は無料、退会も簡単なので試しに読んでみてもよさそうです。

Pythonで3次元グラフを描く

matplotlibとtkinterで3Dグラフ(応答曲面)を別ウインドに壁画する

3次元グラフを動かしている様子

 

1. はじめに

最近仕事で最適化パラーメータについて同僚に説明するため三次元グラフ(応答局面)を描きたい時があったのですが、Excelだと綺麗な3次元グラフを書くことが難しく、かといってこのためだけに有料のmatlabを使うのも気がひけるので、ささっとpythonで実装してみました。pythonだと記事冒頭Gifのようにグラフを動かすこともできるのが良いですね。

 

2. コード

import numpy as np
from matplotlib import pyplot as plt
import tkinter as tk
from matplotlib.backends.backend_tkagg import (
    FigureCanvasTkAgg, NavigationToolbar2Tk)
import matplotlib.colors

root = tk.Tk()#ウインドの作成
root.title("3次元グラフの表示テスト")#ウインドのタイトル
root.geometry("800x800") #ウインドの大きさ

# データを用意する
x = np.arange(-10, 10, 0.1) # x軸を作成
y = np.arange(-10, 10, 0.1) # y軸を作成
X, Y = np.meshgrid(x, y)    # グリッドデータの作成
Z=np.sqrt((np.square(X)+np.square(Y))) #Z軸を作成

# フォントの種類とサイズを設定する。
plt.rcParams['font.size'] = 15
plt.rcParams['font.family'] = 'Arial'

# グラフの入れ物を用意する。
fig = plt.figure()
ax1 = fig.add_subplot(111, projection='3d')  

# 軸のラベルを設定する。
ax1.set_xlabel('x', labelpad=10)
ax1.set_ylabel('y', labelpad=10)
ax1.set_zlabel('z', labelpad=10)

# データプロットする。
ax=ax1.plot_surface(X, Y, Z, cmap='jet',label="z")

#カラーバーの設定
cbar = fig.colorbar(ax, shrink = 0.6)
cbar.set_label("Z", fontsize=15)

# グラフを表示する。
#tkinterのウインド上部にグラフを表示する
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.draw()
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)

#tkinterのウインド下部にツールを追加する
toolbar = NavigationToolbar2Tk(canvas, root)
toolbar.update()
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)

root.mainloop()

上記のプログラミを実行すると記事冒頭のように別ウインドが開き、マウスで動かせる3Dグラフが現れます。

 

3. 説明

3.1 基本的なコード

基本的なコードは過去記事に紹介した「tkinterのウインド上にグラフを表示する方法」と同じです。過去記事は2次元グラフですが、今回は3次元グラフに変えたところが違いになります。

www.stjun.com

 

3.2 3次元グラフ

今回の大きな違いは以下2つです。

ax1 = fig.add_subplot(111, projection='3d')  

ax=ax1.plot_surface(X, Y, Z, cmap='jet',label="z")

まず1行目の「projection='3d'」で3次元グラフであることを明記します。

次の2行目でsurface(X,Y,Z~~)とすることで応答局面を選びます。

例えばここを,

ax=ax1.plot_surface(X, Y, Z, label="z")

にすると面ではなくて3次元の散布図になります。

また,

ax=ax1.plot_wireframe(X, Y, Z, label="z")

にするとワイヤーフレーム表示になります。

ただ散布図もワイヤフレームも色が無くなってしまうので、plot_surfaceがおすすめです。

 

3.3 応答局面の色
ax=ax1.plot_surface(X, Y, Z, cmap='jet',label="z")

この文のcampのことです。「jet」は冒頭のように虹色になります。個人的にはその他のFEMソフトと同じこのjetが好みです。

matplotで使えるカラーマップは以下の公式HPで紹介されています。

Choosing Colormaps in Matplotlib — Matplotlib 3.5.2 documentation

例えば、cmap="CMRmap"にすると以下のように淡い色になります。

winterにすると以下のようになります。

bwrだと以下のようになります。

また単色系もあります。例えばGreysだと以下のように黒の単色になります。

 

4. おすすめ参考書

PyAutoGUIやOpenCVの使用方法が載っている書籍を紹介します。

この3つは非常に丁寧に書かれているのでお勧めです。

Pythonで始めるOpenCV入門

Pythonで始めるOpenCV入門

 

Pythonで始めるOpenCV入門」と 「PythonGUI自動化しよう」については、Amazonの月額読み放題サービス「Kindle unlimited」に加入していれば読み放題です。

初回30日間は無料、退会も簡単なので試しに読んでみてもよさそうです。