目录
[2.1 交互式分割实验](#2.1 交互式分割实验)
[2.1.1 交互式分割 实验代码](#2.1.1 交互式分割 实验代码)
[2.1.2 实验结果](#2.1.2 实验结果)
[2.2 聚类算法实现图像分割](#2.2 聚类算法实现图像分割)
[2.2.1 聚类算法实现分割 实验代码](#2.2.1 聚类算法实现分割 实验代码)
[2.2.2 实验结果](#2.2.2 实验结果)
一、实验内容
- 了解图割操作,实现用户交互式分割,通过在一幅图像上为前景和背景提供一些标记或利用边界框选择一个包含前景的区域,实现分割。
- 采用聚类法实现图像的分割,例如K-means、Mean-Shift、DBSCAN等方法
二、实验过程
2.1 交互式分割实验
2.1.1 交互式分割 实验代码
这里使用OpenCV库进行图像分割,通过用户在图像上绘制矩形框来指定前景区域,然后利用GrabCut算法对图像进行分割,从而将前景和背景分离。通过定义鼠标回调函数处理用户的鼠标事件,当用户完成矩形框绘制后,根据掩码显示分割结果。掩码中的值为2或0的区域被认为是背景,其他区域被认为是前景。最终结果显示在名为'result'的窗口中。
python
import cv2
import numpy as np
# img = cv2.imread('D:\Computer vision\A_picture.png')
img=cv2.imread('D:\Computer vision\School picture\school8.jpeg')
img = cv2.resize(img, (960, 720))
mask = np.zeros(img.shape[:2], np.uint8)
bgdModel = np.zeros((1, 65), np.float64)
fgdModel = np.zeros((1, 65), np.float64)
def draw_rect(event, x, y, flags, param):
global ix, iy, drawing, rect_over
if event == cv2.EVENT_LBUTTONDOWN:
drawing = True
ix, iy = x, y
elif event == cv2.EVENT_MOUSEMOVE:
if drawing == True:
img_copy = img.copy()
cv2.rectangle(img_copy, (ix, iy), (x, y), (0, 255, 0), 2)
cv2.imshow('image', img_copy)
elif event == cv2.EVENT_LBUTTONUP:
drawing = False
rect_over = True
cv2.rectangle(img, (ix, iy), (x, y), (0, 255, 0), 2)
rect = (min(ix, x), min(iy, y), abs(ix - x), abs(iy - y))
cv2.grabCut(img, mask, rect, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_RECT)
cv2.imshow('image', img)
cv2.namedWindow('image')
cv2.setMouseCallback('image', draw_rect)
drawing = False
ix, iy = -1, -1
rect_over = False
while True:
cv2.imshow('image', img)
k = cv2.waitKey(1) & 0xFF
if rect_over == True:
mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
img_cut = img * mask2[:, :, np.newaxis]
cv2.imshow('result', img_cut)
if k == 27:
break
cv2.destroyAllWindows()
2.1.2 实验结果
(1)测试1:前景和背景区分明显
原图如图1所示,前景和背景区分明显,绘制矩形框如图2所示,图像分割结果如图3所示,可以看到分割效果较好。
图1
图2
图3
(2)测试2:前景和背景区分不明显
原图如图4所示,前景和背景区分不明显,绘制矩形框如图5所示,图像分割结果如图6所示,可以看到分割效果较差。
图4
图5
图6
(3)测试3:其他情况
再次尝试其他图片,原图如图7所示,标注的矩形框及分割结果如图8所示,当分割的矩形框包围的前景与背景有较大差距,能明显区分时,效果较好。
图7
图8
2.2 聚类算法实现图像分割
2.2.1 聚类算法实现分割 实验代码
这里使用OpenCV库进行图像分割,通过对一张图像进行颜色聚类,实验中分成3个簇(3种颜色),获取每个像素的聚类标签和每个簇的中心点颜色值。根据聚类结果,将每个像素替换为其所属簇的中心点颜色值,从而生成分割后的图像。
python
import numpy as np
import cv2
from sklearn.cluster import KMeans
# img = cv2.imread('D:\Computer vision\A_picture.png')
img=cv2.imread('D:\Computer vision\School picture\school10.jpeg')
img = cv2.resize(img, (960, 720))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
h, w, c = img.shape
data = img.reshape((h * w, c))
kmeans = KMeans(n_clusters=3, random_state=0)
kmeans.fit(data)
labels = kmeans.labels_
centers = kmeans.cluster_centers_
labels = labels.reshape((h, w))
result = np.zeros((h, w, c), dtype=np.uint8)
for i in range(h):
for j in range(w):
result[i, j] = centers[labels[i, j]]
cv2.imshow('Original', img)
cv2.imshow('Segmented', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
2.2.2 实验结果
(1)测试1:前景和背景区分明显
原图如图9所示,前景和背景区分明显,图像转换为RGB格式如图10所示,使用K-means聚类进行图像分割结果如图11所示,可以看到分割效果较好。
图9
图10
图11
(2)测试2:前景和背景区分不明显
原图如图12所示,前景和背景区分不明显,图像转换为RGB格式如图13所示,使用K-means聚类进行图像分割结果如图14所示(n_clusters=3)。当修改参数,即使用n_clusters=2时的图像分割结果如图15所示。
图12
图13
图14
图15
(3)测试3:其他情况
原图如图16所示,前景和背景区分不明显,图像转换为RGB格式如图17所示,使用K-means聚类进行图像分割结果如图18所示(n_clusters=3)。当修改参数,即使用n_clusters=2时的图像分割结果如图19所示。
图16
图17
图18
图19
三、实验总结
图像分割,是将一幅数字图像按照某种目的划分为两个或多个子图像区域。本次实验主要实现交互式图像分割和使用KMeans聚类算法对图像进行颜色分割方法,交互式分割通过利用边界框(bounding box)选择一个包含前景的区域,K-means聚类法将图像的像素点聚类为 K 个不同的组,每个组对应图像中的一个分割区域。这种分割方法的核心思想是 将图像像素看作数据点,并依据像素的特征对其进行聚类 。通常情况下,K-means 会基于像素的颜色特征(RGB或其他颜色空间的值)和空间位置进行聚类。