opencv-python 指静脉的ROI(感兴趣区域)的指节提取(原理+代码)

静脉采集过程中,由于手指自由度比较大,所以可能会有手指旋转,平移等现象,这有可能使得同一个手指的两次采集图像差别较大。这是我们不希望看到的。所以对图像进行ROI的提取非常有必要,也是图像预处理的一个过程。

本文:阐述我是如何对一张图片进行指节的区分的

原理:由于指节的两端有关节腔,而关节腔内部主要是软骨和组织液,这样会使得在图片中关节腔的位置会比较亮,而根据这一特点,我们就可以方便的知道指节是哪个位置了。

代码及其原理:

import cv2 as cv 
import numpy as np
from matplotlib import pyplot as plt

test_1= cv.imread('test_1.bmp',0)
test0=cv.imread('test.bmp',0)
gray_map=test0[240]
gray_map_1=test_1[240]
plt.plot(gray_map);plt.show()
plt.plot(gray_map_1);plt.show()

 

test0和test_1是我们用来实践的两张图(不同手指,网页存在拉伸):

opencv-python 指静脉的ROI(感兴趣区域)的指节提取(原理+代码)_第1张图片

在代码中,两句plt.plot()可以让我们清楚的看到在图像腰部的位置([240])的灰度分布

opencv-python 指静脉的ROI(感兴趣区域)的指节提取(原理+代码)_第2张图片

opencv-python 指静脉的ROI(感兴趣区域)的指节提取(原理+代码)_第3张图片

 

接下来只要找到左右灰度值最高的地方就大概是关节腔的位置了。

代码上我用的是登山算法找到山顶,但是这个有很多的小山顶混淆视听,但是我们最后只要其中两个,直接看代码

def find_peak(arr):
    peaks=[]
    step=1
    pos=1
    while(pos<600):   #实际上两个peak主要分布在100-200和450-550
        if (arr[pos]>=arr[pos+step])and(arr[pos]>arr[pos-step]):
            if ((arr[pos]>arr[pos+20])and(arr[pos]>arr[pos-20])):  #这个if语句可以滤除很多的噪音peak
                peaks.append(pos)
        pos=pos+step
    peak1=0
    peak2=340  #取的图片中间位置,但是有可能存在后面的关节腔灰度值比中间位置低的情况
    print(peaks)
    for i in peaks:   #这个循环从好多个peak中找到我们要的两个最大的peak
        if (i<340):
            if arr[i]>=arr[peak1] :
                peak1=i
        else:
             if arr[i]>=arr[peak2] : 
                peak2=i 
    #if(peak2-peak1)<200 :    
        #print("EOI error in peak")
    return peak1,peak2

 如果是平滑的曲线用登山算法很简单,但是这里我们需要找两个peak,而且曲线存在非常多的锯齿状peak,这都是我们不需要的。

(算法不保证不会受噪音干扰) 

效果:

这是截取的图像

opencv-python 指静脉的ROI(感兴趣区域)的指节提取(原理+代码)_第4张图片opencv-python 指静脉的ROI(感兴趣区域)的指节提取(原理+代码)_第5张图片

在实际运用中可以多取几条线上的peak然后求平均值

接下来准备想想怎么把背景去除(背景在识别中没有任何用处)

 

你可能感兴趣的:(opencv-python学习,opencv-python,roi区域,指静脉图像)