图像配准方法(一)
2017-11-07 19:15
465 查看
一:选取ROI与图像进行匹配
openv的aircv库中提供了图像匹配的方法:
以下是demo:
结果为:
以下是拍摄的一组照片,其中7、8、9为特意偏移一段距离后拍摄的。 可以得知对于照片1中所取的ROI(Region Of Interest),图片1-10所对应的坐标为:
1: (224.0, 288.0)
2: (228.0, 291.0)
3: (232.0, 292.0)
4: (228.0, 289.0)
5: (230.0, 291.0)
6: (232.0, 290.0)
7: (230.0, 292.0)
8: (259.0, 290.0)
9: (259.0, 286.0)
10: (265.0, 284.0)
但是假如所取区域为特征不明显区域结果会怎么样呢?
假如取的区域如下图所示:
那么得到的1-10图像匹配结果为:
1: (310.0, 240.0)
2: (314.0, 243.0)
3: (350.0, 229.0)
4: (313.0, 241.0)
5: (316.0, 242.0)
6: (339.0, 232.0)
7: (345.0, 248.0)
8: (35.0, 425.0)
9: (376.0, 233.0)
10:(384.0, 202.0)
容易出现很明显的误匹配,如图8与ROI匹配结果为:
因此ROI的选取是非常重要的。这是需要关注的一个点。
后面在怎么选取ROI区域是一个需要深究的重点问题。
二:直接图像融合
将image 1-7 进行直接求和平均:
结果为:
可以得知图片有些糊了。
三:将图像匹配与直接融合结合起来:
所得到的结果为:
可以看到,图像没有糊掉,但是边缘处由于没有填充像素而呈现出一些黑色。当然这是对于已知的1-7图片(抖动不大)合成的结果。
当加上8-10时(抖动偏移很大的情况),合成结果为:
可见偏移量大的图片对于最后生成的图片还是有很坏的影响的。
总结以上可知,采用图像匹配的方法对准图像以优化流瀑模式的效果是可行的,但是有两点要注意的地方(也是难点)。
(1)寻找合适的ROI(Region Of Interest),以实现图像的精确配准。
(2)去除偏移量较大的图像的方法(上例中的8-10图像)。
openv的aircv库中提供了图像匹配的方法:
以下是demo:
import cv2 import aircv as ac def draw_rectangle(img, pos_1, pos_4, color, line_width): cv2.rectangle(img, pos_1, pos_4, color, line_width) cv2.imshow('objDetect', imsrc) cv2.waitKey(0) cv2.destroyAllWindows() if __name__ == "__main__": imsrc = ac.imread('D:\\python_opencv\\source_image\\image_match\\1.jpg') imobj = imsrc[248:328, 187:261] #第一个参数代表y方向,第二个参数代表x方向,因此在这里取的是(224±37, 288±40) imsrc = ac.imread('D:\\python_opencv\\source_image\\image_match\\2.jpg') # find the match position pos = ac.find_template(imsrc, imobj) print(pos) circle_center_pos = pos['result'] color = (0, 255, 0) line_width = 3 # draw rectangle draw_rectangle(imsrc, (int(circle_center_pos[0])-50, int(circle_center_pos[1])-50), (int(circle_center_pos[0])+ 50, int(circle_center_pos[1])+50), (0, 255, 0), 2)
结果为:
以下是拍摄的一组照片,其中7、8、9为特意偏移一段距离后拍摄的。 可以得知对于照片1中所取的ROI(Region Of Interest),图片1-10所对应的坐标为:
1: (224.0, 288.0)
2: (228.0, 291.0)
3: (232.0, 292.0)
4: (228.0, 289.0)
5: (230.0, 291.0)
6: (232.0, 290.0)
7: (230.0, 292.0)
8: (259.0, 290.0)
9: (259.0, 286.0)
10: (265.0, 284.0)
但是假如所取区域为特征不明显区域结果会怎么样呢?
假如取的区域如下图所示:
那么得到的1-10图像匹配结果为:
1: (310.0, 240.0)
2: (314.0, 243.0)
3: (350.0, 229.0)
4: (313.0, 241.0)
5: (316.0, 242.0)
6: (339.0, 232.0)
7: (345.0, 248.0)
8: (35.0, 425.0)
9: (376.0, 233.0)
10:(384.0, 202.0)
容易出现很明显的误匹配,如图8与ROI匹配结果为:
因此ROI的选取是非常重要的。这是需要关注的一个点。
后面在怎么选取ROI区域是一个需要深究的重点问题。
二:直接图像融合
将image 1-7 进行直接求和平均:
import cv2 import numpy as np ''' def add(a,b,c,d,e,f,g): # 迭代输出行 result = np.zeros((640,480)) for i in range(len(a)): # 迭代输出列 for j in range(len(a[0])): result[i][j] = a[i][j] + b[i][j] + c[i][j] + d[i][j] + e[i][j] + f[i][j] + g[i][j] return result ''' def add(a,b): # 迭代输出行 result = np.zeros((640,480)) for i in range(len(a)): # 迭代输出列 for j in range(len(a[0])): result[i][j] = a[i][j] + b[i][j] return result def typeconvert(a): for i in range(len(a)): # 迭代输出列 for j in range(len(a[0])): a[i][j] = a[i][j] * (256) return a def f(x): return np.float(x) def g(x): return np.int(x) if __name__ == "__main__": imsrc_1 = cv2.imread('D:\\python_opencv\\source_image\\image_match\\1.jpg') imsrc_2 = cv2.imread('D:\\python_opencv\\source_image\\image_match\\2.jpg') imsrc_3 = cv2.imread('D:\\python_opencv\\source_image\\image_match\\3.jpg') imsrc_4 = cv2.imread('D:\\python_opencv\\source_image\\image_match\\4.jpg') imsrc_5 = cv2.imread('D:\\python_opencv\\source_image\\image_match\\5.jpg') imsrc_6 = cv2.imread('D:\\python_opencv\\source_image\\image_match\\6.jpg') imsrc_7 = cv2.imread('D:\\python_opencv\\source_image\\image_match\\7.jpg') imsrc_8 = cv2.imread('D:\\python_opencv\\source_image\\image_match\\8.jpg') print(imsrc_1.dtype) ''' imsrc_8 = cv2.imread('D:\\python_opencv\\source_image\\image_match\\8.jpg') imsrc_9 = cv2.imread('D:\\python_opencv\\source_image\\image_match\\9.jpg') imsrc_10 = cv2.imread('D:\\python_opencv\\source_image\\image_match\\10.jpg') ''' #imsrc_sum = add(imsrc_1, imsrc_2, imsrc_3, imsrc_4, imsrc_5, imsrc_6, imsrc_7) f2 = np.vectorize(f)#让函数矩阵化,解决只能一对一强制性变换这一要求 imsrc_1 = f2(imsrc_1) imsrc_2 = f2(imsrc_2) imsrc_sum = imsrc_1 + imsrc_2 + imsrc_3 + imsrc_4 + imsrc_5 + imsrc_6 + imsrc_7 imsrc_average = imsrc_sum/7 #imsrc_sum = add(imsrc_1, imsrc_2) g2 = np.vectorize(g)#让函数矩阵化,解决只能一对一强制性变换这一要求 #imsrc_average = g2(imsrc_average) #imsrc_average = np.unit8(imsrc_average) print(g2(imsrc_average)) cv2.imshow('merge', typeconvert(g2(imsrc_average))) cv2.waitKey(0) cv2.destroyAllWindows() ''' imsrc_sum = cv2.addWeighted(imsrc_1, 0.5, imsrc_4, 0.5, 0) print(imsrc_sum) imsrc_average = imsrc_sum/7 #print(imsrc_average) cv2.imshow('merge', imsrc_sum) cv2.waitKey(0) cv2.destroyAllWindows() '''
结果为:
可以得知图片有些糊了。
三:将图像匹配与直接融合结合起来:
import cv2 import aircv as ac import numpy as np def draw_rectangle(img, pos_1, pos_4, color, line_width): cv2.rectangle(img, pos_1, pos_4, color, line_width) cv2.imshow('objDetect', imsrc) cv2.waitKey(0) cv2.destroyAllWindows() def translate(img, x, y): H = np.float32([[1,0,x],[0,1,y]]) rows,cols = img.shape[:2] res = cv2.warpAffine(img,H,(cols,rows)) #需要图像、变换矩阵、变换后的大小 return res def findposition(img): imsrc = ac.imread('C:\\opencv_python\\img_source\\img\\1.jpg') imtemplate = imsrc[248:328, 187:261] #第一个参数代表y方向,第二个参数代表x方向 imsrc = img # find the match position pos = ac.find_template(imsrc, imtemplate) center_pos = pos['result'] return center_pos def add(a,b): # 迭代输出行 result = np.zeros((640,480)) for i in range(len(a)): # 迭代输出列 for j in range(len(a[0])): result[i][j] = a[i][j] + b[i][j] return result def typeconvert(a): for i in range(len(a)): # 迭代输出列 for j in range(len(a[0])): a[i][j] = a[i][j] * (256) return a def f(x): return np.float(x) def g(x): return np.int(x) if __name__ == "__main__": imsrc_1 = cv2.imread('C:\\opencv_python\\img_source\\img\\1.jpg') imsrc_2 = cv2.imread('C:\\opencv_python\\img_source\\img\\2.jpg') imsrc_3 = cv2.imread('C:\\opencv_python\\img_source\\img\\3.jpg') imsrc_4 = cv2.imread('C:\\opencv_python\\img_source\\img\\4.jpg') imsrc_5 = cv2.imread('C:\\opencv_python\\img_source\\img\\5.jpg') imsrc_6 = cv2.imread('C:\\opencv_python\\img_source\\img\\6.jpg') imsrc_7 = cv2.imread('C:\\opencv_python\\img_source\\img\\7.jpg') imsrc_8 = cv2.imread('C:\\opencv_python\\img_source\\img\\8.jpg') position_1 = findposition(imsrc_1) print(position_1[0]) print(position_1[1]) position_2 = findposition(imsrc_2) position_3 = findposition(imsrc_3) position_4 = findposition(imsrc_4) position_5 = findposition(imsrc_5) position_6 = findposition(imsrc_6) position_7 = findposition(imsrc_7) print(imsrc_1.shape) print(position_1[0] - position_2[0]) print(position_1[1] - position_2[1]) imsrc_1 = translate(imsrc_1, position_1[0] - position_1[0], position_1[1] - position_1[1]) imsrc_2 = translate(imsrc_2, position_1[0] - position_2[0], position_1[1] - position_2[1]) imsrc_3 = translate(imsrc_3, position_1[0] - position_3[0], position_1[1] - position_3[1]) imsrc_4 = translate(imsrc_4, position_1[0] - position_4[0], position_1[1] - position_4[1]) imsrc_5 = translate(imsrc_5, position_1[0] - position_5[0], position_1[1] - position_5[1]) imsrc_6 = translate(imsrc_6, position_1[0] - position_6[0], position_1[1] - position_6[1]) imsrc_7 = translate(imsrc_7, position_1[0] - position_7[0], position_1[1] - position_7[1]) ''' imsrc_8 = cv2.imread('D:\\python_opencv\\source_image\\image_match\\8.jpg') imsrc_9 = cv2.imread('D:\\python_opencv\\source_image\\image_match\\9.jpg') imsrc_10 = cv2.imread('D:\\python_opencv\\source_image\\image_match\\10.jpg') ''' #imsrc_sum = add(imsrc_1, imsrc_2, imsrc_3, imsrc_4, imsrc_5, imsrc_6, imsrc_7) print(imsrc_1.shape) f2 = np.vectorize(f)#让函数矩阵化,解决只能一对一强制性变换这一要求 imsrc_1 = f2(imsrc_1) imsrc_2 = f2(imsrc_2) imsrc_sum = imsrc_1 + imsrc_2 + imsrc_3 + imsrc_4 + imsrc_5 + imsrc_6 + imsrc_7 imsrc_average = imsrc_sum/7 #imsrc_sum = add(imsrc_1, imsrc_2) g2 = np.vectorize(g)#让函数矩阵化,解决只能一对一强制性变换这一要求 #imsrc_average = g2(imsrc_average) #imsrc_average = np.unit8(imsrc_average) #print(g2(imsrc_average)) cv2.imshow('merge', typeconvert(g2(imsrc_average))) cv2.waitKey(0) cv2.destroyAllWindows() ''' imsrc_sum = cv2.addWeighted(imsrc_1, 0.5, imsrc_4, 0.5, 0) print(imsrc_sum) imsrc_average = imsrc_sum/7 #print(imsrc_average) cv2.imshow('merge', imsrc_sum) cv2.waitKey(0) cv2.destroyAllWindows() '''
所得到的结果为:
可以看到,图像没有糊掉,但是边缘处由于没有填充像素而呈现出一些黑色。当然这是对于已知的1-7图片(抖动不大)合成的结果。
当加上8-10时(抖动偏移很大的情况),合成结果为:
可见偏移量大的图片对于最后生成的图片还是有很坏的影响的。
总结以上可知,采用图像匹配的方法对准图像以优化流瀑模式的效果是可行的,但是有两点要注意的地方(也是难点)。
(1)寻找合适的ROI(Region Of Interest),以实现图像的精确配准。
(2)去除偏移量较大的图像的方法(上例中的8-10图像)。
相关文章推荐