图像匹配算法

图像匹配算法基于像素比较求和实现。

差分矩阵求和

通过计算两个图像矩阵数据之间的差异分析图像的相似性,然后设置阀值进行比较,公式如下:

1
差分矩阵 = 图像A矩阵数据 - 图像B矩阵数据

Python实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

def show_pic_location(img, findimg):
"""
show_pic_location
:param img:
:param findimg:
:return:
"""
w = img.shape[1]
h = img.shape[0]
fw = findimg.shape[1]
fh = findimg.shape[0]
findpt = None
for now_h in xrange(h - fh):
for now_w in xrange(w - fw):
comp_tz = img[now_h:now_h + fh, now_w: now_w + fw, :] - findimg
if np.sum(comp_tz) < 1:
findpt = now_w, now_h
if findpt is not None:
cv2.rectangle(img, findpt, (findpt[0] + fw, findpt[1] + fh), (255, 0, 0))
return img

差分矩阵均值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

def show_pic_location(img, findimg):
"""
show_pic_location
:param img:
:param findimg:
:return:
"""
w = img.shape[1]
h = img.shape[0]
fw = findimg.shape[1]
fh = findimg.shape[0]
findpt = None
for now_h in xrange(h - fh):
for now_w in xrange(w - fw):
comp_tz = img[now_h:now_h + fh, now_w: now_w + fw, :] - findimg
if abs(np.mean(comp_tz)) < 20:
findpt = now_w, now_h
if findpt is not None:
cv2.rectangle(img, findpt, (findpt[0] + fw, findpt[1] + fh), (255, 0, 0))
return img

欧氏距离匹配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

def show_pic_location(img, findimg):
"""
show_pic_location
:param img:
:param findimg:
:return:
"""
w = img.shape[1]
h = img.shape[0]
fw = findimg.shape[1]
fh = findimg.shape[0]

minds = 1e8
mincb_h = 0
mincb_w = 0

for now_h in xrange(h - fh):
for now_w in xrange(w - fw):
my_img = img[now_h:now_h + fh, now_w: now_w + fw, :]
my_findimg = findimg
myx = np.array(my_img)
myy = np.array(my_findimg)
dis = np.sqrt(np.sum((myx - myy) * (myx - myy)))
if dis < minds:
mincb_h = now_h
mincb_w = now_w
minds = dis
print mincb_h, mincb_w, minds

findpt = mincb_w, mincb_h
cv2.rectangle(img, findpt, (findpt[0] + fw, findpt[1] + fh), (0, 0, 255))
return img

添加噪音

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

def add_noise(img):
"""
add_noise
:param img:
:return:
"""
count = 50000
for k in xrange(count):
xi = int(np.random.uniform(0, img.shape[1]))
xj = int(np.random.uniform(0, img.shape[0]))
img[xj, xi, 0] = 255 * np.random.rand()
img[xj, xi, 1] = 255 * np.random.rand()
img[xj, xi, 2] = 255 * np.random.rand()

原始图像
原始图像

待匹配图像

待匹配图像

加噪点匹配图像

加入噪点匹配图像

旋转加噪点匹配图像

旋转加噪点匹配图像

完整代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

#! /usr/bin/python
# -*- coding:utf-8 -*-
"""
@author: abc
@file: euclidean_distance.py
@date: 2016-12-09
@desc: 欧式距离匹配
"""
__author__ = "abc"

import cv2
import numpy as np


def show_pic_location(img, findimg):
"""
show_pic_location
:param img:
:param findimg:
:return:
"""
w = img.shape[1]
h = img.shape[0]
fw = findimg.shape[1]
fh = findimg.shape[0]

minds = 1e8
mincb_h = 0
mincb_w = 0

for now_h in xrange(h - fh):
for now_w in xrange(w - fw):
my_img = img[now_h:now_h + fh, now_w: now_w + fw, :]
my_findimg = findimg
dis = get_euclidean_distance(my_img, my_findimg)
if dis < minds:
mincb_h = now_h
mincb_w = now_w
minds = dis
print mincb_h, mincb_w, minds

findpt = mincb_w, mincb_h
cv2.rectangle(img, findpt, (findpt[0] + fw, findpt[1] + fh), (0, 0, 255))
return img


def get_euclidean_distance(x, y):
"""
计算欧氏距离
:param x:
:param y:
:return:
"""
myx = np.array(x)
myy = np.array(y)
return np.sqrt(np.sum((myx - myy) * (myx - myy)))


def add_noise(img):
"""
add_noise
:param img:
:return:
"""
count = 50000
for k in xrange(count):
xi = int(np.random.uniform(0, img.shape[1]))
xj = int(np.random.uniform(0, img.shape[0]))
img[xj, xi, 0] = 255 * np.random.rand()
img[xj, xi, 1] = 255 * np.random.rand()
img[xj, xi, 2] = 255 * np.random.rand()


def handle_img(imgpath, imgpath1, imgpath2):
"""
handle_img
:param imgpath:
:param imgpath1:
:param imgpath2:
:return:
"""
myimg = cv2.imread(imgpath)
myimg1 = cv2.imread(imgpath1)
myimg2 = cv2.imread(imgpath2)

add_noise(myimg)

myimg = show_pic_location(myimg, myimg1)
myimg = show_pic_location(myimg, myimg2)

cv2.namedWindow('img')
cv2.imshow('img', myimg)
cv2.waitKey()
cv2.destroyAllWindows()


if __name__ == "__main__":
imgpath = "/home/abc/Projects/machine_learning/img/test_r45.png"
imgpath1 = "/home/abc/Projects/machine_learning/img/test_1.png"
imgpath2 = "/home/abc/Projects/machine_learning/img/test_2.png"
handle_img(imgpath, imgpath1, imgpath2)