python,opencvで増分符号相関(ISC)実装してみた

プログラミング
増分符号相関法(ISC : Increment Sign Correlation)とは、画像照合手法の一つである。
増分符号相関とは、輝度の増減の符号に着目した統計量のこと。
特徴として、ノイズや照明変動、対象物の遮蔽にロバストである。
pythonとopencvを使って、このアルゴリズムを実装しました。

目次

増分符号相関とは

着目画素と隣接する画素の濃度値を比較した結果を、2bitの符号として表し、画像同士の類似度を符号相関として評価する手法である。
一般的にはノイズや遮蔽、照明変動にロバストと言われています。

動作環境

・PyCharm Community Edition 2018.2.4 x64
・Python3.6
・OpenCV 3.4.3.18

画像ファイル

・テンプレート画像

・照合用画像①

・照合用画像②(照合用画像①+ノイズ)

・照合用画像③(照合用画像①+コントラスト変化)

・照合用画像④(照合用画像①+一部遮蔽)

ソース

import cv2

def img_incsign(img_gray, img_h, img_w):
    # initialize
    val = [[0 for i in range(img_w)] for j in range(img_h)]
    incSign = [[0 for i in range(img_w)] for j in range(img_h)]

    for i in range(img_h):
        for j in range(img_w):
            val[i][j] = img_gray[i, j]

    for i in range(img_h):
        for j in range(img_w-1):
            sign_val = int(val[i][j+1]) - int(val[i][j])
            if(sign_val >= 0):
                incSign[i][j] = 1
            else:
                incSign[i][j] = 0

    return incSign

def calc_score(temp_IncSign, temp_h, temp_w, org_IncSign, i, j, thining_rate):
    n_m = 0.0
    n_u = 0.0
    C = 0.0
    for k in range(0, temp_h, thining_rate):
        for l in range(0, temp_w, thining_rate):
            if (temp_IncSign[k][l] == org_IncSign[k+i][l+j]):
                n_m = n_m + 1
            else:
                n_u = n_u + 1
    nm = n_m + n_u
    C = n_m / nm

    return C


if __name__ == '__main__':
    # open template image
    img_temp = cv2.imread("./lena_eye.jpg")
    img_gray_temp = cv2.cvtColor(img_temp, cv2.COLOR_BGR2GRAY)

    # open original image
    img_org = cv2.imread("./lena_dark.jpg")
    img_gray_org = cv2.cvtColor(img_org, cv2.COLOR_BGR2GRAY)

    # get image size
    temp_h = img_gray_temp.shape[0]
    temp_w = img_gray_temp.shape[1]
    org_h = img_gray_org.shape[0]
    org_w = img_gray_org.shape[1]

    # generate increment sign from temp image
    temp_IncSign = img_incsign(img_gray_temp, temp_h, temp_w)

    # generate increment sign from original image
    org_IncSign = img_incsign(img_gray_org, org_h, org_w)

    # compare increment sign by all pixels
    C_MAX = 0
    thining_rate = 2
    for i in range(org_h - temp_h):
        for j in range(org_w - temp_w):
            C = calc_score(temp_IncSign, temp_h, temp_w, org_IncSign, i, j, thining_rate)
            if (C > C_MAX):
                # store point
                C_MAX = C
                # store coordinate
                x = i
                y = j


    # output matching result
    cv2.rectangle(img_org, (y, x), (y+temp_w, x+temp_h), (0, 0, 255), 2)
    cv2.imwrite("./result.jpg", img_org)
    score = C_MAX * 100 #[%]
    print("match rate : ", score)

 

結果

画像照合結果は以下のようになりました。
赤の四角線がマッチング率が最も高かった範囲を表しています。
今回準備した4枚の画像全てにおいて正しくマッチングされ、ロバストな結果を得ることが出来ました。

・照合用画像①

マッチ率:81.97343453510436

 

・照合用画像②

マッチ率:78.93738140417457

 

・照合用画像③

マッチ率:78.93738140417457

 

・照合用画像④

マッチ率:69.54459203036053

今後の課題と試してみたいこと

処理速度についてはあまり考慮せずに実装しているため、
サイズが大きい画像に対しては処理時間がかかるかもしれません。
リサイズ等の工夫をしなければいけないですね。
また、今回の検証では画像の回転に対しては考慮していないため、
回転に対するロバスト性も試してみたいですね。

参照サイト

参考文献

・村瀬一郎,金子俊一,五十嵐悟,増分符号相関によるロバスト画像照合,電子情報通信学会論文誌D-II, Vol.J83-DII, No.5, pp.1323-1331, 2000.

・月山恭一, 斉藤文彦, 方向可変増分符号相関によるテンプレート画像照合, IEEJ Trans. IA, Vol.124, No.10, 2004

タイトルとURLをコピーしました