差分矩阵求和图像匹配
图像的匹配时基于像素的并比较和计算来实现的方法。将图像中的切片在原图中进行匹配,并标注出来。使用差分算法,它的核心在于差分矩阵,实质为差异矩阵,计算公式如下:
差分矩阵 = 图像A矩阵数据 – 图像B矩阵数据
算法的过程是首先计算两个矩阵数据之间差异分析图像的相似性;然后,设置一个阈值进行比较,如果差分矩阵的所有元素在阈值以内,则表示这两张图像是相似的,且描述了同一个物体。另外,它要求两个图像的大小相同。
编程实现算法的思路是,将切片图在原图中进移动,并计算两个图像的差分矩阵,如果差分矩阵的所有元素之和小于1,则认为找到了切片图在图像中的位置。
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] find = None for now_h in range(0,h-fh): for now_w in range(0,w-fw): comp_tz = myimg[now_h:now_h+fh,now_w:now_w+fw,:]-myimg1 if np.sum(comp_tz)<1: find = now_w, now_h if find != None: cv2.rectangle(myimg, find, (find[0]+fw,find[1]+fh),(255,0,0)) return img
fn1 = 'picturetest.png' fn2 = 'plane.png' myimg = cv2.imread(fn1) myimg1 = cv2.imread(fn2) myimg = showpiclocation(myimg, myimg1) cv2.namedWindow('img') cv2.imshow('img',myimg) cv2.waitKey(2000) cv2.destroyAllWindows()
实验结果如下:
差分矩阵均值进行图像匹配
当数字图像质量较差时,需要计算差分矩阵的均值,并为均值设一个适当的阈值。在目标图中加上少量(50000个)不同颜色的噪声点,从而测试算法在弱噪声环境下的有效性。因为图像质量不高,存在很多噪声点,所以要将差分矩阵均值的阈值设置得稍大一点,这里设为20。通常阈值为10~200,阈值越大,能容忍的噪声越多。
# 少量噪声定位图像 # 随机的位置,随机的像素值 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] find = None for now_h in range(0,h-fh): for now_w in range(0,w-fw): comp_tz = myimg[now_h:now_h+fh,now_w:now_w+fw,:]-myimg1 if abs(np.mean(comp_tz))<10: find = now_w, now_h print('ok') print('.') if find != None: cv2.rectangle(myimg, find, (find[0]+fw,find[1]+fh),(0,0,255)) return img
def addnoise(img, cont): for k in range(0, cont): 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 = 'picturetest.png' fn1 = 'plane.png' myimg = cv2.imread(fn) myimg1 = cv2.imread(fn1) addnoise(myimg,5000) myimg = showpiclocation(myimg,myimg1) cv2.namedWindow('img') cv2.imshow('img',myimg) cv2.waitKey(2000) cv2.destroyAllWindows()
结果如下:
用欧式距离进行图像匹配结果
对强噪声环境下的图像进行匹配时,欧式距离匹配方法相对于以上两种方法的会有更好的效果。
首先在目标图像中加上更多的(500000个)不同颜色的噪声点。
核心算法为:设图像矩阵有n个元素,用n个元素值(x1,x2,…,xn)组成该图像的特征组,特征组形成了n维空间,特征组中的特征码构成每一维的数值。在n维空间下,两个图像矩阵各形成了一个点,然后计算这两个点之间的距离,距离最小者为最匹配的图像。
# 少量噪声定位图像 # 随机的位置,随机的像素值 import cv2 import numpy as np print('loading……')
def get_EuclideanDistance(x,y): myx = np.array(x) myy = np.array(y) return np.sqrt(np.sum((myx-myy)**2))
def findpic(img, findimg, h, fh, w, fw): minds = 1e8 mincb_h = 0 mincb_w = 0 my_findimg = findimg for now_h in range(0, h-fh): for now_w in range(0, w-fw): my_img = img[now_h:now_h+fh,now_w:now_w+fw,:] dis = get_EuclideanDistance(my_img, my_findimg) if dis < minds: mincb_h = now_h mincb_w = now_w minds = dis # 更新最小距离 print('.') find = mincb_w, mincb_h cv2.rectangle(img, find, (find[0]+fw, find[1]+fh), (0,0,255)) return img
def showpiclocation(img,findimg): # 定位图像 w = img.shape[1] h = img.shape[0] fw = findimg.shape[1] fh = findimg.shape[0] return findpic(img,findimg,h,fh,w,fw)
def addnoise(img, cont): for k in range(0, cont): 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 = 'picturetest.png' fn1 = 'plane.png' myimg = cv2.imread(fn) myimg1 = cv2.imread(fn1) addnoise(myimg,500000) myimg = showpiclocation(myimg,myimg1) cv2.namedWindow('img') cv2.imshow('img',myimg) cv2.waitKey(2000) cv2.destroyAllWindows()
结果如下: