numpy使用指南[菜鸟教程]http://www.runoob.com/numpy/numpy-tutorial.html
opencv使用指南[官方文档]http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/tutorials.html
实现差分矩阵的算法
差分矩阵求和算法的核心在于差分矩阵,实质为差异矩阵。
计算公式为:差分矩阵=图像A矩阵数据-图像B矩阵数据
首先,计算两个图像的矩阵数据之间差异分析图像的相似性;然后,设置一个阈值进行比较,如果差分矩阵的所有元素之和在阈值以内,则表示这两张图像是相似的,且描述了同一物体。
def showpiclocation(img,findimg):
# 定位图像
w = img.shape[1]
h = img.shape[0]
fw = findimg.shape[1]
fh = findimg.shape[0]
findpt = None
for now_h in range(0,h-fh):
for now_w in range(0, 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
print('.',)
if findpt != None:
print('fw is %d' % fw)
cv2.rectangle(img, findpt, (findpt[0]+fw, findpt[1]+fh),(255,0,0))
return img
完整代码如下
#-*- coding:utf-8 -*-
#code:1054263694@qq.com
#Imagelocation.py
import cv2
import numpy as np
print('loading')
def showpiclocation(img,findimg):
# 定位图像
w = img.shape[1]
h = img.shape[0]
fw = findimg.shape[1]
fh = findimg.shape[0]
findpt = None
for now_h in range(0,h-fh):
for now_w in range(0, 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 != None:
print('fw is %d' % fw)
cv2.rectangle(img, findpt, (findpt[0]+fw, findpt[1]+fh),(255,0,0))
return img
fn = 'test.jpg'
fn1 = 'testsmall.jpg'
myimg = cv2.imread(fn)
myimg1 = cv2.imread(fn1)
myimg = showpiclocation(myimg,myimg1)
cv2.namedWindow('img2')
cv2.imshow('img',myimg)
cv2.waitKey()
cv2.destroyAllWindows()
实际效果如图
原图如下
注意:裁剪的图片必须是原图副本经过win10画图工具(或PS等其他软件)进行裁剪后直接保存得到,以下情况可能会得不到结果:
(1)对原图进行截图。其得到的屏幕捕捉截图,与原图像素矩阵不一致
(2)对原图进行裁剪另存为得到裁剪图。图片被jpeg或png等格式算法压缩调整过,与原图像素矩阵不一致
给图像加上噪声的算法()
给图像人为加噪声的一种方式是,将图像若干个像素点的值设置为噪声点的值。比如,为图像加上5000个像素值为[15,10,5]的像素点,编写代码如下
#-*- coding:utf-8 -*-
#code:1054263694@qq.com
#Imagelocation.py
import cv2
import numpy as np
fn="test.jpg"
if __name__ == "__main__":
print('loading...')
img = cv2.imread(fn)
def addnoise(img):
coutn = 5000
for k in range(0,coutn):
xi = int(np.random.uniform(0,img.shape[1]))
xj = int(np.random.uniform(0,img.shape[0]))
img[xj,xi,0] = 15
img[xj,xi,1] = 10
img[xj,xi,2] = 5
addnoise(img)
cv2.namedWindow('img')
cv2.imshow('img',img)
cv2.waitKey()
cv2.destroyAllWindows()
实际效果如图
或者是加上5000个色彩随机的像素点
#-*- coding:utf-8 -*-
#code:1054263694@qq.com
#Imagelocation.py
import cv2
import numpy as np
fn="test.jpg"
if __name__ == "__main__":
print('loading...%s'%fn)
img = cv2.imread(fn)
def addnoise(img):
coutn = 5000
for k in range(0,coutn):
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()
addnoise(img)
cv2.namedWindow('img')
cv2.imshow('img',img)
cv2.waitKey()
cv2.destroyAllWindows()
实际效果如下
我们尝试下在强噪声环境下图片匹配的实际效果
很明显这种简单的图像匹配算法只适用于对原图像裁剪出来的部分进行识别,对于有噪点甚至强噪声环境下不适用,根本就不显示结果 下面我们引进差分矩阵均值算法,来解决这一问题
当数字图像质量较差时,则需要计算差分矩阵的均值,并为均值设一个适当的阈值。
差分矩阵均值图像匹配完整代码如下
#-*- coding:utf-8 -*-
#code:1054263694@qq.com
#Imagelocation.py
import cv2
import numpy as np
print('loading...')
def showpiclocation(img,findimg):
# 定位图像
w = img.shape[1]
h = img.shape[0]
fw = findimg.shape[1]
fh = findimg.shape[0]
findpt = None
for now_h in range(0,h-fh):
for now_w in range(0,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
print('ok')
print ('.')
if findpt != None:
cv2.rectangle(img,findpt,(findpt[0]+fw, findpt[1]+fh),(0,0,255))
return img
def addnoise(img):
coutn = 5000
for k in range(0,coutn):
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()
fn = 'big.png'
fn1 = 'small.png'
myimg = cv2.imread(fn)
myimg1 = cv2.imread(fn1)
addnoise(myimg)
myimgf = showpiclocation(myimg,myimg1)
cv2.namedWindow('img')
cv2.imshow('img',myimgf)
cv2.waitKey()
cv2.destroyAllWindows()
实际效果如图
当我们将噪声点数量增加到1000000+数量级,阈值增加到100时,整个图片糊成一片 ,图像匹配失败
注意:差分矩阵的阈值一般为10~200,阈值越大,能容忍的噪声点越多。如果阈值超过200,最好使用欧氏距离算法。