opencvコンピュータ視覚学習ノート5

59682 ワード

第六章画像検索及び画像記述子による検索
特徴を抽出して画像のマッチングと検索を行う.
1特徴検出アルゴリズム
一般的な特徴と抽出アルゴリズム:
Harris検出角点
Sift検出スポット(blob)には特許保護があります.
Surf検出スポットには特許保護があります.
Fast検出角点
Brief検出スポット
Orbバンド方向のfastアルゴリズムと回転不変性を持つbrifアルゴリズム
特徴の定義
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2016/12/5 12:30
# @Author : Retacn
# @Site :        
# @File : cornerHarris.py
# @Software: PyCharm
__author__ = "retacn"
__copyright__ = "property of mankind."
__license__ = "CN"
__version__ = "0.0.1"
__maintainer__ = "retacn"
__email__ = "[email protected]"
__status__ = "Development"

import cv2
import numpy as np

#     
img = cv2.imread('../test1.jpg')
#       
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = np.float32(gray)
#       
dst = cv2.cornerHarris(gray,
 2,
 23, # sobel     ,3-31     
 0.04)
#             
img[dst > 0.01 * dst.max()] = [0, 0, 255]
while (True):
 cv2.imshow("corners", img)
 if cv2.waitKey(33) & 0xFF == ord('q'):
 break
cv2.destroyAllWindows()
dogとsiftを用いて特徴抽出と説明を行う.
サンプルコードは以下の通りです
import cv2
import sys
import numpy as py

#     
# imgpath=sys.argv[1]
imgpath = '../test1.jpg'
img = cv2.imread(imgpath)
#       
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#   sift  ,      ,   dog    
sift = cv2.xfeatures2d.SIFT_create()
keypoints, descriptor = sift.detectAndCompute(gray, None)

# print(keypoints)
#           
# angle        
# class_id     id
# octave           
# pt          
# response         
# size        
img = cv2.drawKeypoints(image=img,
 outImage=img,
 keypoints=keypoints,
 color=(51, 163, 236),
 flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

#     
cv2.imshow('sift_keypoints', img)
while (True):
 if cv2.waitKey(int(1000 / 12)) & 0xFF == ord('q'):
 break
cv2.destroyAllWindows()
心には高速hessianアルゴリズムとSURFを使って特徴を抽出します.
サンプルコードは以下の通りです.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2016/12/10 17:30
# @Author : Retacn
# @Site : sift      
# @File : sift.py
# @Software: PyCharm
__author__ = "retacn"
__copyright__ = "property of mankind."
__license__ = "CN"
__version__ = "0.0.1"
__maintainer__ = "retacn"
__email__ = "[email protected]"
__status__ = "Development"

import cv2
import sys
import numpy as py

#     
# imgpath=sys.argv[1]
# alg=sys.argv[2]
# threshold=sys.argv[3]

imgpath = '../test1.jpg'
img = cv2.imread(imgpath)
# alg = 'SURF'
alg = 'SIFT'
# threshold = '8000'
#          
threshold = '4000'


def fd(algorithm):
 if algorithm == 'SIFT':
 return cv2.xfeatures2d.SIFT_create()
 if algorithm == 'SURF':
 # return cv2.xfeatures2d.SURF_create(float(threshold) if len(sys.argv) == 4 else 4000)
 return cv2.xfeatures2d.SURF_create(float(threshold))


#       
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#   sift  ,      ,   dog    
fd_alg = fd(alg)
keypoints, descriptor = fd_alg.detectAndCompute(gray, None)

# print(keypoints)
#           
# angle        
# class_id     id
# octave           
# pt          
# response         
# size        
img = cv2.drawKeypoints(image=img,
 outImage=img,
 keypoints=keypoints,
 color=(51, 163, 236),
 flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

#     
cv2.imshow('keypoints', img)
while (True):
 if cv2.waitKey(int(1000 / 12)) & 0xFF == ord('q'):
 break
cv2.destroyAllWindows()
ORBに基づく特徴検出と特徴マッチング
ORBはベースです
FAST(feature sfrom accersterated segment test)ポイント検出技術
ピクセルの周りに円を描き、16ピクセルを含む.
BRIF(binaryrobust independent element ary feature)記述子
暴力(bruute-force)マッチング法
二つのディスクリプタを比較して、マッチ結果を生成します.
ORBの特徴マッチング
サンプルコードは以下の通りです

import numpy as np
import cv2
from matplotlib import pyplot as plt

cv2.ocl.setUseOpenCL(False)
#       
img1 = cv2.imread('../test2_part.jpg', cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('../test2.jpg', cv2.IMREAD_GRAYSCALE)

#   orb         
orb = cv2.ORB_create()
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)

#     
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)

#     
img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:40], img2, flags=2)
plt.imshow(img3), plt.show()
以下のエラーを報告します
cv 2.error:D:\Build\OpenCV\opencv-31.0\modules\python\src 2\cv 2.cpp:163:error:(-215)The data shound normally be NULL!in functionNumpyAllocator::allocate
解決方法は、次のコードを追加します.
cv2.ocl.setUseOpenCL(False)
k最近接配匹

import numpy as np
import cv2
from matplotlib import pyplot as plt

cv2.ocl.setUseOpenCL(False)
#       
img1 = cv2.imread('../test2_part.jpg', cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('../test2.jpg', cv2.IMREAD_GRAYSCALE)

#   orb         
orb = cv2.ORB_create()
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)

# knn  ,  k   
bf = cv2.BFMatcher(cv2.NORM_L1, crossCheck=False)
matches = bf.knnMatch(des1, des2, k=2)

#     
img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, matches, img2, flags=2)
plt.imshow(img3), plt.show()
Flannマッチング法
Fast library for approximate nearesneighborsは最近隣の快速倉庫に近似します.

import numpy as np
import cv2
from matplotlib import pyplot as plt

#     
queryImage = cv2.imread('../test2_part.jpg', cv2.IMREAD_GRAYSCALE)
trainingImage = cv2.imread('../test2.jpg', cv2.IMREAD_GRAYSCALE)

#   sift  
sift = cv2.xfeatures2d.SIFT_create()
kp1, des1 = sift.detectAndCompute(queryImage, None)
kp2, des2 = sift.detectAndCompute(trainingImage, None)

FLANN_INDEX_KDTREE = 0
#       
indexParams = dict(algorithm=FLANN_INDEX_KDTREE, trees=5) #     
searchParams = dict(checks=50) #     ,            

flann = cv2.FlannBasedMatcher(indexParams, searchParams)

matches = flann.knnMatch(des1, des2, k=2)

matchesMask = [[0, 0] for i in range(len(matches))]

for i, (m, n) in enumerate(matches):
 if m.distance < 0.7 * n.distance:
 matchesMask[i] = [1, 0]
drawParams = dict(matchColor=(0, 255, 0),
 singlePointColor=(255, 0, 0),
 matchesMask=matchesMask,
 flags=0)

resultImage = cv2.drawMatchesKnn(queryImage, kp1, trainingImage, kp2, matches, None, **drawParams)
plt.imshow(resultImage), plt.show()
運転結果は以下の通りです
Flannシングルマッチ
サンプルコードは以下の通りです
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2016/12/11 12:02
# @Author : Retacn
# @Site : flann      
# @File : flann_homography.py
# @Software: PyCharm
__author__ = "retacn"
__copyright__ = "property of mankind."
__license__ = "CN"
__version__ = "0.0.1"
__maintainer__ = "retacn"
__email__ = "[email protected]"
__status__ = "Development"

import numpy as np
import cv2
from matplotlib import pyplot as plt

MIN_MATCH_COUNT = 10

#     
img1 = cv2.imread('../test3_part.jpg', cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('../test3.jpg', cv2.IMREAD_GRAYSCALE)

#   sift  
sift = cv2.xfeatures2d.SIFT_create()
#          
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

FLANN_INDEX_KDTREE = 0
#       
indexParams = dict(algorithm=FLANN_INDEX_KDTREE, trees=5) #     
searchParams = dict(checks=50) #     ,            

flann = cv2.FlannBasedMatcher(indexParams, searchParams)

matches = flann.knnMatch(des1, des2, k=2)

good = []
for m, n in matches:
 if m.distance < 0.7 * n.distance:
 good.append(m)

if len(good) > MIN_MATCH_COUNT:
 #                 
 src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
 dst_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)

 #    
 M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
 matchesMask = mask.ravel().tolist()

 #                     ,     
 h, w = img1.shape
 pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]).reshape(-1, 1, 2)
 dst = cv2.perspectiveTransform(pts, M)
 img2 = cv2.polylines(img2, [np.int32(dst)], True, 255, 3, cv2.LINE_AA)
else:
 print("Not enough matches are found -%d/%d" % (len(good), MIN_MATCH_COUNT))
 matchesMask = None

#     
draw_params = dict(matchColor=(0, 255, 0), #   
 singlePointColor=None,
 matchesMask=matchesMask,
 flags=2)
img3 = cv2.drawMatches(img1, kp1, img2, kp2, good, None, **draw_params)
plt.imshow(img3, 'gray'), plt.show()
運転結果は以下の通りです
タトゥーに基づいて証明書を取るアプリケーションの例
A画像記述子をファイルに保存する
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2016/12/11 13:52
# @Author : Retacn
# @Site :             
# @File : generate_descriptors.py
# @Software: PyCharm
__author__ = "retacn"
__copyright__ = "property of mankind."
__license__ = "CN"
__version__ = "0.0.1"
__maintainer__ = "retacn"
__email__ = "[email protected]"
__status__ = "Development"

import cv2
import numpy as np
from os import walk
from os.path import join
import sys


#      
def create_descriptors(folder):
 files = []
 for (dirpath, dirnames, filenames) in walk(folder):
 files.extend(filenames)
 for f in files:
 save_descriptor(folder, f, cv2.xfeatures2d.SIFT_create())


#      
def save_descriptor(folder, image_path, feature_detector):
 print("reading %s" % image_path)
 if image_path.endswith("npy") or image_path.endswith("avi"):
 return
 img = cv2.imread(join(folder, image_path), cv2.IMREAD_GRAYSCALE)
 keypoints, descriptors = feature_detector.detectAndCompute(img, None)
 descriptor_file = image_path.replace("jpg", "npy")
 np.save(join(folder, descriptor_file), descriptors)


#             
dir = sys.argv[1]
create_descriptors(dir)
Bスキャンマッチング
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2016/12/11 14:05
# @Author : Retacn
# @Site :     
# @File : scan4matches.py
# @Software: PyCharm
__author__ = "retacn"
__copyright__ = "property of mankind."
__license__ = "CN"
__version__ = "0.0.1"
__maintainer__ = "retacn"
__email__ = "[email protected]"
__status__ = "Development"

from os.path import join
from os import walk
import numpy as np
import cv2
from sys import argv
from matplotlib import pyplot as plt

#        
folder = argv[1]
query = cv2.imread(join(folder, 'part.jpg'), cv2.IMREAD_GRAYSCALE)

#        ,  ,   
files = []
images = []
descriptors = []
for (dirpath, dirnames, filenames) in walk(folder):
 files.extend(filenames)
 for f in files:
 if f.endswith('npy') and f != 'part.npy':
 descriptors.append(f)
 print(descriptors)

#   sift   
sift = cv2.xfeatures2d.SIFT_create()
query_kp, query_ds = sift.detectAndCompute(query, None)

#   flann  
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params, search_params)

#      
MIN_MATCH_COUNT = 10

potential_culprits = {}
print(">> Initiating picture scan...")
for d in descriptors:
 print("--------- analyzing %s for matches ------------" % d)
 matches = flann.knnMatch(query_ds, np.load(join(folder, d)), k=2)
 good = []
 for m, n in matches:
 if m.distance < 0.7 * n.distance:
 good.append(m)
 if len(good) > MIN_MATCH_COUNT:
 print('%s is a match! (%d)' % (d, len(good)))
 else:
 print('%s is not a match ' % d)
 potential_culprits[d] = len(good)

max_matches = None
potential_suspect = None
for culprit, matches in potential_culprits.items():
 if max_matches == None or matches > max_matches:
 max_matches = matches
 potential_suspect = culprit
print("potential suspect is %s" % potential_suspect.replace("npy", "").upper())