图片处理之模式匹配(match_template)

以一张脸部皮肤切片中的毛孔作为研究对象,使用模式匹配寻找到该切片中所有的毛孔

1.选取切片,并找到匹配对象

from skimage.feature import match_template
img_gray = cv2.cvtColor(img_o,cv2.COLOR_BGR2GRAY)
img_kernel = img_gray[255:295,460:500]

plt.subplot(131),plt.imshow(img_o)
plt.title('original'),plt.xticks([]),plt.yticks([])
plt.subplot(132),plt.imshow(img_gray,'gray')
plt.title('gray'),plt.xticks([]),plt.yticks([])
plt.subplot(133),plt.imshow(img_kernel,'gray')
plt.title('template'),plt.xticks([]),plt.yticks([])
plt.show()

这里写图片描述

如上图所示,左边图为皮肤切片原图,中间为灰度图,右边为选中的匹配对象

2.match_template

result = match_template(img_gray, img_kernel, pad_input=True, mode='constant', constant_values=0)
plt.subplot(121),plt.imshow(img_gray,'gray')
plt.title('img_gray')
plt.subplot(122),plt.imshow(result,'gray')
plt.title('match_template'),plt.xticks([]),plt.yticks([])
plt.show()

这里写图片描述

匹配结果如上图右所示,其中亮度较高的部分即我们所寻找的部分

接下来我们要让这张图看起来,更加明显,所以进行二值化操作,并降噪

mask = np.ones_like(result)
mask[result > 0.4] = 255
mask[result < 0.4] = 0
plt.subplot(121),plt.imshow(mask,'gray'),plt.title('threshold')

# open
kernel = np.ones((2,2),np.uint8)
th_mor = cv2.morphologyEx(mask,cv2.MORPH_OPEN,kernel, iterations = 3)
plt.subplot(122),plt.imshow(th_mor,'gray'),plt.title('open'),plt.xticks([]),plt.yticks([])
plt.show()

这里写图片描述

如此我们已经得到毛孔的轮廓图,不过这样看是不是太抽象了,ok,那么我们就把它画到原图上看一下

3.draw contours

# 寻找轮廓
 _, contour_total, _ = cv2.findContours(th_mor, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 绘制筛选后的轮廓
img_ground = img_o.copy()
cv2.drawContours(img_ground,new_contours,-1,(0,255,255),2)

fig = plt.figure(figsize=(12, 9))
axes = np.zeros((3, 3), dtype=np.object)
axes[0, 0] = plt.subplot(231),plt.imshow(img_o),plt.title('original image')
axes[0, 1] = plt.subplot(232),plt.imshow(img_ground),plt.title('contours')
plt.show()

这里写图片描述

至此模式匹配的简单应用就算结束了。准确率什么的仅仅凭借我们肉眼观察是无法断定的,在此我们可以人工在原图上标注出毛孔的轮廓,然后与模式匹配结果进行比较,下面贴上作者尝试标注的图与模式匹配结果的对比(人工标注比较随意)

这里写图片描述

其中第二部分,模式匹配方法应用及二值化操作过程中,参数设置决定匹配结果。
另外,在各种方法使用过程中,发现LBP效果也挺好。

补充:上述第二部分方法是采用skimage的match_template,最近因为工作需要,又做了一份opencv的方法,具体如下:

import cv2
img_match = cv2.matchTemplate(img_gray, img_kernel, cv2.TM_CCOEFF_NORMED)

# 给匹配图补黑边,解决cv2匹配过程中边缘忽略问题
img_match = cv2.copyMakeBorder(img_match,0,img_kernel.shape[0]-1,0,img_kernel.shape[1]-1,cv2.BORDER_CONSTANT,value=(0, 0, 0))  

经检测发现,两者效果接近,skimage效果稍优。

本人邮箱:[email protected],欢迎讨论。

发布了20 篇原创文章 · 获赞 15 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/github_35965351/article/details/77946651