我正在尝试消除图像中的噪声,目前正在运行此代码
import numpy as np
import argparse
import cv2
from skimage import morphology
# Construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required = True,
help = "Path to the image")
args = vars(ap.parse_args())
# Load the image, convert it to grayscale, and blur it slightly
image = cv2.imread(args["image"])
cv2.imshow("Image", image)
cv2.imwrite("image.jpg", image)
greenLower = np.array([50, 100, 0], dtype = "uint8")
greenUpper = np.array([120, 255, 120], dtype = "uint8")
green = cv2.inRange(image, greenLower, greenUpper)
#green = cv2.GaussianBlur(green, (3, 3), 0)
cv2.imshow("green", green)
cv2.imwrite("green.jpg", green)
cleaned = morphology.remove_small_objects(green, min_size=64, connectivity=2)
cv2.imshow("cleaned", cleaned)
cv2.imwrite("cleaned.jpg", cleaned)
cv2.waitKey(0)
但是,尽管使用了remove_small_objects功能,图像似乎并没有从“绿色”更改为“已清理”。这是为什么,我该如何清理图像?理想情况下,我只想分离白菜的图像。
我的想法是在阈值化之后去除小于100的像素,然后用模糊来平滑图像,并填充被白色包围的黑洞——这就是我在matlab中所做的。如果有人能指导我得到与我的matlab实现相同的结果,那将是非常感谢的。谢谢你的帮助。
编辑:在更改代码时犯了一些错误,更新到当前状态并显示3个图像
图片:
绿色:
干净:
我的目标是从matlab实现中获得如下图片:
似乎您要删除的是一组断开连接的小blob。 我认为用正确的内核删除它们会有很好的效果。
给定一个nxn内核,search将内核移动到图像中,并用内核中的最小像素替换中心像素。 然后您可以expand()生成的图像以恢复绿色部分的侵蚀边缘。
另一个选择是使用fastndenoising
预处理
当你过滤一个图像的时候,一个好主意是降低图像的分辨率或者使其模糊一点;这样相邻的像素在颜色上会变得更加均匀,所以它会缓和图像上的亮点和暗点,并使洞远离你的遮罩。
色彩空间
目前,你正试图通过不同亮度的颜色范围来包含一个图像——你想要绿色像素,不管它们是暗的还是亮的。这在HSV色彩空间中更容易实现。查看我的答案here深入HSV色彩空间。
二值图像/掩模中的噪声去除
由ngalstyan提供的answer展示了如何用形态学很好地实现这一点。你想做的是称为打开,这是一个组合的过程,即腐蚀(或多或少只是移除某个半径内的所有东西)然后膨胀(无论移除多少都会添加回任何剩余的对象)。在OpenCV中,这是通过^{} 完成的。该页上的教程显示了它的工作原理。
填补空白
在上面,opening被显示为从二进制掩码中移除小白点的方法。关闭是相反的操作——从被白色包围的图像中删除黑色块。您可以使用与上面相同的想法,但使用^{} 。在你的情况下,这甚至不是必要的,因为面具没有任何洞。但如果是的话,你可以用关门来关上它们。你会注意到我的第一步实际上是去掉了底部的一小块植物。实际上,您可以先关闭,然后打开以删除其他地方的伪位来填补这些空白,但对于此图像,这可能不是必需的。
尝试阈值的新值
你可能想要更舒适地使用不同的颜色空间和阈值级别,以获得对特定图像最有效的感觉。它还没有完成,界面有点不稳定,但是我有一个工具,你可以在线使用它在不同的颜色空间中尝试不同的阈值;如果你愿意,可以查看here。这就是我如何快速找到你的形象价值。
不过,上面的问题是用
cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
解决的。但是,如果有人想使用morphology.remove_small_objects
来删除小于指定大小的区域,那么这个答案可能会有帮助。我用来去除上面图像的噪声的代码是:
清理后的图像如下所示:
要使用
morphology.remove_small_objects
,必须首先标记blob。为此,我使用imglab = morphology.label(green)
。标记是这样做的,第一个blob的所有像素都编号为1。类似地,第7个blob的所有像素都编号为7,依此类推。因此,在移除小区域后,剩余blob的像素值应设置为255,以便cv2.imshow()
可以显示这些blob。为此,我创建了一个数组img3
,其大小与已清理图像的大小相同。我使用img3[cleaned > 0] = 255
行将值大于0的所有像素转换为255。相关问题 更多 >
编程相关推荐