Python K-means实现简单图像聚类的示例代码
作者:xiongxyowo 发布时间:2023-06-30 10:40:58
标签:Python,K-means,图像聚类
这里直接给出第一个版本的直接实现:
import os
import numpy as np
from sklearn.cluster import KMeans
import cv2
from imutils import build_montages
import matplotlib.image as imgplt
image_path = []
all_images = []
images = os.listdir('./images')
for image_name in images:
image_path.append('./images/' + image_name)
for path in image_path:
image = imgplt.imread(path)
image = image.reshape(-1, )
all_images.append(image)
clt = KMeans(n_clusters=2)
clt.fit(all_images)
labelIDs = np.unique(clt.labels_)
for labelID in labelIDs:
idxs = np.where(clt.labels_ == labelID)[0]
idxs = np.random.choice(idxs, size=min(25, len(idxs)),
replace=False)
show_box = []
for i in idxs:
image = cv2.imread(image_path[i])
image = cv2.resize(image, (96, 96))
show_box.append(image)
montage = build_montages(show_box, (96, 96), (5, 5))[0]
title = "Type {}".format(labelID)
cv2.imshow(title, montage)
cv2.waitKey(0)
主要需要注意的问题是对K-Means原理的理解。K-means做的是对向量的聚类,也就是说,假设要处理的是224×224×3的RGB图像,那么就得先将其转为1维的向量。在上面的做法里,我们是直接对其展平:
image = image.reshape(-1, )
那么这么做的缺陷也是十分明显的。例如,对于两张一模一样的图像,我们将前者向左平移一个像素。这么做下来后两张图像在感官上几乎没有任何区别,但由于整体平移会导致两者的图像矩阵逐像素比较的结果差异巨大。以橘子汽车聚类为例,实验结果如下:
可以看到结果是比较差的。因此,我们进行改进,利用ResNet-50进行图像特征的提取(embedding),在特征的基础上聚类而非直接在像素上聚类,代码如下:
import os
import numpy as np
from sklearn.cluster import KMeans
import cv2
from imutils import build_montages
import torch.nn as nn
import torchvision.models as models
from PIL import Image
from torchvision import transforms
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
resnet50 = models.resnet50(pretrained=True)
self.resnet = nn.Sequential(resnet50.conv1,
resnet50.bn1,
resnet50.relu,
resnet50.maxpool,
resnet50.layer1,
resnet50.layer2,
resnet50.layer3,
resnet50.layer4)
def forward(self, x):
x = self.resnet(x)
return x
net = Net().eval()
image_path = []
all_images = []
images = os.listdir('./images')
for image_name in images:
image_path.append('./images/' + image_name)
for path in image_path:
image = Image.open(path).convert('RGB')
image = transforms.Resize([224,244])(image)
image = transforms.ToTensor()(image)
image = image.unsqueeze(0)
image = net(image)
image = image.reshape(-1, )
all_images.append(image.detach().numpy())
clt = KMeans(n_clusters=2)
clt.fit(all_images)
labelIDs = np.unique(clt.labels_)
for labelID in labelIDs:
idxs = np.where(clt.labels_ == labelID)[0]
idxs = np.random.choice(idxs, size=min(25, len(idxs)),
replace=False)
show_box = []
for i in idxs:
image = cv2.imread(image_path[i])
image = cv2.resize(image, (96, 96))
show_box.append(image)
montage = build_montages(show_box, (96, 96), (5, 5))[0]
title = "Type {}".format(labelID)
cv2.imshow(title, montage)
cv2.waitKey(0)
可以发现结果明显改善:
来源:https://blog.csdn.net/qq_40714949/article/details/120854418


猜你喜欢
- Go init函数详解init()函数会在每个包完成初始化后自动执行,并且执行优先级比main函数高。init 函数通常被用来:对变量进行初
- 提到开心消消乐这款小游戏,相信大家都不陌生,其曾在 2015 年获得过玩家最喜爱的移动单机游戏奖,受欢迎程度可见一斑,本文我们使用 Pyth
- layui数据表格批量删除多条件搜索框:注样式自己写<div class="demoTable" style=&q
- 网络爬虫抓取特定网站网页的html数据,但是一个网站有上千上万条数据,我们不可能知道网站网页的url地址,所以,要有个技巧去抓取网站的所有h
- mysql连接超时和mysql连接错误在生产环境中,偶尔且不规律的出现mysql连接超时和创建连接出错的问题:15-09-2020 13:2
- Go语言也称 Golang,兼具效率、性能、安全、健壮等特性。Go语言从底层原生支持并发,无须第三方库、开发者的编程技巧和开发经验就可以轻松
- 为方便用ipset 来管理防火墙,写了下面Ipset类来对Ip进行管理#!/usr/bin/env python# coding: utf-
- 一.问题描述在二维数组的遍历中,我们经常使用双层for循环。在某些时候,我们并不需要遍历整个二维数组。当条件满足时就应该终止for循环。但是
- 需求:在刷word题库的时候,答案就在题目下方,干扰复习效果,将答案字体变成白色,查看答案的时候只需要将答案背景刷黑转换需求:在word中找
- 一个Link被点击之后有可能是打开新窗口,也有可能是刷新当前窗口,这两种打开方式一直并存于互联网中。 作为测试对象,于25日将打开方式改为‘
- 前言python中有一个非常有用的语法叫做生成器,所利用到的关键字就是yield。有效利用生成器这个工具可以有效地节约系统资源,避免不必要的
- 相比于逻辑回归,在很多情况下,SVM算法能够对数据计算从而产生更好的精度。而传统的SVM只能适用于二分类操作,不过却可以通过核技巧(核函数)
- 前言本文从代码复用的角度一步一步演示如何从python普通代码进化到面向对象,并通过代码去解释一些面向对象的理论。所以,本文前面的内容都是非
- 为什么需要线程池呢? 设想一下,如果我们使用有任务就开启
- 用Python发送126邮件,供大家参考,具体内容如下今天想做个自动化邮件提醒的功能,最近刚好在学习python,都说python那么强大,
- 1、 设置WriteHeader的顺序问题之前遇到个问题,在一段代码中这样设置WriteHeader,最后在header中取Name时怎么也
- Random库主要包含返回随机数的函数,主要用于普通的随机数生成的程序,如果对随机性有特殊要求,比如加密等,可以用函数os.urandom(
- 已解决卸载pip重新安装的方法问题需求粉丝群里面的一个小伙伴遇到问题跑来私信我,想用卸载pip重新安装pip,但是发生了报错(当时他心里瞬间
- 为了保护系统或数据安全,我们需要最佳随机密码。这里使用unix系统定义的文件设备/dev/random,从中获取随机数生成器的种子。需求说明
- 线性判别分析(linear discriminant analysis),LDA。也称为Fisher线性判别(FLD)是模式识别的经典算法。