opencv 图像分割与提取(python)

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 中的其他图像处理函数、学习计算机视觉的基础知识,或者自己实现这些算法以获得更深入的理解。

后端开发标签