如何使用OpenCV-Python去除图像噪声?

7
我正在处理皮肤图像,用于识别皮肤瑕疵,由于存在噪声,主要是毛发的存在,这项工作变得更加复杂。
我有一个图像示例,我试图突出显示只有皮肤斑点,但由于毛发数量太多,算法无效。因此,我希望您能帮助我开发一种算法来消除或减少毛发数量,以便我只能突出显示我的感兴趣区域(ROI),即斑点。
用于突出显示皮肤瑕疵的算法:
import numpy as np
import cv2

#Read the image and perform threshold
img = cv2.imread('IMD006.bmp')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.medianBlur(gray,5)
_,thresh = cv2.threshold(blur,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

#Search for contours and select the biggest one
contours, hierarchy =         cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = max(contours, key=cv2.contourArea)

#Create a new mask for the result image
h, w = img.shape[:2]
mask = np.zeros((h, w), np.uint8)

#Draw the contour on the new mask and perform the bitwise operation
cv2.drawContours(mask, [cnt],-1, 255, -1)
res = cv2.bitwise_and(img, img, mask=mask)

#Display the result
cv2.imwrite('IMD006.png', res)
#cv2.imshow('img', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

示例图像: 输入图片描述

如何处理这些噪声,以达到改善我的感兴趣区域的效果?


1
相关链接:https://www.researchgate.net/post/How_can_I_remove_hair_from_skin_image,http://www.cs.rug.nl/svcg/Shapes/GapDetection,https://www.researchgate.net/publication/276369854_Automatic_skin_lesion_segmentation_with_optimal_colour_channel_from_dermoscopic_images - user190081
1个回答

14
这是一项相当困难的任务,因为头发覆盖了你的ROI(痣)。我不知道如何帮助去除痣上的头发,但我可以帮助去除像图片中没有头发的背景。对于从痣上去除头发,我建议您搜索“图像去水印”和“深度神经网络”,以便训练模型来去除头发(请注意,这项任务将非常困难)。
话虽如此,对于去除背景,您可以尝试使用已经具备无头发检测功能的代码。您将得到一个二进制图像,如下所示:

enter image description here

现在,您的区域被白线(头发)填充,这些线条超过了您的ROI轮廓,cv2.findContours()也会选择它们,因为它们是相连的。但是,如果您查看图片,您会发现白线非常细,您可以通过对图像执行开运算(cv2.morphologyEx)来将其从图像中删除。开运算是侵蚀后进行膨胀,因此当您使用足够大的内核大小侵蚀图像时,白线将消失:

enter image description here

现在你有一个周围带有一些噪点的白色斑点,可以通过执行另一个膨胀操作(cv2.dilate())来连接:

enter image description here

为了使ROI更加平滑,您可以使用图像模糊函数cv2.blur()

enter image description here

接下来,您可以制定另一个阈值并搜索最大的轮廓。最终结果:

enter image description here

希望这有所帮助。祝好!
示例代码:
import numpy as np
import cv2

# Read the image and perfrom an OTSU threshold
img = cv2.imread('hair.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

# Remove hair with opening
kernel = np.ones((5,5),np.uint8)
opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2)

# Combine surrounding noise with ROI
kernel = np.ones((6,6),np.uint8)
dilate = cv2.dilate(opening,kernel,iterations=3)

# Blur the image for smoother ROI
blur = cv2.blur(dilate,(15,15))

# Perform another OTSU threshold and search for biggest contour
ret, thresh = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
_, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = max(contours, key=cv2.contourArea)

# Create a new mask for the result image
h, w = img.shape[:2]
mask = np.zeros((h, w), np.uint8)

# Draw the contour on the new mask and perform the bitwise operation
cv2.drawContours(mask, [cnt],-1, 255, -1)
res = cv2.bitwise_and(img, img, mask=mask)

# Display the result
cv2.imshow('img', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

关于这些与皮肤有关的问题,如何去除它们?在我看来,DullRazon 可以做这些去除,但是没有找到实现方法。 - Tecnologia da Net
@kavko,你能帮我解决这个问题吗:https://dev59.com/eK_la4cB1Zd3GeqPoyse - Carlos Diego

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接