[英]How to remove image noise using opencv - python?
I am working with skin images, in recognition of skin blemishes, and due to the presence of noises, mainly by the presence of hairs, this work becomes more complicated. 我正在处理皮肤图像,识别皮肤瑕疵,并且由于存在噪声,主要是由于毛发的存在,这项工作变得更加复杂。
I have an image example in which I work in an attempt to highlight only the skin spot, but due to the large number of hairs, the algorithm is not effective. 我有一个图像示例,我在其中尝试仅突出皮肤斑点,但由于大量的毛发,算法无效。 With this, I would like you to help me develop an algorithm to remove or reduce the amount of hair so that I can only highlight my area of interest (ROI), which are the spots. 有了这个,我希望你能帮我开发一种去除或减少头发量的算法,这样我才能突出我感兴趣的区域(ROI),这是一个点。
Algorithm used to highlight skin blemishes: 用于突出皮肤瑕疵的算法:
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()
How to deal with these noises to the point of improving my region of interest? 如何处理这些噪音以改善我感兴趣的区域?
This is quite a difficult task becasue the hair goes over your ROI (mole). 这是一项相当困难的任务,因为头发会超过您的投资回报率(摩尔)。 I don't know how to help remove it from the mole but I can help to remove the backround like in the picture without hairs. 我不知道如何帮助将它从痣中移除但是我可以帮助移除背景,如图中没有毛发。 For the removal of hairs from mole I advise you to search for "removing of watermarks from image" and "deep neural networks" to maybe train a model to remove the hairs (note that this task will be quite difficult). 为了从痣中去除毛发,我建议你搜索“从图像中去除水印”和“深度神经网络”,以便训练模型去除毛发(注意这项任务将非常困难)。
That being said, for the removing of background you could try the same code that you allready have for detection without hairs. 话虽这么说,为了删除背景你可以尝试使用相同的代码,你已经有了没有毛发的检测。 You will get a binary image like this: 您将获得如下二进制图像:
Now your region is filled with white lines (hairs) that go over your contour that is your ROI and cv2.findContours()
would also pick them out because they are connected. 现在你的区域充满了白色线条(头发),这些白色线条(头发)超过你的轮廓,这是你的投资回报率,而cv2.findContours()
也会选择它们,因为它们是连接的。 But if you look at the picture you will find out that the white lines are quite thin and you can remove it from the image by performing opening ( cv2.morphologyEx
) on the image. 但是,如果你看一下图片,你会发现白线非常薄,你可以通过在图像上执行打开( cv2.morphologyEx
)将其从图像中删除。 Opening is erosion followed by dilation so when you erode the image with a big enough kernel size the white lines will dissapear: 开口是侵蚀,然后是膨胀,所以当你用足够大的内核尺寸侵蚀图像时,白线会消失:
Now you have a white spot with some noises arround which you can connect by performing another dilation ( cv2.dilate()
): 现在你有一个带有一些噪音的白点,你可以通过执行另一次扩张( cv2.dilate()
)来连接:
To make the ROI a bit smoother you can blur the image cv2.blur()
: 为了使ROI更平滑,您可以模糊图像cv2.blur()
:
After that you can make another treshold and search for the biggest contour. 之后,您可以创建另一个阈值并搜索最大轮廓。 The final result: 最终结果:
Hope it helps a bit. 希望它有所帮助。 Cheers! 干杯!
Example code: 示例代码:
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()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.