1. Opencv 图像分割与提取
在计算机视觉中,图像分割是指将图像分成多个部分或区域的过程。这些部分或区域可以用于识别物体、检测特征、跟踪对象、计算数字图像信息等。在这篇文章中,我们将介绍使用 Python 和 OpenCV 进行图像分割和对象提取的一些基本方法。
1.1 图像分割的基本概念
图像分割的目的是将图像分成多个部分或区域,每个部分或区域内具有相似的颜色、灰度级或纹理等特征。一些基本的图像分割方法包括:
阈值分割:将图像分成两部分,一部分为低于阈值的像素,另一部分为高于阈值的像素。
区域生长:从一个种子像素开始增长,将每个相邻像素与它比较,如果具有相似的特征,则合并到同一区域。
边缘检测:识别图像中物体的边缘和轮廓,将它们分割为单独的部分。
1.2 使用 Python 和 OpenCV 进行阈值分割
阈值分割是最简单和最常用的图像分割方法。它将图像分成两个部分:高于阈值和低于阈值。OpenCV 提供了一个函数 cv2.threshold()
用于进行阈值分割。以下是一个简单的示例,演示如何使用该函数将一张灰度图像分解成黑白二值图像:
import cv2
import numpy as np
# 读取图像
img = cv2.imread('image.jpg',0)
# 使用阈值分割
ret,thresh = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
# 显示结果
cv2.imshow('thresh',thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
在上面的代码中,我们使用了 Python 的 OpenCV 模块以及 NumPy,读取了一张灰度图像。然后使用cv2.threshold()
函数对图像进行了阈值分割,将所有低于 127 的像素设置为 0,高于 127 的像素设置为 255。最后,我们将仅保留两个像素值的图像显示出来。
1.3 使用 Python 和 OpenCV 进行形态学分割
形态学分割是一种将形态学操作用于图像的分割方法。形态学操作包括腐蚀、膨胀、开运算和闭运算。在 OpenCV 中,形态学操作可以使用 cv2.erode()
、cv2.dilate()
、cv2.morphologyEx()
等函数实现。以下是一个简单的示例中,演示如何使用形态学操作分割形状不规则、背景颜色不均匀的图像。
import cv2
import numpy as np
# 读取图像
img = cv2.imread('image.jpg',0)
# 定义核
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(10,10))
# 进行腐蚀运算
eroded = cv2.erode(img,kernel)
# 进行膨胀运算
dilated = cv2.dilate(eroded,kernel)
# 使用二值化分割图像
ret,thresh = cv2.threshold(dilated,127,255,cv2.THRESH_BINARY)
# 显示结果
cv2.imshow('thresh',thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
在上面的示例中,我们首先读取了一张灰度图像,然后定义了一个 kernel(核),使用 cv2.erode()
函数进行腐蚀运算,使用 cv2.dilate()
函数进行膨胀运算,最后使用 cv2.threshold()
函数进行二值化分割。结果是我们得到了一个图像分割结果的二值图像。
1.4 使用 Python 和 OpenCV 进行分水岭算法分割
分水岭算法是一种基于区域和边界的图像分割方法。在 OpenCV 中,可以使用一系列函数来实现分水岭算法分割,包括 cv2.distanceTransform()
、cv2.threshold()
和 cv2.connectedComponents()
等函数。
import cv2
import numpy as np
# 读取图像
img = cv2.imread('image.jpg')
# 灰度化
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 阈值处理
ret,thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# 形态学操作
kernel = np.ones((3,3),np.uint8)
opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel,iterations = 2)
# 距离变换
dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5)
# 标记分割
ret, sure_fg = cv2.threshold(dist_transform,0.2*dist_transform.max(),255,0)
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(opening,sure_fg)
# 前景种子生成
ret, markers = cv2.connectedComponents(sure_fg)
# 为所有标记加1,保证背景为0不变
markers = markers+1
# 未知区域设为0
markers[unknown==255] = 0
# 分水岭算法
markers = cv2.watershed(img,markers)
img[markers == -1] = [255,0,0]
# 显示结果
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
在上面的示例中,我们使用一张彩色图像作为输入,首先将其转换为灰度图像,然后进行二值化处理,接着进行形态学操作,距离变换和标记分割。最后使用分水岭算法对图像进行分割并显示结果。
2. 结论
总之,本文介绍了使用 Python 和 OpenCV 进行图像分割和对象提取的基本方法。我们演示了阈值分割、形态学分割和分水岭算法分割等方法,并提供了相应的 Python 代码。如果您想更好地理解这些技术,可以查看 OpenCV 中的其他图像处理函数、学习计算机视觉的基础知识,或者自己实现这些算法以获得更深入的理解。