PythonでOpenCVさわってみた

OpenCV インストール

PythonでOpenCVを使う@Mac - Qiita

ここ参照.

基本コード

# 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)

参考文献

OpenCVによる画像処理入門 (KS情報科学専門書)

OpenCVによる画像処理入門 (KS情報科学専門書)