简体   繁体   English

如何使用opencv-python删除图像噪声?

[英]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()

Example image used: 使用的示例图像: 在此输入图像描述

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM