【Python】【画像処理】画像の画素毎のGBR値を3Dグラフにプロットする

#coding:utf-8
"""
$jupyter notebook
$for python3.x
"""
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
from sklearn.cluster import KMeans
from PIL import Image
from PIL import ImageDraw
from random import randint
from os.path import exists
from os import mkdir
from math import fabs
from random import random
from copy import deepcopy
from math import log
from math import sqrt
import cv2
import numpy as np
from collections import namedtuple
import csv

def main():
    #特徴ベクトルの型の定義
    vec = namedtuple('vec_info',['GBR','coordinate'])

    #画像を読み込み
    img = cv2.imread("sample.png")
    
    #画像のサイズ
    height = img.shape[0]
    width  = img.shape[1]

    #特徴ベクトルの総数(画素数)
    num_vec = height*width

    #各画素の特徴ベクトルを取得する
    vectors = []
    for y in range(height):
        for x in range(width):
            BGR = img[y,x]
            v = vec(BGR,(y,x))
            vectors.append(v)
    vectors = np.array(vectors)
    feature_vectors = vectors[:,0]
    #feature_vectors = np.reshape(feature_vectors,(1,len(feature_vectors)))
    tmp = []
    for vec in feature_vectors:
        tmp.append(vec)
    feature_vectors = np.array(list(tmp))

    #特徴空間の点をプロット
    feature_vectors_G = feature_vectors[:,0]
    feature_vectors_B = feature_vectors[:,1]
    feature_vectors_R = feature_vectors[:,2]

    #初期プロットの表示
    fig = plt.figure()
    ax = Axes3D(fig)
    ax.scatter3D(feature_vectors_G,feature_vectors_B,feature_vectors_R)
    plt.show()

if __name__ == '__main__':
    main()

ライブラリは適当
グラフを動かせるようにしたい.
f:id:umashika5555:20170501132337p:plain
f:id:umashika5555:20170501135633p:plainf:id:umashika5555:20170501135631p:plainf:id:umashika5555:20170501135628p:plain


【追記】
デフォルトで回転できるようになってた.

【Python】【機械学習】3次元モデルのk-means

#for python3.6

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
from sklearn.cluster import KMeans

#サンプルを定義
a = [0.0,0.0,0.0]
b = [0.1,0.1,0.1]
c = [1.0,1.0,1.0]
d = [0.9,0.8,0.7]
e = [1.0,0.0,0.0]
f = [0.9,0.1,0.1]
dots = np.array([a,b,c,d,e,f])
X = dots[:,0]#各サンプルのx座標
Y = dots[:,1]
Z = dots[:,2]

#初期プロットの表示
fig = plt.figure()
ax = Axes3D(fig)
ax.scatter3D(X,Y,Z)
plt.show()

#クラスタの個数
num_cluster = 3

#k-means法
km = KMeans(n_clusters=num_cluster,
            init='random',
            n_init=2,
            max_iter=100,
            tol=1e-04,
            random_state=0
            )
y_km = km.fit_predict(k)#y_kmにクラスタの番号が保存される

#クラスタ毎に分類
CLUSTER = [[[],[],[]] for _ in range(num_cluster)]
for i,v in enumerate(dots):#各ベクトルに対して
    for j in range(len(y_km)):#分類ラベルに対して
        if y_km[i] == j:#分類ラベルがjだったら
            CLUSTER[j][0].append(v[0])#クラスタjのx座標にベクトルvのx座標を入れる
            CLUSTER[j][1].append(v[1])
            CLUSTER[j][2].append(v[2])

#グラフを描画
fig = plt.figure()
ax = Axes3D(fig)
for i,c in enumerate(CLUSTER):#各クラスタ毎に
    x,y,z = c[0],c[1],c[2]#x,y,z座標
    ax.scatter3D(x,y,z)
plt.show()

f:id:umashika5555:20170501114053p:plain
というように分類される.

【Python】3次元モデルのプロット

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(-3,3,0.25)
y = np.arange(-3,3,0.25)
X,Y = np.meshgrid(x,y)
Z = np.sin(X) + np.cos(Y)

fig = plt.figure()
ax = Axes3D(fig)
ax.plot_wireframe(X,Y,Z)

plt.show()

参考
d.hatena.ne.jp


散乱図のプロット

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

a = [0.0,0.0,0.0]
b = [0.1,0.1,0.1]
c = [1.0,1.0,1.0]
d = [0.9,0.8,0.7]
e = [1.0,0.0,0.0]
f = [0.9,0.1,0.1]
k = np.array([a,b,c,d,e,f])
X = k[:,0]
Y = k[:,1]
Z = k[:,2]

fig = plt.figure()
ax = Axes3D(fig)
ax.scatter3D(X,Y,Z)
plt.show()

X=k[:,0]のように記述できるのは

k = array([[・,・,・],
           [・,・,・],
           ..........,
           [・,・,・]])

のような形をしているからである.
f:id:umashika5555:20170501111044p:plain

k-means++法

k-means法ではセントロイドの初期値が不適切である場合, クラスタリングが上手く行かなかったり収束に時間がかかる場合がある.
この問題の対策としては

  • k-meansアルゴリズムを一つのデータセットで複数回実行し,誤差平方和から最も性能が良いモデルを選択する.
  • 初期のセントロイドを互いに離れた位置に置くこと(k-means++法)

k-means++法での初期化

  1. 選択の対象となるk個のセントロイドを格納するために空のデータセットMを初期化する
  2. 入力サンプルから初期のセントロイド \muをランダムに選択しMに割り当てる
  3. Mに含まれていないサンプル x^{i}ごとにMのセントロイドに対して距離の2乗が最小となるセントロイドを求める
  4. 次のセントロイド \mu をランダムに選択するには各サンプルの距離の重みを等しく以下の確立分布を使用する

 \frac{d(\mu^{p},M)^{2}}{\sum_{i}d(x^{i},M)^{2}}

  1. k個のセントロイドが選択されるまでステップ3-4を繰り返す
  2. 従来のk-means法を使って引き続き処理を行う

【Python】【スクレイピング】HTMLデータのスクレイピング

import urllib.request
url = 'http://umashika5555.hatenablog.com/'
response = urllib.request.urlopen(url)
data = response.read()
decoded_data = data.decode('utf_8')
print(decoded_data)
import urllib.request
import bs4
url = 'http://umashika5555.hatenablog.com/'
soup = bs4.BeautifulSoup(urllib.request.urlopen(url).read())
print(str(soup))

参考
minus9d.hatenablog.com

【ネットワーク】お勉強19

フロー制御TCPプロトコルで, 相手のバッファが溢れないようにするもの.
相手のバッファに溜まっている量を見て満杯そうだったらあまり送らないようにする.
逆に空いているときは一気に送りつける.
一気に送りつけれる量のことをウィンドウサイズという.

TCPではスロースタートアルゴリズムを用いる.
これはルータなど中継するデバイスは基本的に第3層以下の運ぶことを目的にできているので, ホスト側から処理する.
ホスト計算機は閾値まで指数的に送るデータを増やしていき, 閾値になったら徐々にデータを増やしていく.
一度にたくさん送ると渋滞するかもしれないので様子を見ている.
輻輳が発生した場合, 確認応答が1つでも帰ってこなかった場合,いったん送る数を減らす.

TCPではフロー制御でバッファオーバーフローをスロースタートアルゴリズム輻輳制御をしている!!!

TCPまとめ
スリーウェイハンドシェイクでコネクションを確率.
コネクションを確立して互いに確実に送受信ができることを示す.

送るときはフロー制御と輻輳制御を行う.
パケットの破棄が起きないように確実に送るため.

【Python】【OpenCV】n*m のランダムな色の画像を作成

# vim: set fileencoding=utf-8 :
import numpy as np
import cv2
from random import randint
import numpy as np

cols = 320
rows = 320

#イメージ生成
image = np.zeros((rows, cols, 3), np.uint8)

div = 16 # 縦横の分割数 
w = cols / div # 分割された領域の横幅
h = rows / div # 分割された領域の縦幅
for segrow in xrange(div):
    y1 = segrow * h # 分割領域上
    y2 = y1 + h     # 分割領域下
    for segcol in xrange(div):
        x1 = segcol * w #分割領域左
        x2 = x1 + w     #分割領域右
        b = randint(0,255)
        g = randint(0,255)
        r = randint(0,255) 
        c1 = np.array([b,g,r])
        #(x1,y1)-(x2,y2)の矩形を塗りつぶす
        image[y1:y2, x1:x2] = c1


# 表示して[ESC]が押されるまで待つ
cv2.imshow("image", image)
while cv2.waitKey(33) != 27:
    pass

参考
takamints.hatenablog.jp

【並行処理】【Python】プロセスについて

Processクラス
multiprocessingクラスでのプロセスの手順

  1. Processのオブジェクトを作成
  2. start()メソッドの呼び出し
  3. join()で処理が完全に終わるまで待つ

Process()クラスの呼び出しで引数はtargetに実行したい関数名,argsにtargetに入れる引数を入れる.一つとは限らないので最後に,をつける.

from multiprocessing import Process

def f(name):
    print("hello",name)

if __name__ == '__main__':
    p = Process(target=f,args=('bob',))
    p.start()
    p.join()


hello bob
上のコードについて実行されたプロセスのIDを表示するために拡張したコード

from multiprocessing import Process
import os

def info(title):
    print(title)
    print('module name:',__name__)
    print('parent process:',os.getppid())
    print('process id:',os.getpid())

def f(name):
    info('function f')
    print('hello',name)

if __name__ == '__main__':
    info('main line')
    print("-"*20)
    p = Process(target=f,args=('bob',))
    p.start()
    p.join()

os.getppid()は親プロセスのID,os.getpid()は現在のプロセスのIDを取得する.


main line
module name: __main__
parent process: 13055
process id: 18154

function f
module name: __main__
parent process: 18154
process id: 18155
hello bob

mainでの現プロセスと関数fでの親プロセスが一致することに注意

コンテキストと開始方式

import multiprocessing as mp

def foo(q):
    q.put("hello")

if __name__ == "__main__":
    mp.set_start_method("spawn")
    q = mp.Queue()
    p = mp.Process(target=foo,args=(q,))
    p.start()
    print(q.get())
    p.join()

hello

プロセス間でのオブジェクト交換
キュー
Queueクラスはqueue.Queueクラスとほぼ同じ使い方ができる.

from multiprocessing import Process,Queue
def f(q):
    q.put([42,None,"hello"])

if __name__ == "__main__":
    q = Queue()
    p = Process(target=f,args=(q,))
    p.start()
    print(q.get())
    p.join()


[42,None,'hello']

パイプ
Pipe()関数はコネクションオブジェクトのペアを返す.
デフォルトでは双方向性パイプを返す.

【Python】コマンドライン引数

コマンドライン引数はsys.argvで操作することができる.
先頭は自身のプログラムの名前となることに注意.

#sample.py
import sys
print("コマンドライン引数:",sys.argv)
$python sample.py a b c
コマンドライン引数:['sample.py','a','b','c']

【ネットワーク】お勉強18

【第40回】TCP シーケンス番号
MSS
TCP/IPではデータが長い場合は分割して送信する.
その分割するサイズがMSS.
送信は元のデータと同じ順序で送る.
この時に使うのがシーケンス番号.
データを転送する際にはシーケンス番号に送るデータの先頭番号を入れる.
確認応答を送る際には確認応答番号に次に受け取るデータの先頭番号(シーケンス番号+MSS分)を入れる.
エラーが起きたかどうかを判定するには確認応答が一定時間(RTT)帰ってこなかったことによって判定する.

【ネットワーク】お勉強17

【第31回】Layer3 Routing
ルーティング
ルータは最適なルートを見つけるために他のネットワークへのルートを知る必要がある.
更に知ったルートの中から最適なものを選んでルーティングテーブルを作成する.
ルートの知り方は2種類あり静的ルーティング動的ルーティング.

静的ルーティング
静的ルーティングは管理者が手動でルートを定義する.
欠点としてルータの故障があった場合, 他の道をたどるという有痛が効かない.

動的ルーティング
ルータ同士が情報を交換し合っていてルータが故障したとき,あるルータに障害があった場合,それを自動的に切り離すことができる.
3 Minutes Networking No.31Figure31-04
ルータ同士が情報を交換するということはデータを送り合うということでその分帯域幅を使用するということである.よってデータ転送に使われる帯域幅が減ってしまうことが欠点.
また最適ルートを計算するという処理があるのでルータの処理能力が必要.
すべてのルータが同一のルート情報を持つことが必要.
3 Minutes Networking No.31Figure31-05
すべてのルータが同一のルート情報を持っている状態のことをコンバージェンスという.
動的ルーティングはルーティングプロトコルによって実現される.
ルーティングプロトコルとはルータ同士の情報の交換の方法や最適ルートの決定法などを定めたプロトコル.

【ネットワーク】お勉強16

【第27回】 プロトコル帯域幅
通信には4つのアドレスが必要でそのアドレスの確認方法は以下である.

アドレス 取得方法
送信元のMACアドレス 既に決まっている
送信元のIPアドレス DHCP
宛先IPアドレス DNS
宛先MACアドレス ARP


【第28回】Layer3 Router
ルータによるネットワークの接続
ルータを使わない場合,同じネットワーク内にしかデータは転送できない.


【第29回】Layer3 デフォルトゲートウェイ
ブロードキャストドメイン
動的にIPアドレスを貰うときのDHCPDISCOVERなどは全てのホストに届くブロードキャスト,これをほかネットワークに送り出さにようにルータがある.
ブロードキャストが届く範囲のことをブロードキャストドメインという.
衝突ドメインはブリッジ,スイッチが区分けし, ブロードキャストドメインはルータが区分けする.

ARPとルータ
ARPで違うネットワーク上のホストのMACアドレスを知りたい時,ARPはブロードキャストなのでルータが遮ってしまう.
これを防ぐためにインターネットワークではデフォルトゲートウェイが必要となる.
デフォルトゲートウェイは他ネットワークとの接続点に位置するデバイス.

デフォルトゲートウェイ
他のネットワークへデータ転送を希望するホストは一度デフォルトゲートウェイにデータを送り他ネットワークに転送してもらう.
3 Minutes Networking No.29Figure29-03
デフォルトゲートウェイを設定しないとARPが通らないので異なるネットワーク間の通信が出来ない.
宛先のネットワークを見る方法はサブネットマスクのネットワーク部の範囲
3 Minutes Networking No.30Figure30-01
ルータの動作,サブネットマスクによる通信の流れ
3 Minutes Networking No.30Figure30-02
宛先IPアドレスが無い場合はルータは破棄する.(スイッチは全てのポートから送り出す)