nyanpyou Note

主な目的は調べたり作ったりしたプログラミング備忘録(予定)

学びのメモ

今まで調べたり断片的に学んできた知識を整理することも兼ねて、OpenCVPythonの参考書を改めて1から読んでいる。
その中で覚えた事、よく忘れることなどをメモ書きとして無秩序に書き連ねる。


#osの区切り文字を取得する
import os
a = os.path.sep

import cv2
image = cv2.imread("imagepath")
#.shapeは縦、横、色のチャンネル数の順番に要素が並んだタプルを返す
(height, width, depth) = image.shape

よくこんがらがるが、heightはy座標とrow、widthはx座標とcolumnに対応する。
OpenCVで読み込んだ画像の色の情報は、各pixel毎に(B,G,R)の順番に並んで入っている(カラー画像の場合)。
個別の画素の値にアクセスするときは

image[200,400]

などとするが、この時の順番は[”行”,"列"]であることを忘れない。つまり座標的には(y,x)の並び(でもよく忘れる)。


(x,y)-coordinatesはxy座標の事。


PythonOpenCVで画像を扱う際、基本的な画像処理(アスペクト比を維持して拡大縮小や回転)を簡単に行うための便利機能を集めたライブラリーとしてimutilsがある。

github.com


ArgumentPaserを使うと、プログラム実行時にコマンドライン上からプログラムに引数を渡すことができる。読み込みたい画像のパスを、引数として受け取るようにしておく等ができるようになる。

qiita.com


OpenCVで扱う画像は、デフォルトでは8bitの符号なし整数になっているため、画像の差分を取りたい時は32bit整数に直して行い、結果の絶対値を取ってから8bitに戻す。

import numpy as np
subtraction = a.astype("int32") - b.astype("int32")
subtraction = np.absolute(subtraction).astype("uint8")

収縮(Erosion)処理と膨張(Dilation)処理を組み合わせることで、二値化画像のノイズを除去することが出来る。引数にNoneを指定すると3×3のstructuring element(構造化要素?)を用いて実行するらしい。iterationsは処理を適用する回数。

import cv2
#image is binary image
#Erosion
eroded = cv2.erode(image, None, iterations = 1)
#Dilartion
non_noise_image = cv2.dilate(eroded, None, iterations = 1)

docs.opencv.org


import numpy as np
#正の無限大
a = np.inf
#負の無限大
b = -np.inf

Pythonのif文は1行でも書ける。

#通常
if a>10:
    b = 1
else:
    b = 0

#1行
b = 1 if a>10 else 0

OpenCVからWebカメラのパラメータを変更したい場合(例えば明るさ)は、

import cv2
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_BRIGHTNESS, value)

とすると変更が可能だが、valueに設定できる数値の範囲は、使用するカメラによって異なるため、事前に何らかの方法で調べておく必要がある。cap.getで設定されている値が確認できるため、アナログな方法だが、適当な値をsetしてすぐにgetして確認するなど。設定できない値を入力した場合、setした値と異なる値がgetで返ってくる。OpenCVで用意されているプロパティのリストはこちらの公式ドキュメントにまとまっているが、使用するカメラによっては変更できないものもある(露出時間など)ため、これも逐一調べる必要がある。


itertools.cycleを使うと指定したリストなどを無限に繰り返せる。

from itertools import cycle
#無限に1,2,3の順番で表示
a = [1,2,3]
for i in cycle(a):
    print(i)
#next()メソッドを使って順番に取り出すことも可能
from itertools import cycle
a = cycle([1,10,100])
next(a)
>>1
next(a)
>>10
next(a)
>>100
next(a)
>>1

**kwargsを関数の引数に設定しておくと、引数を辞書として受け取れる。

def test(**kwargs):
    print(kwargs)
test(a=1, b=10, c=100)
>>{'a':1, 'b':10, 'c':100}

pop()メソッドを使うと辞書から指定したキーとそれに対応する値を削除して、値を取り出せる。

dic = {"a":10, "b":100, "c":1000}
val = dic.pop("b")
print(dic)
>>{"a":10, "c":1000}
print(val)
>>100