OpenCV实现K-Means图像分割:原理、流程与代码示例
本文介绍利用OpenCV和K-Means算法进行图像分割的方法。主要流程包括读取图像、转换格式、执行聚类及还原图像。针对前景背景颜色相近的情况,建议先进行高斯滤波以消除噪声干扰。文章提供了完整的Python代码示例,展示如何调整聚类中心数量及颜色以优化分割效果。
1 K-Means图像分割
基于K-Means原理对图像像素进行聚类分析。该方法的优势在于原理直观且分割效果明显;但在实际应用中,若图像前景与背景颜色相近或色彩区分度较低,分割效果可能不尽如人意。本文在分割前引入滤波处理,旨在消除树枝等细节颜色的干扰(注:滤波并非K-Means图像分割的必要步骤)。
2 处理流程
具体步骤如下: (1)读取输入图片,并将其转换为二维数组格式。 (2)应用K-Means算法对图像进行分割,获取类别标签及各类别的中心点坐标。 (3)依据类别标签复制对应的中心点颜色生成结果图像,并将其还原至原始图像尺寸。
3 代码实现
(1)在图像分割前增加滤波处理,以消除噪声干扰。
## 1 图像分割--Keman聚类
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 1 读入图片
img0 = cv2.imread('bird.png', 1) # (548,727,3)
img0 = cv2.cvtColor(img0, cv2.COLOR_BGR2RGB)
img_ = cv2.GaussianBlur(img0, (13, 13), 10, 10)
h, w, c = img_.shape
img_blur = img_.reshape([-1, 3])
img_blur = np.float32(img_blur)
# 2 分类
criteria = (
cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
num_clusters = 2
_, label, center_color = cv2.kmeans(img_blur, num_clusters,
None, criteria,
num_clusters,
cv2.KMEANS_RANDOM_CENTERS)
center_color = np.uint8(
center_color) # img_blur[398396,3],label[398396,1],center[2,3]
res = center_color[label.ravel()] # [398396,3]
res = res.reshape([h, w, c]) # res[668044,3]--> [548,727,3]
# 3 显示
plt.subplot(131)
plt.title('origin')
plt.imshow(img0)
plt.subplot(132)
plt.title('img_blur')
plt.imshow(img_)
plt.subplot(133)
plt.title('result')
plt.imshow(res)
plt.show()

(2)针对颜色区分度较低的情况,适当减少聚类种类数量,通常可获得更满意的分割效果。
## 1 图像分割--Keman聚类
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 1 读入图片
img = cv2.imread('luna.png', 1) # (548,727,3)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
h, w, c = img.shape
img0= img.reshape([-1, 3])
img0 = np.float32(img0)
# 3 分类
criteria = (
cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
num_clusters = 2
_, label, center_color = cv2.kmeans(img0, num_clusters,
None, criteria,
num_clusters,
cv2.KMEANS_RANDOM_CENTERS)
center_color = np.uint8(
center_color) # img_blur[398396,3],label[398396,1],center[2,3]
res = center_color[label.ravel()] # [398396,3]
res = res.reshape([h, w, c]) # res[668044,3]--> [548,727,3]
plt.subplot(121)
plt.title('origin')
plt.imshow(img)
plt.subplot(122)
plt.title('result')
plt.imshow(res)
plt.show()

注意:可以通过修改中心点的颜色数值,来调整分割后图像的最终显示颜色。
center_color = np.uint8(
center_color)
## 调整显示颜色
center_color[0]=[0,0,255]
center_color[1]=[255,0,0]
res = center_color[label.ravel()]

至此,关于OpenCV利用K-Means聚类实现图像分割的示例代码介绍完毕。如需了解更多OpenCV K-Means聚类相关内容,建议查阅本站过往文章或继续浏览后续教程。感谢大家的支持!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













