end0tknr's kipple - 新web写経開発

http://d.hatena.ne.jp/end0tknr/ から移転しました

画像処理(画像認識) - 「密なSIFT(HOG : Histogram of Oriented Gradients )」算出

oreillyの「実践コンピュータビジョン」写経の続き

実践コンピュータビジョン サンプルプログラム

SIFT特徴量検出の続きでもあります

画像処理 - vlfeatによるSIFT特徴点検出 - end0tknr's kipple - 新web写経開発

SIFT特徴点検出結果の対応点探索 (python) - end0tknr's kipple - 新web写経開発

密なSIFT(HOG : Histogram of Oriented Gradients ) とは

SIFT特徴量は、特徴点の周辺の勾配に対し、勾配ヒストグラムを算出しましたが、 HOGは、一定間隔で勾配ヒストグラムを算出します。

pythonHOGを算出し、その座標を表示

#!/usr/local/bin/python
# -*- coding: utf-8 -*-
from PIL import Image
import numpy
import matplotlib
matplotlib.use('Agg')
import matplotlib.pylab as plb
import os
## http://www.vlfeat.org/download/vlfeat-0.9.20.tar.gz
SIFT_CMD = '/home/endo/local/vlfeat/sift'


def main():
    # 画像から「密なSIFT記述子(HOG)」を抽出し、fileに保存.
    process_image_dsift('empire.jpg', 'empire.sift', 90, 40, True)

    l,d = read_features_from_file('empire.sift')
    im = numpy.array(Image.open('empire.jpg'))
    plot_features(im,l,True)
    plb.savefig( '8_1_2.png' )


# 画像から「密なSIFT記述子(HOG)」を抽出し、fileに保存.
#   args size=特徴量size, steps=grid間隔, resize=画像resize用のタプル
#   force_orientation= True →最大の局所勾配の方向で記述子が正規化
#                      False→全て上向き
def process_image_dsift(imagename,
                        resultname,
                        size=20,
                        steps=10,
                        force_orientation=False,
                        resize=None):
    im = Image.open(imagename).convert('L')  # file open後、グレースケール化
    if resize != None:
        im = im.resize(resize)
    m, n = im.size

    if imagename[-3:] != 'pgm':
        im.save('tmp.pgm')  # pgmファイルを作成
        imagename = 'tmp.pgm'

    # frameを作成し一時fileに保存
    scale = size / 3.0
    x, y = numpy.meshgrid(range(steps, m, steps), range(steps, n, steps))
    xx, yy = x.flatten(), y.flatten()
    frame = numpy.array([xx, yy,
                         scale * numpy.ones(xx.shape[0]),
                         numpy.zeros(xx.shape[0])])

    numpy.savetxt('tmp.frame', frame.T, fmt='%03.3f')

    if force_orientation:
        cmmd = str(SIFT_CMD +" "+ imagename + " --output=" + resultname +
                   " --read-frames=tmp.frame --orientations")
    else:
        cmmd = str(SIFT_CMD +" "+ imagename + " --output=" + resultname +
                   " --read-frames=tmp.frame")
    os.system(cmmd)

    print 'processed', imagename, 'to', resultname


# 特徴量を読込み行列形式で返す
def read_features_from_file(filename):
    f = numpy.loadtxt(filename)
    return f[:, :4], f[:, 4:]  # 特徴点の配置と記述子

# 画像を特徴量とともに描画。
# 入力:im(配列形式の画像),locs(各特徴量の座標とスケール、方向)
def plot_features(im, locs, circle=False):
    def draw_circle(c, r):
        t = numpy.arange(0, 1.01, .01) * 2 * numpy.pi
        x = r * numpy.cos(t) + c[0]
        y = r * numpy.sin(t) + c[1]
        plb.plot(x, y, 'b', linewidth=2)

    plb.imshow(im)

    if circle:
        for p in locs:
            draw_circle(p[:2],p[2])
    else:
        plb.plot(locs[:,0],locs[:,1],'ob')
    plb.axis('off')


if __name__ == '__main__':
    main()

↑こう書くと、↓こう表示されます。(単に座標を表示しているので、全く面白くありませんが) f:id:end0tknr:20171021194701p:plain