说明
我有一个手指的图像(背景为绿色),并希望提取指甲作为特征。我的目标是用功能描述指甲的轮廓。但是我还没有尝试过的功能部分,我敢肯定我可以自己弄清楚。我很难拔出指甲,并希望得到您的帮助。您可以在帖子末尾找到图片。
我到目前为止所做的事情:
我尝试进行圆形检测或椭圆形检测。使用霍夫变换的圆检测无法识别指甲。椭圆检测也是如此(除了花了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
图片
起始图片:
已移除绿色并转换为灰色:
轮廓:
答案 0 :(得分:0)
我认为,考虑到语义/实例分割问题,解决此问题的最佳方法可能是使用Encoder-Decoder(例如U-Net)类型的体系结构,因为使用基于常规图像处理的方法来解决此问题非常困难。但是,我会尝试一下。 在我的方法中,我按照贝娄提到的步骤来检测指甲区域(结果并不完美,但您可以对此进行改进):
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)
答案 1 :(得分:0)
浏览使用MobileNetV1-FPN-SSD的项目,以阈值置信度检测图像中的指甲。