gpt4 book ai didi

python - 如何用手指从图像中提取指甲?

转载 作者:太空宇宙 更新时间:2023-11-03 23:05:04 24 4
gpt4 key购买 nike

描述

我有一张手指图像(绿色背景),想提取指甲作为特征。我的目标是用函数来描述指甲的轮廓。但是功能部分我还没有尝试过,我相信我可以自己弄清楚。我很难拔出指甲,希望得到您的帮助。您可以在帖子末尾找到图片。

到目前为止我做了什么:

  1. 载入图片
  2. 调整图像大小以减少计算量
  3. 对其进行处理(模糊、去除绿色背景、转换为灰度)
  4. 从图像中提取指甲(怎么做?)

我尝试进行圆形检测或椭圆检测。使用霍夫变换的圆圈检测无法识别指甲。椭圆检测也是如此(除了它花了 2 分钟,而且等待时间太长了)。现在我的问题是:有没有简单的方法解决问题并拔掉手指甲?

我还使用边缘检测/轮廓检测来提取指甲,但是它太不准确而且没有帮助。

我的梦想是在指甲开始处额外分离灰色/深色部分,但我没有做到,因此放弃了这部分。但是,如果您知道一种简单易行的方法,我很乐意听到。


重要代码片段:

# imports

# helper functions
def remove_green(img):
empty_img = np.zeros_like(img)
RED, GREEN, BLUE = (2, 1, 0)
reds = img[:, :, RED]
greens = img[:, :, GREEN]
blues = img[:, :, BLUE]
# loop over the image, pixel by pixel
tmpMask = (greens < 35) | (reds > greens) | (blues > greens)
img[tmpMask == 0] = (0, 0, 0) # remove background from original picture
empty_img[tmpMask] = (255, 255, 255) # mask with finger in white
return img, empty_img

# main function
# load and process
image = cv2.imread(imagePath, 1) # load
image = cv2.resize(image, None, fx=0.3, fy=0.3) # resize
image = cv2.GaussianBlur(image, (3, 3), 0)
no_green_image, mask_finger = remove_green(image) # remove green
gray = cv2.cvtColor(no_green_image, cv2.COLOR_BGR2GRAY) # gray scalEd
gray_mask_finger = cv2.cvtColor(mask_finger, cv2.COLOR_BGR2GRAY)

# refine edges
kernel = np.ones((5, 5), np.uint8)
gray_mask_finger = cv2.morphologyEx(gray_mask_finger, cv2.MORPH_GRADIENT, kernel)

detect_nail(gray_mask_finger)
# here I struggle

图片

起始图片:

Starting image

移除绿色并转换为灰色:

Processed image

轮廓:

Contours

最佳答案

我认为解决这个问题的最佳方法,考虑到语义/实例分割问题,可能是使用编码器-解码器(例如 U-Net)类型的架构,因为使用基于传统图像处理的方法解决这个问题非常具有挑战性.不过,我会试一试。在我的方法中,我按照下面提到的步骤来检测指甲区域(结果并不完美,但您可以对此进行改进):

  • 将平滑饱和度值的阈值应用于分段 ROI
  • 使用 Sobel 算子计算梯度,然后将阈值应用于边缘区域检测(具有高梯度值)
  • 轮廓检测和指甲区域分割
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)

逐步输出: enter image description here

关于python - 如何用手指从图像中提取指甲?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58236218/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com