python (jupyter notebook) で Gnuplot グラフを出力
こんにちは.
春が近づいていますが,大雪のところもあり珍しい天候ですね.
今日は Jupyter notebook 上で Gnuplot グラフを出力する方法を紹介します.
グラフ描画ソフトは様々ありますが,筆者は使用用途で使い分けています.
比較的きれいなグラフが欲しいときや論文投稿用には Kaleida Graph を,大量のグラフを作成するときは Gnuplot を C言語や python から動かして描画しています.
Excel もそれなりのグラフができますが,目盛が四辺に書けない,マシンスペックによってはデータ数が多いと重くなってしまう,などの問題があります.
用途にあった描画ソフトを選びましょう :)
今回は python で Gnuplot のグラフを描画し出力します.
いろいろ調べた結果,実際に使用した例を書きます.
以下コードです.
gnuplotCommand 内にgnuplot のコマンドを打ち込む形です.
筆者は Times New Roman を多用しています.
#######################################################
##### Gnuplot by python (jupyter notebook)
from subprocess import call
gnuplotCommand ='''
set datafile separator ',';
set border lw 2 lc rgb 'black';
set xrange [-200:600];
set yrange [0:1];
set xlabel '';
set ylabel '';
set key right bottom;
set size ratio 1;
set terminal emf size 400,400 'Times New Roman';
set output '(outputするパス)';
plot ~~~;
reset;
'''
call( [ "gnuplot", "-e", gnuplotCommand])
#######################################################
これでは Gnuplot の for 文を使えないのが問題です.
ご存知の方は教えていただけますと幸いです.
それでは.
canny edge detection : 画像処理によるエッジ検出 (python)
こんにちは.
今日は画像処理に関して,エッジ抽出法であるcannyのエッジ検出法を数か月前に実装したので紹介します.
想像よりも鮮明にエッジ検出ができるため,結構面白いです.笑
openCV などでも簡単にできますが,基本的には足し算掛け算でできるので numpy の配列を用いました.
データ解析でブラックボックスのソフトを使用することが多い今日ですが,原理を1から勉強するのも重要でありますね.
環境は以下の通りです.
win 8
python 3.5
anaconda 3-4.0.0
今回は python を用い,画像の配列化,配列の画像化は PIL というライブラリを使用しています.
PIL はターミナル上からインストールできます.
canny edge detection は以下の流れで行います.
- original image のノイズを減らすためガウシアンフィルタを施し平滑化.
- sobel フィルタを用い,x, y 方向それぞれに画素の一次微分を行う(勾配を計算する).
- grd_x, grd_y の勾配の合計をその画素の勾配の大きさとして保存.
- atan = (grd_y / grd_x) を求め,エッジの方向を決定し,細線化を行う.
- 閾値を用いて場合分けを行いエッジ判定し,エッジを検出する.
以下 python (Jupyter notebook 上) でのコードです.
グレースケールの画像での処理になります.
閾値の上限下限を設定することで結果が変わります.
インデント左揃えになっているのはご容赦下さい...
間違いなどあれば指摘いただけますと幸いです.
###########################################################
################### canny edge detection ######################
###########################################################
from PIL import Image
import numpy as np
import os
import math
##### ファイルのパス #####
file_path = '(画像があるディレクトリのパス)'
##### ディレクトリ作成 #####
if (os.path.exists(filter_path) == False):
os.mkdir(filter_path)
if (os.path.exists(grd_path) == False):
os.mkdir(grd_path)
if (os.path.exists(canny_path) == False):
os.mkdir(canny_path)
###################################################################
##### Im_originalに画像を取り込み,array_original(配列)に輝度値を配列として保存#####
im_original = Image.open(file_path + '\\(画像ファイル名, tif, png など)')
array_original = np.asarray(im_original)
width, height = im_original.size
###################################################################
##### 勾配強さを求める #####
##### 勾配をそれぞれ grd_x, grd_y とする #####
grd_x = np.zeros(height,width))
grd_y = np.zeros(height,width))
grd_sum = np.zeros(height,width))
##### sobel filter によるエッジ強さ計算 #####
for vrtcl in range (1, height-1):
for hrzn in range (1, width-1):
grd_x_array = np.array([array_original[vrtcl-1,hrzn-1]*(-1),array_original[vrtcl-1,hrzn]*(0),array_original[vrtcl-1,hrzn+1]*(1), array_original[vrtcl,hrzn-1]*(-2),array_original[vrtcl,hrzn]*(0),array_original[vrtcl,hrzn+1]*(2),array_original[vrtcl+1,hrzn-1]*(-1),array_original[vrtcl+1,hrzn]*(0),array_original[vrtcl+1,hrzn+1]*(1)])
g_x = np.sum(grd_x_array)
grd_y_array = np.array([array_original[vrtcl-1,hrzn-1]*(1),array_original[vrtcl-1,hrzn]*(2),array_original[vrtcl-1,hrzn+1]*(1),array_original[vrtcl,hrzn-1]*(0),array_original[vrtcl,hrzn]*(0),array_original[vrtcl,hrzn+1]*(0),array_original[vrtcl+1,hrzn-1]*(-1),array_original[vrtcl+1,hrzn]*(-2),array_original[vrtcl+1,hrzn+1]*(-1)])
g_y = np.sum(grd_y_array)
grd_x[vrtcl,hrzn] = (int)(g_x)
grd_y[vrtcl,hrzn] = (int)(g_y)
grd_sum[vrtcl,hrzn] = (grd_x[vrtcl,hrzn]**2+grd_y[vrtcl,hrzn]**2)**0.5
##### image にするために輝度値を 0~255 に収める #####
grd_sum = np.array(grd_sum, dtype = 'float')
grd_sum = grd_sum * 255 / np.max(grd_sum)
##### 勾配画像の保存 (grd ディレクトリ) #####
img_grd.save(grd_path + '\\grd.tif')
###### gradの方向より,非極大抑制を行う(細線化) #######
for vrtcl in range (1, height-1):
for hrzn in range (1, width-1):
grd_angl = math.atan2(g_y,g_x)
##### gradの方向の決定
##### 縦の場合
if (grd_angl>=(3/8*math.pi) or grd_angl<=(-3/8*math.pi)):
if grd_sum[vrtcl,hrzn]>(grd_sum[vrtcl-1,hrzn] and grd_sum[vrtcl+1,hrzn]):
grd_sum[vrtcl,hrzn]=grd_sum[vrtcl,hrzn]
else:
grd_sum[vrtcl,hrzn]=0
##### 横の場合
if (grd_angl>=(-1/8*math.pi)and grd_angl<=(1/8*math.pi)):
if grd_sum[vrtcl,hrzn]>(grd_sum[vrtcl,hrzn-1] and grd_sum[vrtcl,hrzn+1]):
grd_sum[vrtcl,hrzn]=grd_sum[vrtcl,hrzn]
else:
grd_sum[vrtcl,hrzn]=0
##### 斜めの場合(右上)
if (grd_angl>=(1/8*math.pi) or grd_angl<=(3/8*math.pi)):
if grd_sum[vrtcl,hrzn]>(grd_sum[vrtcl+1,hrzn-1] and grd_sum[vrtcl+1,hrzn-1]):
grd_sum[vrtcl,hrzn]=grd_sum[vrtcl,hrzn]
else:
grd_sum[vrtcl,hrzn]=0
##### 斜めの場合(左上)
if (grd_angl>=(-3/8*math.pi) or grd_angl<=(-1/8*math.pi)):
if grd_sum[vrtcl,hrzn]>(grd_sum[vrtcl+1,hrzn+1] and grd_sum[vrtcl-1,hrzn-1]):
grd_sum[vrtcl,hrzn]=grd_sum[vrtcl,hrzn]
else:
grd_sum[vrtcl,hrzn]=0
grd_sum = np.array(grd_sum, dtype = 'float')
grd_sum = grd_sum * 255. / np.max(grd_sum)
##### 閾値の設定(上限と下限) #####
maxVal = np.average(grd_sum)*3.0
minVal = np.average(grd_sum)*0.6
print(i, np.average(grd_sum))
edge_array = np.zeros(height,width))
##### 閾値で場合分け(上限より大きければエッジ,上限以下下限以上なら周りの状態で場合分けを行う) #####
for vrtcl in range (1, height-1):
for hrzn in range (1, width-1):
if (grd_sum[vrtcl,hrzn]>maxVal):
edge_array[vrtcl,hrzn] = 1
else:
edge_array[vrtcl,hrzn] = 0
for vrtcl in range (1, height-1):
for hrzn in range (1, width-1):
if (grd_sum[vrtcl,hrzn]>maxVal):
grd_sum[vrtcl,hrzn] = 255
if (grd_sum[vrtcl,hrzn]<maxVal and grd_sum[vrtcl,hrzn]>minVal):
if (1 == ([edge_array[vrtcl-1,hrzn-1] or edge_array[vrtcl-1,hrzn] or edge_array[vrtcl-1,hrzn+1] or
edge_array[vrtcl,hrzn-1] or edge_array[vrtcl,hrzn+1] or
edge_array[vrtcl+1,hrzn-1] or edge_array[vrtcl+1,hrzn] or edge_array[vrtcl+1,hrzn+1]])):
grd_sum[vrtcl,hrzn] = 255
else :
grd_sum[vrtcl,hrzn] = 0
if (grd_sum[vrtcl,hrzn]<minVal):
grd_sum[vrtcl,hrzn] = 0
##### 勾配画像の保存 (canny ディレクトリ) #####
img_grd.save(canny_path + '\\canny.tif')
print('process were correctly finished')
jupyter notebook のテーマの変更
jupyter notebook のテーマの変更方法を書き残しておきます.
jupyter themes という extension を使用します.
環境
Anaconda 3-4.0.0
Python 3.5
-
下記コマンドを入力( > は不要)
> pip install jupyterthemes
jupyterthemes がインストールされます.
-
-l で使用できるテーマが表示されます.
> jt -l
以下のものが使用可能でした.
chesterish
grade3
monokai
oceans16
onedark
solarizedd
solarizedl
-
-tでダウンロードできます.
> jt -t chesterish