PythonでOpenCVさわってみた
OpenCV インストール
ここ参照.
基本コード
# coding: utf-8 import cv2 import math import numpy as np # ファイル名の指定 file_src = '2.png' file_dst = '2.png' # 画像の読み込み img_src = cv2.imread(file_src, 1) # ウィンドウ名の指定 cv2.namedWindow('src') cv2.namedWindow('dst') # 画像処理 # 上下反転 img_dst = cv2.flip(img_src, flipCode=0) # 出力 cv2.imshow('src', img_src) cv2.imshow('dst', img_dst) # 終了処理 cv2.waitKey(0) cv2.destroyAllWindows()
以下のコードは基本コードの 画像処理の下に書いていくもの
様々な色空間への変換
# 複数色チャンネルの分割と結合 BGR->RGB img_bgr = cv2.split(img_src) img_dst = cv2.merge((img_bgr[0],img_bgr[1],img_bgr[2])) # BGRからHSVへの変換 img_dst = cv2.cvtColor(img_src, cv2.COLOR_BGR2HSV) # BGRからグレースケールへの変換 img_dst = cv2.cvtColor(img_src, cv2.COLOR_BGR2GRAY)
ガンマ変換
# ガンマ変換 ガンマ値は2.0 # ルックアップテーブルの生成 Y = np.ones((256, 1),dtype= 'uint8') * 0 for i in range(256): Y[i][0] = 255 * pow(float(i)/ 255, 1.0 / 2.0) # ルックアップテーブル変換 img_dst = cv2.LUT(img_src, Y)
アフィン変換
# アフィン変換 # 原点中心45°反時計回り # その後に,y座標方向に画像高さの半分だけ平行移動 size = tuple(np.array([img_src.shape[1], img_src.shape[0]])) afn_mat = np.float32( [ [math.cos(-math.pi / 4), -math.sin(-math.pi / 4), 0], [math.sin(-math.pi / 4), math.cos(-math.pi / 4), img_src.shape[0] * 0.5] ]) img_dst = cv2.warpAffine(img_src, afn_mat, size, flags=cv2.INTER_LINEAR) center = tuple(np.array([img_src.shape[1] * 0.5, img_src.shape[0] * 0.5])) angle = 45.0 scale = 1.0 size = tuple(np.array([img_src.shape[1], img_src.shape[0]])) rot_mat = cv2.getRotationMatrix2D(center,angle,scale) img_dst = cv2.warpAffine(img_src, rot_mat, size, flags=cv2.INTER_LINEAR)
透視変換
# 透視変換 size = tuple(np.array([img_src.shape[1], img_src.shape[0]])) pts1 = np.float32([ [160,479], [480,479], [480,240], [160,240] ]) pts2 = np.float32([ [160,479], [480,479], [400,240], [240,240] ]) psp_mat = cv2.getPerspectiveTransform(pts1, pts2) img_dst = cv2.warpPerspective(img_src, psp_mat, size)
濃淡ヒストグラム
# 濃淡ヒストグラム img_dst = np.zeros([100, 256]).astype('uint8') rows, cols = img_dst.shape # 度数分布を求める hdims = [256] hranges = [0, 256] hist = cv2.calcHist([img_src],[0], None, hdims, hranges) # 度数の最大値を取得 min_val , max_val, min_loc, max_loc = cv2.minMaxLoc(hist) for i in range(0, 255): v = hist[i] cv2.line(img_dst, (i, rows), (i, rows - rows * (v / max_val)), (255,255,255)) # ネガポジ変換 img_dst = 255 - img_ssrc
明度調整
# 明度調整 shift = 100 table = np.arange(256, dtype=np.uint8) for i in range(0,255): j = i + shift if j < 0: table[i] = 0 elif j > 255: table[i] = 255 else: table[i] = j img_dst = cv2.LUT(img_src, table) # コントラスト低減 min = 0 max = 255 img_dst = cv2.normalize(img_src, alpha=min, beta=max, norm_type=cv2.NORM_MINMAX)
フィルタ処理
# 平均化オペレータ img_dst = cv2.blur(img_src, (3,3)) # バイラテラルオペレータ img_dst = cv2.bilateralFilter(img_src, 11, 1, 1) # 中央値フィルタ処理 img_dst = cv2.medianBlur(img_src ,9) # Sovelオペレータ img_tmp = cv2.Sobel(img_src, cv2.CV_32F, 1, 0) img_dst = cv2.convertScaleAbs(img_tmp) # 2次微分オペレータ img_tmp = cv2.Laplacian(img_src, cv2.CV_32F, 3) img_dst = cv2.convertScaleAbs(img_tmp) # 鮮鋭化フィルタ k = 1.0 op = np.array([ [-k, -k, -k], [-k, 1 + 8 * k, -k], [-k, -k, -k] ]) img_tmp = cv2.filter2D(img_src, -1, op) img_dst = cv2.convertScaleAbs(img_tmp)
参考文献
- 作者: 小枝正直,上田悦子,中村恭之
- 出版社/メーカー: 講談社
- 発売日: 2014/07/18
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
Pythonでスタックとキュー
スタック
class Stack: def __init__(self, stack = None,max = 100): self.max = max if type(stack) is type([]): self.stack = stack elif stack is None: self.stack = [] else: print('Please list type!\n') def push(self, e): if not self.is_full(): self.stack.append(e) return self.stack else: print('Stack is full!!\n') def pop(self): if not self.is_empty(): e = self.stack.pop() return (e, self.stack) else: print('Stack is empty!!\n') def is_empty(self): if len(self.stack) is 0: return True else: return False def is_full(self): if len(self.stack) is self.max: return True else: return False
キュー
class Queue: def __init__(self, queue = None, max = 100): self.max = max if type(queue) is type([]): self.queue = queue elif queue is None: self.queue = [] else: print('Please enter list type!\n') def enqueue(self, e): if not self.is_full(): self.queue.append(e) return self.queue else: print('Queue is full!!\n') def dequeue(self): if not self.is_empty(): e = self.queue[0] del self.queue[0] return (e, self.queue) else: print('Queue is empty!!\n') def is_empty(self): if len(self.queue) is 0: return True else: return False def is_full(self): if len(self.queue) is self.max: return True else: return False
Python3 文法メモ
クロージャ
def closure(param): def inner(): return "Hello %s" % param return inner c1 = closure("MARIO") print(c1()) # Hello MARIO c2 = closure("LUIGI") print(c2()) # Hello LUIGI
ラムダ
def hello(names, func): for name in names: func(name) names = ["MARIO", "LUIGI", "DONKY"] hello(names, lambda name: print(name+"!"))
ジェネレータ
def my_range(first=0, last=10, step=1): number = first while number < last: yield number number += step ranger = my_range(1,5) for i in ranger: print(i)
デコレータ
def document_it(func): def new_function(*args, **kwargs): print('Running function:', func.__name__) print('Positional arguments:',args) print('Keyword arguments:',kwargs) result = func(*args, **kwargs) print('Result:',result) return result return new_function @document_it def add_ints(a,b): return a+b print(add_ints(3,5))
プロパティ
class Duck(): def __init__(self,input_name): self.__name = input_name @property def name(self): print("inside the getter") return self.__name @name.setter def name(self, input_name): print("inside the setter") self.__name = input_name f = Duck("Howard") print(f.name) f.name = "One" print(f.__name) # ここでエラーを吐く
参考文献
- 作者: Bill Lubanovic,斎藤康毅,長尾高弘
- 出版社/メーカー: オライリージャパン
- 発売日: 2015/12/01
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
Cython 文法メモ
# ライブラリのインポート from libc.math cimport sin from libc.string cimport strcmp from libc.stdio cimport fopen,fclose,fgets,fseek,ftell,fwrite # 関数宣言 def main(): #変数宣言 cdef int a=1 cdef char* s = "Hello マリオさん。こんにちは" cdef list l = [1,2,3,4,5] cdef dict d = {"one":1,"two":2} cdef tuple t = (1,2) cdef set se = {"one","two","three"} # fopenでのファイル読み込み fin = fopen("add.pyx","r") if not fin: print "読み込みミスった" cdef char str[1000] fseek(fin, 0L, 1); # ファイルシーク while fgets(str,256,fin) != NULL: # print ftell(fin) print str fclose(fin) # ファイル閉じる # ファイル書き込み fout = fopen("output.txt","w") if not fout: print "読み込みミスった" fwrite(s, sizeof(char), len(s), fout); fclose(fout)
参考URL
CythonとPythonとの処理時間の比較
Pythonを高速化するCythonを使ってみた - Kesin's diary
ここに書いてあることがおもしろそうだったのでやってみた.
1~100000000まで足しこむプログラム. 環境はmacで。
C
#include <stdio.h> int main(){ int i,n=0; for(i=0;i<100000000;i++) n+=i; }
オプションで最適化しとく.
gcc -O2 a.c
time ./a.out ./a.out 0.00s user 0.00s system 31% cpu 0.007 total
うん。速い。
Python
n=0 for i in range(100000000): n += i
同じく
time python3 add.py python add.py 13.15s user 1.53s system 97% cpu 15.021 total
遅い.
型指定していないCython
def add_test(): n=0 for i in range(100000000): n+=i
で、setup.pyを
from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext ext_modules = [Extension("add", ["add.pyx"])] setup( name = 'Hello world app', cmdclass = {'build_ext': build_ext}, ext_modules = ext_modules )
として,main.pyを以下の通りに作成して
from add import add_test add_test()
として実行すると
time python3 main.py python3 main.py 5.75s user 0.02s system 99% cpu 5.830 total
だいぶ速くなった!
型指定したCython
def add_test(): cdef int n = 0 cdef int i for i in range(100000000): n+=i
あとはさっきと同様にして実行
time python3 main.py python3 main.py 0.03s user 0.01s system 68% cpu 0.064 total
速すぎわろた。
グラフにすると
こんな感じ.
httpdをソースコードからインストール
CentOSで行った.
インストール
yum install -y gcc make pcre pcre-devel wget cd /usr/local/src wget http://ftp.yz.yamagata-u.ac.jp/pub/network/apache//apr/apr-1.5.2.tar.gz tar xzvf apr-1.5.2.tar.gz cd apr-1.5.2 ./configure --prefix=/opt/apr/apr-1.5.2 make make test make install cd /usr/local/src wget http://ftp.jaist.ac.jp/pub/apache//apr/apr-util-1.5.4.tar.gz tar -xvzf apr-util-1.5.4.tar.gz cd apr-util-1.5.4 ./configure --prefix=/opt/apr-util/apr-util-1.5.4 --with-apr=/opt/apr/apr-1.5.2 make make test make install cd /usr/local/src wget http://ftp.jaist.ac.jp/pub/apache/httpd/httpd-2.4.18.tar.gz tar -xvzf httpd-2.4.18.tar.gz cd /usr/local/src/httpd-2.4.18 ./configure --prefix=/opt/httpd/httpd-2.4.18 --with-apr=/opt/apr/apr-1.5.2 --with-apr-util=/opt/apr-util/apr-util-1.5.4 make make install
動的モジュールのインストール
# httpd開発ツール yum install -y httpd-devel
そして
# mod_infoを入れる場合 httpd -M | grep info # 何も出ない場合, 未インストール cd /Apacheのソース/modules/generators/ apxs -i -a -c mod_info.c
httpd.conf側で
LoadModule info_module modules/mod_info.so <IfModule mod_info.c> <Location /server-info> SetHandler server-info Order deny,allow Deny from all Allow from 127.0.0.1 </Location> </IfModule>
としてhttpdを再起動
Pythonの文法での疑問 set list
>>> a = [set([])]*7 >>> a [set(), set(), set(), set(), set(), set(), set()]
こんな感じでsetのリストを作ってa[1]だけに1を入れようとしたところ
>>> a[1].add(1) >>> a [{1}, {1}, {1}, {1}, {1}, {1}, {1}]
ってなるのなんでだろう...って思って Twitterで呟いたら、ありがたいリプが!!!
話は簡単で
a = [set([])] * 7
とすると
「set([]) が 7個コピーされて代入される」ので a[0]もa[1]も同じオブジェクトだからだそうです。
正しいやり方は
a = [ [] for i in range(7) ]
よく考えたら当たり前な話でした。
リプくださった皆さん、本当にありがとうございました。
D3.js 折れ線グラフ メモ
だんだん慣れてきた.
[ { "DATE": "2015/11/27 15:47:29", "TOTAL_RECORDS": 265 }, { "DATE": "2015/11/27 15:50:47", "TOTAL_RECORDS": 461 }, { "DATE": "2015/11/27 15:53:58", "TOTAL_RECORDS": 647 }, { "DATE": "2015/11/27 15:58:14", "TOTAL_RECORDS": 829 }, { "DATE": "2015/11/27 16:27:18", "TOTAL_RECORDS": 1008 }, { "DATE": "2015/11/30 11:18:07", "TOTAL_RECORDS": 1198 }, { "DATE": "2015/12/01 10:34:28", "TOTAL_RECORDS": 1364 }, { "DATE": "2015/12/03 10:49:03", "TOTAL_RECORDS": 1977 }, { "DATE": "2015/12/03 10:50:18", "TOTAL_RECORDS": 2156 }, { "DATE": "2015/12/04 10:29:15", "TOTAL_RECORDS": 2347 }, { "DATE": "2015/12/07 10:44:02", "TOTAL_RECORDS": 2509 } ]
というjsonファイルの可視化
d3.json(dirpath+"total_records.json", function(error, data){ // 軸の表示のためのマージンと画面サイズ var margin = {top: 20, right: 20, bottom: 30, left: 40}; var width = 1000 - margin.left - margin.right; var height = 300 - margin.top - margin.bottom; // svgタグの作成 var svg = d3.select("#total_records") .append("svg") .attr({ //元の画面サイズ width: width + margin.left + margin.right, height: height + margin.top + margin.bottom }) .append("g") // マージンの分だけ位置をずらす .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); // x軸の最小最大 var xMin = new Date(data[0]["DATE"]); var xMax = new Date(data[data.length - 1]["DATE"]); // y軸の最小最大 var yMin = Math.min.apply(null,data.map(function(o){return o["TOTAL_RECORDS"];})); var yMax = Math.max.apply(null,data.map(function(o){return o["TOTAL_RECORDS"];})); // スケールの定義 var xScale = d3.scale.linear() .domain([xMin,xMax]) .range([0,width]); var yScale = d3.scale.linear() .domain([yMin-10, yMax]) .range([height, 0]); var fmtFunc = d3.time.format("%Y/%m/%d"); // 軸の設定 var xAxis = d3.svg.axis() .scale(xScale) .orient("bottom") .tickSize(6, -height) .tickFormat(function(d){ return fmtFunc(new Date(d))}); var yAxis = d3.svg.axis() .ticks(5) //軸のチックの数 .scale(yScale) .orient("left") .tickSize(6, -width); // line設定 var line = d3.svg.line() .x(function(d,i){ return xScale(new Date(d["DATE"]));}) .y(function(d,i){ return yScale(d["TOTAL_RECORDS"]);}); // svgタグの中にcircleタグの作成 svg.selectAll("circle") .data(data) .enter() .append("circle") .attr({ r: 5, cx: function(d,i){ return xScale(new Date(d["DATE"])); }, cy: function(d,i){ return yScale(d["TOTAL_RECORDS"]);} }); // line表示 svg.append("path") .datum(data) //data読み込み .attr({ class: "line", d: line //上で作ったlineを入れて、linepathを作る }); // gタグの中でyAxisをcallし、y軸を作る svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr({ x: 10, y: -10 }) .style("text-anchor", "end") .text("Number"); svg.append("g") .attr({ class: "x axis", transform: "translate(0," + height + ")" }) .call(xAxis); });
参考URL
D3.js 縦棒グラフ メモ
スケールでだいぶ苦戦した。
以下は
item 18 18 0 30 47 0 1
を読み込んで縦棒グラフの作成のメモ.
d3.csv(dirpath+"hoursA.csv", function(error, data){ // 描画サイズ var width = 550; var height = 200; // svgタグの定義 var svg = d3.select("#hoursA").append("svg") .attr("width", width) .attr("height", height) // 棒の幅 // var barWidth = 40; // データ読み込み var dataset = []; for(var i=0; i<data.length;i++){ dataset.push(data[i].item); } // スケール関数を作成 var xScale = d3.scale.linear() .domain([0,dataset.length]) // [入力の最小値,入力の最大値] .range([0,width]); // [出力の最小値, 出力の最大値] // ブラウザは下に伸びていくのでrangeに注意 var yScale = d3.scale.linear() .domain([0,Math.max.apply(null,dataset)]) // [入力の最小値,入力の最大値] .range([height,30]); // [出力の最小値, 出力の最大値] var rects = svg.selectAll("rect") .data(dataset); // パディング var paddingY = 15 // 棒の作成 rects.enter() .append("rect") .attr({ width: barWidth, height: function(d,i){ return height - yScale(d);}, x: function(d,i){ return i * (width/dataset.length);}, y: function(d,i){ return yScale(d) - paddingY;}, fill: "rgba("+0+","+255+","+0+","+0.5+")" }); // 棒の長さを数値化 rects.enter() .append("text") .attr({ class: "barNum", x: function(d,i){ return i * (width/dataset.length) + barWidth/2;}, y: function(d,i){ return yScale(d)- paddingY - 5;} }) .text(function(d,i){ return d;}); // 横軸の作成 svg.append("rect") .attr({ class: "axis_x", width: width, height: 1, x: 0, y: height - paddingY -1 }); // 横軸の数値 rects.enter() .append("text") .attr({ class: "barNume", x: function(d,i){ return i * (width/dataset.length);}, y: height }) .text(function(d,i){ return i; }); });
こんな感じになると思う
D3.js 基本文法
使う機会が発生したのでメモ。
D3.jsの組み込み
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
基本操作
# DOM要素を指定して変数に代入 # bodyの中に、属性wisth,heightを持ったsvgタグを生成 var dataset = [11,62,23,54,33,51,32,16]; var w = 1000; var h = 300; var svg = d3.select("body").append("svg").attr({width: w, height: h}); # DOM要素を指定して編集. 存在していないタグも指定可能 (後でappendとかする) # 1つだけのときはselect # 複数あるときはselectAll svg.selectAll("rect") .data(dataset) // datasetを結びつける .enter() // 今回の場合、rectタグすべて .append("rect") // タグの生成 .attr({ // 属性の設定 x: padding, y: function(d,i){ return i * 25 ;}, width :function(d) { return xScale(d) - padding;}, height: 20, fill: "red" }) .on("click", function(d){ alert(d);}); // イベントの設定
アニメーション
svg.selectAll("circle") .data(dataset) .enter() .append("circle") .transition() // アニメーションの設定 .delay(function(d, i){ // 要素間の時間間隔の設定 return i * 300; }) .duration(1000) // 何秒かけてするか .ease("bounce") // 要素の指定位置への着地の仕方 .each("start", function(){ // コンストラクタみたいなもの d3.select(this).attr({ // 今回の場合、このthisはcircleにあたる fill: "green", r: 0, cy: h }); }) .attr({ cx: function(d, i){ return 50 + (i * 100); }, cy: h/2, r: function(d){ return d;}, fill: "red" }) .each("end", function(){ // デストラクタみたいなもの d3.select(this) .transition() .duration(1000) .attr({ fill: "blue", r: 0, cy : 0 }); });
コード全体
htmlファイル
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title></title> <link rel="stylesheet" href=""> <style> .axis path .axis line { fill: none; stroke: black; } .axis text { font-size: 11px; } </style> </head> <body> <button id="update">データ更新</button> <svg id="myGraph" width="1000" height="200"> </svg> <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> <script src="./test.js" charset="utf-8"></script> </body> </html>
jsファイル
// 初期化 var padding = 20; var svg = d3.select("#myGraph"); var update = d3.select("#update"); var w = svg.attr("width"); var h = svg.attr("height"); d3.csv("./test.csv", function(error, data){ var dataset = []; for(var i=0; i<data.length;i++){ dataset.push(data[i].item1); } console.log(dataset); var xScale = d3.scale.linear() .domain([0,Math.max.apply(null,dataset)]) .range([padding,w - padding]) .nice(); var xAxis = d3.svg.axis() .scale(xScale) .orient("bottom"); svg.append("g") .attr({ class: "axis", transform: "translate(0,150)" }) .call(xAxis); svg.selectAll("rect") .data(dataset) .enter() .append("rect") .attr({ x: padding, y: function(d,i){ return i * 25; }, width: function(d){return xScale(d) + "px";}, height: 20, fill: "red" }) .on("mouseover", function(d){ d3.select(this).attr("fill","orange"); }) .on("mouseout", function(d){ d3.select(this).attr("fill","red"); }); });