赞
踩
医疗图像的配准问题研究报告
我们在对医疗图像进行分析的过程中,通常会遇到许多的问题,比如图像位置不正确,摆放不整齐,这样对于医疗疾病的判断会有很大的影响,因此我们需要对医疗仪器测量的图片进行校准配齐。
1.主要原理
图像对齐或者说图像配准实际上是一种仿射变换,图像是可以旋转的,同时经过对齐技术处理后,可以保证和左边的模版是一样的,这样就将不规则的图像变得规则起来,在这种技术中,要在一个图像中检测到一组特征点,并与另一张图像中的特征点匹配,在根据这些匹配的特征点计算出一个转换规则,从而可以将一个图像映射到另一个图像上。
2.基础理论
图像对齐的核心技术实际上是一种维数为33的一个单适应矩阵,要满足一个单适应矩阵首先要满足两个条件,其一:两幅图像表示的是同一个平面,即两幅要配准的图像保持着同一空间维度;其二:这两幅照片通过旋转照相机来拍摄,也即是两幅图像是可以相互旋转的。单适应矩阵就是一个简单的33矩阵
假设(x1,y1)是第一张图片上的点,(x2,y2)是第二张图片上的同一个物理点,那么使用单应性矩阵可以映射他们:
通过矩阵的映射转换可以看到,把所像素上的所有图像都这么转换后,两张图片上的同一个物理平面就会呈现相同的角度和大小
3.实现方法
了解到主要的理论原理后发现,之后最为基本的部分就是去寻找类似于(x1,y1)这样的点,这些在图像中能够表达一定信息且十分稳定的点我们称之为关键点或者说是特征点,在OpenCV和Python的联合实现中有很多算法都可以去实现特征点的选取和实现,但是目前几种有名的算法比如SIFT,SURF算法等都拥有专利限制,受困于此,我们主要去采用ORB算法。
ORB算法的本是带有方向的FAST特征点和旋转的BRIEF因子组成,正因为FAST因子导致ORB算法的检测速度十分快,效率十分高。特征点的检测主要由两部分组成:其一便是定位器,这个模块要找到图片上的具有旋转不变性,缩放不变性,仿射不变性的特征点。定位器找到这些点的x,y坐标。这就是FAST因子,找到特征点的速度十分的快;其二便是描述子,我们找到特征点后需要对这些特征点进行一些变换,同时还需采用一定的方法来区分这么多特征点,便于后续进行仿射变换操作。在这里,我们主要采用的是对特征点的外观进行编码,特征点用一连串的数字来表示,不同的图片对于同一个物理点应该有相同的编码序列,也即有相同的描述子。
4.实现图像匹配的步骤
下面的代码进行图像对齐的步骤:
1.读取图片到内存。
2.检测特征点:为两张图检测ORB特征点。为了计算单应性矩阵4个就够了,但是一般会检测到成百上千的特征点。可以使用参数MAX_FEATURES 来控制检测的特征点的数量。检测特征点并计算描述子的函DetectAndCompute。
3.特征匹配:找到两图中匹配的特征点,并按照匹配度排列,保留最匹配的一小部分。然后把匹配的特征点画出来并保存图片到磁盘。我们使用汉明距离来度量两个特征点描述子的相似度。下图中把匹配的特征点用线连起来了。注意,有很多错误匹配的特征点,所以下一步要用一个健壮的算法来计算单应性矩阵。
4.计算单适应矩阵:上一步产生的匹配的特征点不是100%正确的,就算只有20~30%的匹配是正确的也不罕见。FindHomography 函数使用一种被称为随机抽样一致算法(Random Sample Consensus )的技术在大量匹配错误的情况下计算单应性矩阵。
5.扭转图像:有了精确的单应性矩阵,就可以把一张图片的所有像素映射到另一个图片。warpPerspective 函数用来完成这个功能。
6.实现代码
from skimage import io import cv2 as cv import numpy as np import matplotlib.pyplot as plt img_path1 = '/Users/yja/Desktop/0-fixed.png' img_path2 = '/Users/yja/Desktop/0-moving.png' img1 = io.imread(img_path1) img2 = io.imread(img_path2) img1 = np.uint8(img1) img2 = np.uint8(img2) # find the keypoints and descriptors with ORB orb = cv.ORB_create() kp1, des1 = orb.detectAndCompute(img1,None) kp2, des2 = orb.detectAndCompute(img2,None) # def get_good_match(des1,des2): # bf = cv.BFMatcher() # matches = bf.knnMatch(des1, des2, k=2) # good = [] # for m, n in matches: # if m.distance < 0.75 * n.distance: # good.append(m) # return good,matches # goodMatch,matches = get_good_match(des1,des2) # img3 = cv.drawMatchesKnn(img1,kp1,img2,kp2,matches[:20],None,flags=2) # create BFMatcher object bf = cv.BFMatcher(cv.NORM_HAMMING, crossCheck=True) # Match descriptors. matches = bf.match(des1,des2) # Sort them in the order of their distance. matches = sorted(matches, key = lambda x:x.distance) # Draw first 20 matches. img3 = cv.drawMatches(img1,kp1,img2,kp2,matches[:20],None, flags=2) goodMatch = matches[:20] if len(goodMatch) > 4: ptsA= np.float32([kp1[m.queryIdx].pt for m in goodMatch]).reshape(-1, 1, 2) ptsB = np.float32([kp2[m.trainIdx].pt for m in goodMatch]).reshape(-1, 1, 2) ransacReprojThreshold = 4 H, status =cv.findHomography(ptsA,ptsB,cv.RANSAC,ransacReprojThreshold); #其中H为求得的单应性矩阵矩阵 #status则返回一个列表来表征匹配成功的特征点。 #ptsA,ptsB为关键点 #cv2.RANSAC, ransacReprojThreshold这两个参数与RANSAC有关 imgOut = cv.warpPerspective(img2, H, (img1.shape[1],img1.shape[0]),flags=cv.INTER_LINEAR + cv.WARP_INVERSE_MAP) # 叠加配准变换图与基准图 overlapping = cv.addWeighted(img1, 0.6, img2, 0.4, 0) io.imsave('/Users/yja/Desktop/0-moving.png', overlapping) # 显示对比 plt.subplot(221) plt.title('orb') plt.imshow(img3) plt.subplot(222) plt.title('imgOut') plt.imshow(img2) plt.subplot(223) plt.title('overlapping') plt.imshow(overlapping) plt.show()
7.仿真结果
可以看到我们对给定的0和8的数字识别图像可以看到对数字0和数字8取了特征点后图像能够很好的被矫正,将斜着的图像旋转至正图像与原图像重叠校准,如果图像并不匹配,那么重叠图像后应该会出现很多的红色部分,可是将这些图像进行重叠后可以看到基本上都是绿色,这说明两幅图像实际上可以当作是一幅图像,同时两幅图像可以很好的完成配准操作。
对数字8的配准
对数字0的配准
8.小结
图像配准实际上就是图像的仿射变换,采用ORB算法就可以快速的实现两幅图像的配准,对于另外比较常用的SIFT算法实际思路也与ORB算法是一样的,只需要将编译器的Python版本降到3.4以下就可以了,依旧是选取采样点做匹配。
常见的医疗图像处理就是这样的,对两幅甚至多幅图像进行匹配校准,图像对齐,方法几乎一样没什么太大的创意,基本上主要优化是对于处理速度和特征点选取的优化!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。