欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

opencv-python 指静脉的手指轮廓提取实现

程序员文章站 2022-07-12 23:16:14
...

由于指静脉由于采集时候手指的不固定,所以同一手指的不同照片可能会有旋转。我们提取手指的轮廓就是为了拟合出手指的中线,从而对手指的图片进行旋转矫正。

在opencv中提供了好几种方法供我们用来提取图片中物体的边界与轮廓。有Sobel算子,拉普拉斯算法等等,但是应用在我的图片上一点都不友好:

opencv-python 指静脉的手指轮廓提取实现

中间的是原图,不知道是不是因为我没有对原图进行平滑处理,如果用这两种算子来进行进一步的处理的话,难度巨大。但是在opencv中,还有一种十分友好的边缘检测的方法,他就是cv.Canny()

想了解原理和用法的话这里讲的非常清楚:

Canny的原理

接下来展示一下这个函数的效果(网页原因图片被拉伸了)

opencv-python 指静脉的手指轮廓提取实现效果很好,与轮廓无关的部分大大减少。

示例的源码:

import cv2 as cv 
import numpy as np

from matplotlib import pyplot as plt

clahe_test=cv.imread('clahe_test.bmp',0)

sobelx = cv.Sobel(clahe_test,cv.CV_64F,1,0,ksize=5)
laplacian = cv.Laplacian(clahe_test,cv.CV_64F)
canny=cv.Canny(clahe_test,90,150)
#finger_edges=get_edges(canny)
cv.imshow("sobelx",sobelx)
cv.imshow("canny ",canny )
cv.imshow("clahe_test",clahe_test)
cv.imshow("laplacian",laplacian)
cv.waitKey(0)
cv.destroyAllWindows()

但是仅仅得到canny的效果还不够,因为我们要的仅仅是手指的轮廓,其他位置的任何轮廓对我们来说都是多余的。所以我另外编写了一个函数用来专门提取我们需要的部分。

观察Canny,我们发现中间部分都是空白,我们要的仅仅只是最靠近中间的部分,所以在函数中,我直接提取了靠近中间的像素点的坐标,然后把一张空白图像的对应坐标改变为白色(255)

以下是函数的源码:

def get_edges(img):   # img : single channel img which has been processed by cv.Canny
    rows,cols=img.shape
    center=rows/2
    index=[]
    up_index=[]
    for i in range(cols):
        temp_index=np.argwhere(img[:,i]==255)
        temp_index=temp_index.tolist()
        for j in temp_index:
            if j[0]<center:
                up_index.append(center-j[0])      
        up=len(up_index)-1
        up_index.clear()
        down = up+1
        try:
            index.append([temp_index[up][0],i] )
            index.append([temp_index[down][0],i])
        except IndexError:
            index.append(index[-2])
            index.append(index[-1])
    result_img=np.zeros((rows,cols),dtype="uint8")
    for j in index:
        result_img[j[0],j[1]]=255  #put the Corresponding coordinate into 255
    return result_img

函数的说明:

try的部分的意义是:如果当列的上半部分没有找到灰度值为255的像素点,那么就以最近添加的两个像素点的坐标代替。

因为我在实际中遇到了这种图片:

opencv-python 指静脉的手指轮廓提取实现

看第二列,图片的下半部分没有255的值了,程序中down = up+1,而up=len(up_index)-1,他是上面半部分索引值的最后一个,由于下半部分没有255的值了,所以up同时也是temp_index的最后一个,这时候temp_index[down][0]必定会超出边界。但是加入了异常处理就不会有这种顾虑了。

接下来看看效果图:

opencv-python 指静脉的手指轮廓提取实现

还行,有了它接下来就可以继续做中线的拟合了

感受:python的一些基础操作还不熟悉,np中的基础操作也记不太清了,但是贵在学习,继续积累

我太难了,有帮助的话,点个赞噢亲