Numpy如何使用Python删除图像中的小对象

Numpy如何使用Python删除图像中的小对象

在本文中,我们将介绍如何使用Numpy工具包中的函数来删除图像中的小对象。具体来说,我们将讲解如何使用二值图像进行操作,以及如何过滤出我们不想要的小对象,从而得到我们想要的完美图像。

阅读更多:Numpy 教程

什么是二值图像

二值图像是将灰度图像转换为只含有两种色彩的图像。通常用黑白来表示,黑色表示像素点为0(背景),白色表示像素点为1(前景)。在图像处理中,我们通常使用二值图像来表示目标物体,然后对其进行操作。

下面我们来看看如何将灰度图像转换为二值图像:

import cv2
import numpy as np

# 读入一个灰度图像
img_gray = cv2.imread('lena.png', cv2.IMREAD_GRAYSCALE)

# 使用OTSU二值化方法
ret, thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

# 反转图像
thresh_inv = cv2.bitwise_not(thresh)

# 显示图像
cv2.imshow('thresh', thresh)
cv2.imshow('thresh_inv', thresh_inv)
cv2.waitKey(0)
cv2.destroyAllWindows()

输入的是一张灰度图像,首先我们使用OTSU二值化方法将其转换为二值图像,然后使用cv2.bitwise_not()函数反转图像,最终得到二值图像。

如何过滤出小对象

一旦我们得到了二值图像,就需要以某种方式过滤出我们不需要的小对象。一个简单的方法是使用形态学运算,比如腐蚀和膨胀。首先我们需要了解腐蚀和膨胀的基本原理。

腐蚀

腐蚀是将图像中的物体边缘向内侵蚀一个像素或者更多的过程,在去噪声、分割物体等方面有着广泛的应用。腐蚀运算后,前景区域会变小,整幅图像的白色区域会减少,对象会变细。腐蚀的原理可以用类似扫描的方式来理解,将核放在图像的一个像素A上,如果这个像素A的值为1(即白色),则核的每个值与对应像素相乘,如果都是1,则结果值为1,否则为0,这样可以将该像素周围被核覆盖的像素值置为0,即进行了腐蚀。

下面我们来看看如何进行腐蚀操作,并展示腐蚀前后的图像效果:

import cv2
import numpy as np

# 定义3x3的腐蚀核
kernel = np.ones((3, 3), np.uint8)

# 读入一张图像
img = cv2.imread('lena.png')

# 将图像转为灰度图像和二值图像
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

# 腐蚀操作
erosion = cv2.erode(thresh, kernel, iterations=1)

# 显示原图和腐蚀后的图像
cv2.imshow('ori', img)
cv2.imshow('erosion', erosion)
cv2.waitKey(0)
cv2.destroyAllWindows()

输入的是一张包含对象的图像,首先将其转为灰度图像和二值图像,并定义一个3×3的腐蚀核。然后使用cv2.erode()函数对二值图像进行腐蚀操作,并将腐蚀后的图像展示出来。可以看到,经过腐蚀后,原图像中的对象变得更加细化。

膨胀

相对于腐蚀,膨胀的作用是将图像中物体边缘向外扩张并增加其面积,在连通性和填充物体等方面有着广泛的应用。膨胀操作与腐蚀操作相反,如果像素值为1,则保持不变,否则值为0,这样可以增加物体的面积。在进行膨胀操作时,需要指定一个核,核的大小会影响膨胀的效果。

下面我们来看看如何进行膨胀操作,并展示膨胀前后的图像效果:

import cv2
import numpy as np

# 定义3x3的膨胀核
kernel = np.ones((3, 3), np.uint8)

# 读入一张图像
img = cv2.imread('lena.png')

# 将图像转为灰度图像和二值图像
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

# 膨胀操作
dilation = cv2.dilate(thresh, kernel, iterations=1)

# 显示原图和膨胀后的图像
cv2.imshow('ori', img)
cv2.imshow('dilation', dilation)
cv2.waitKey(0)
cv2.destroyAllWindows()

输入的是一张包含对象的图像,首先将其转为灰度图像和二值图像,并定义一个3×3的膨胀核。然后使用cv2.dilate()函数对二值图像进行膨胀操作,并将膨胀后的图像展示出来。可以看到,经过膨胀后,原图像中的对象变得更加粗壮。

开运算

开运算是先进行腐蚀再进行膨胀的运算,比较适合去除图像中小的干扰物体。其原理是先对物体边缘进行腐蚀,消除小的散斑,并突出物体的主体部分,再进行膨胀,填充物体内部细小空洞,从而降低物体边缘的不连续性。

下面我们来看看如何进行开运算操作,并展示开运算前后的图像效果:

import cv2
import numpy as np

# 定义3x3的腐蚀核和膨胀核
kernel_erode = np.ones((3, 3), np.uint8)
kernel_dilate = np.ones((3, 3), np.uint8)

# 读入一张图像
img = cv2.imread('lena.png')

# 将图像转为灰度图像和二值图像
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

# 开运算操作
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel_erode)

# 显示原图和开运算后的图像
cv2.imshow('ori', img)
cv2.imshow('opening', opening)
cv2.waitKey(0)
cv2.destroyAllWindows()

输入的是一张包含对象的图像,首先将其转为灰度图像和二值图像,并定义一个3×3的腐蚀核和膨胀核。然后使用cv2.morphologyEx()函数对二值图像进行开运算操作,并将开运算后的图像展示出来。可以看到,经过开运算后,原图像中的小干扰物体已被消除。

闭运算

闭运算是先进行膨胀再进行腐蚀的运算,比较适合填充物体内部的细小空洞。其原理是先对物体内部进行膨胀,填充物体内部的细小空洞,再进行腐蚀,消除物体内部不连续性。

下面我们来看看如何进行闭运算操作,并展示闭运算前后的图像效果:

import cv2
import numpy as np

# 定义3x3的腐蚀核和膨胀核
kernel_erode = np.ones((3, 3), np.uint8)
kernel_dilate = np.ones((3, 3), np.uint8)

# 读入一张图像
img = cv2.imread('lena.png')

# 将图像转为灰度图像和二值图像
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

# 闭运算操作
closing = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel_dilate)

# 显示原图和闭运算后的图像
cv2.imshow('ori', img)
cv2.imshow('closing', closing)
cv2.waitKey(0)
cv2.destroyAllWindows()

输入的是一张包含对象的图像,首先将其转为灰度图像和二值图像,并定义一个3×3的腐蚀核和膨胀核。然后使用cv2.morphologyEx()函数对二值图像进行闭运算操作,并将闭运算后的图像展示出来。可以看到,经过闭运算后,原图像中的小细节空洞已被填充。

选择合适的操作

在选择形态学运算操作时,需要根据具体情况进行选择。如果要去除小的干扰物体,可以使用开运算操作。如果要填充物体内部的细小空洞,可以使用闭运算操作。另外,也可以根据需要对腐蚀和膨胀操作进行组合,得到更好的效果。

如何使用Numpy删除小对象

在上一节中,我们讲解了如何使用形态学运算过滤出我们不想要的小对象。但实际上,在Numpy工具包中也提供了类似的功能,可以帮助我们实现这个目标。

下面我们来看看如何使用Numpy删除小对象,并展示删除前后的图像效果:

import cv2
import numpy as np

# 读入一张图像
img = cv2.imread('lena.png')

# 将图像转为灰度图像和二值图像
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

# 查找轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 遍历所有轮廓
for i in range(len(contours)):
    area = cv2.contourArea(contours[i])
    if area < 50:
        cv2.drawContours(thresh, [contours[i]], 0, 0, -1)

# 显示原图和删除小对象后的图像
cv2.imshow('ori', img)
cv2.imshow('thresh', thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()

输入的是一张包含对象的图像,首先将其转为灰度图像和二值图像。然后使用cv2.findContours()函数查找图像中的所有轮廓。接下来遍历所有轮廓,并计算其面积,判断是否小于指定面积大小。若是,则使用cv2.drawContours()函数将该轮廓填充为黑色,删除小的对象。最后将删除小对象后的二值图像展示出来。可以看到,经过删除小对象后,原图像中的小干扰物体已被过滤掉。

总结:

本节中,我们介绍了形态学运算的基本原理和常用操作,包括腐蚀、膨胀、开运算和闭运算,并使用OpenCV和Numpy工具包实现了这些操作,并展示了操作前后的图像效果。这些操作在图像处理、计算机视觉和机器人视觉等领域有着广泛的应用。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程