静脉采集过程中,由于手指自由度比较大,所以可能会有手指旋转,平移等现象,这有可能使得同一个手指的两次采集图像差别较大。这是我们不希望看到的。所以对图像进行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是我们用来实践的两张图(不同手指,网页存在拉伸):
在代码中,两句plt.plot()可以让我们清楚的看到在图像腰部的位置([240])的灰度分布
接下来只要找到左右灰度值最高的地方就大概是关节腔的位置了。
代码上我用的是登山算法找到山顶,但是这个有很多的小山顶混淆视听,但是我们最后只要其中两个,直接看代码
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,这都是我们不需要的。
(算法不保证不会受噪音干扰)
效果:
这是截取的图像
在实际运用中可以多取几条线上的peak然后求平均值
接下来准备想想怎么把背景去除(背景在识别中没有任何用处)