Python 如何用手指从图像中提取指甲?
说明 我有一个手指的图像(绿色背景),想提取指甲作为特征。我的目标是用功能描述指甲的轮廓。然而,功能部分我还没有尝试过,我相信我可以自己弄明白。我挣扎着拔指甲,想得到你的帮助。你可以在文章的末尾找到图片 到目前为止我所做的:Python 如何用手指从图像中提取指甲?,python,image,opencv,edge-detection,Python,Image,Opencv,Edge Detection,说明 我有一个手指的图像(绿色背景),想提取指甲作为特征。我的目标是用功能描述指甲的轮廓。然而,功能部分我还没有尝试过,我相信我可以自己弄明白。我挣扎着拔指甲,想得到你的帮助。你可以在文章的末尾找到图片 到目前为止我所做的: 加载图像 调整图像大小以减少计算工作量 处理它(模糊、去除绿色背景、转换为灰度 从图像中提取指甲(如何提取?) 我试着做一个圆检测或椭圆检测。使用hough变换的圆检测无法识别指甲。椭圆检测也是如此(除了需要2分钟,等待的时间太长)。现在我的问题是:有没有简单的方法解决问题
重要的代码片段:
#导入
#辅助函数
def清除_绿色(img):
空\u img=np.类零(img)
红、绿、蓝=(2、1、0)
红色=img[:,:,红色]
绿色=img[:,:,绿色]
蓝色=img[:,:,蓝色]
#逐像素在图像上循环
tmpMask=(绿色<35)|(红色>绿色)|(蓝色>绿色)
img[tmpMask==0]=(0,0,0)#从原始图片中删除背景
空的_img[tmpMask]=(255、255、255)#手指为白色的遮罩
返回img,空\u img
#主要功能
#负载与过程
image=cv2.imread(imagePath,1)#加载
图像=cv2。调整大小(图像,无,fx=0.3,fy=0.3)#调整大小
图像=cv2.GaussianBlur(图像,(3,3,0)
无绿色图像,遮罩手指=移除绿色(图像)#移除绿色
灰色=cv2.CVT彩色(无绿色图像,cv2.COLOR颜色为灰色)#灰度
gray\u mask\u finger=cv2.CVT颜色(mask\u finger,cv2.COLOR\u BGR2GRAY)
#细化边
内核=np.one((5,5),np.uint8)
gray_mask_finger=cv2.morphologyEx(gray_mask_finger,cv2.MORPH_GRADIENT,内核)
检测指甲(灰色面具、手指)
#我在这里挣扎
图像 起始图像: 删除绿色并转换为灰色: 轮廓:
考虑到语义/实例分割问题,我认为解决此问题的最佳方法可能是使用编码器-解码器(例如U-Net)类型的体系结构,因为使用基于传统图像处理的方法解决此问题非常具有挑战性。不过,我将尝试一下。 在我的方法中,我按照下面提到的步骤检测指甲区域(结果并不完美,但您可以对此进行改进):
- 基于平滑饱和值的阈值分割感兴趣区域
- 使用Sobel算子进行梯度计算,然后将阈值应用于边缘区域检测(具有高梯度值)
- 轮廓检测与指甲区域分割
通过该项目,它使用MobileNetV1 FPN SSD以阈值置信度检测图像中的指甲
我担心你不会喜欢我的答案,但作为一名机器学习实践者,我认为最好的方法之一是手动注释多个拇指,并在其上训练分割神经网络。我想不出一种不会产生伪影或巨大缺陷的方法inaccuracies@Badogo使用MobileNetV1 FPN SSD进行指甲检测。。
image = cv2.imread("finger.jpg") # load image
hsv_img = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # BGR to HSV conversion
hsv_img = cv2.resize(hsv_img, (250, 250))
img_s = hsv_img[:, :, 1] # Extracting Saturation channel on which we will work
img_s_blur = cv2.GaussianBlur(img_s, (7, 7), 0) # smoothing before applying threshold
img_s_binary = cv2.threshold(img_s_blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] # Thresholding to generate binary image (ROI detection)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
img_s_binary = cv2.morphologyEx(img_s_binary, cv2.MORPH_OPEN, kernel, iterations=3) # reduce some noise
img_croped = cv2.bitwise_and(img_s, img_s_binary) * 2 # ROI only image extraction & contrast enhancement, you can crop this region
abs_grad_x = cv2.convertScaleAbs(cv2.Sobel(img_croped, cv2.CV_64F, 1, 0, ksize=3))
abs_grad_y = cv2.convertScaleAbs(cv2.Sobel(img_croped, cv2.CV_64F, 0, 1, ksize=3))
grad = cv2.addWeighted(abs_grad_x, .5, abs_grad_y, .5, 0) # Gradient calculation
grad = cv2.medianBlur(grad, 13)
edges = cv2.threshold(grad, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
cnts = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # Contours Detection
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
cnt = None
max_area = 0
for c in cnts:
area = cv2.contourArea(c)
if area > max_area: # Filtering contour
max_area = area
cnt = c
cv2.drawContours(hsv_img, [cnt], 0, (0, 255, 0), 3)