OpenCV 实战3——图像分割Kmean聚类

图像分割--Keman聚类

1 Kmean图像分割

按照Kmean原理,对图像像素进行聚类。
优点:此方法原理简单,效果显著。
缺点:实践发现对于前景和背景颜色相近或者颜色区分度差的图像效果不显著。
本文对图像进行滤波,主要是为了消除树枝颜色的影响(滤波为非Keman图像分割的必要操作)。

2 流程

(1)读入图片,把图片转化为二维。
(2)根据Kmean算法对图像分割,返回类别标签和各类别中心点。
(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中的Kmeans算法可以用于颜色聚类,它通过将像素点聚类成不同的颜色组合,从而实现对图像的颜色分割和分类。下面是一个简单的实例来说明如何使用OpenCV中的Kmeans算法进行颜色聚类。 首先,我们需要导入必要的库,并读取一张图像作为输入。假设我们要对这张图像进行颜色聚类聚类数为K。 ```python import cv2 import numpy as np # 读取图像 img = cv2.imread('image.jpg') ``` 接下来,我们需要将图像转换为一维矩阵,并将其转化为浮点型数据。 ```python # 将图像转换为一维矩阵 pixels = img.reshape(-1, 3) # 将数据转换为浮点型 pixels = np.float32(pixels) ``` 然后,我们可以使用OpenCV中的kmeans函数进行颜色聚类。该函数接受三个参数:数据集,聚类数K和停止条件。 ```python # 设置停止条件 criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0) # 运行Kmeans算法进行聚类 _, labels, centers = cv2.kmeans(pixels, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS) ``` Kmeans运行结束后,我们可以得到每个像素点所属的类别标签以及聚类中心的颜色值。然后,我们可以根据类别标签为每个像素点上色,以此进行颜色分割和分类。 ```python # 将类别标签转换为整数型 labels = np.uint8(labels) # 重新构建图像 segmented_img = centers[labels.flatten()].reshape(img.shape) # 显示图像 cv2.imshow("Original Image", img) cv2.imshow("Segmented Image", segmented_img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 最后,我们可以通过展示原始图像和聚类后的图像来观察聚类的效果。 这就是使用OpenCV的Kmeans算法进行颜色聚类的简单实现。您可以根据实际需求调整聚类数和停止条件来得到更好的聚类效果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值