Matlab对图像进行鼠标取点操作及K值聚类分析

这篇文章将以良乡大学城某大学附近的共享单车图进行鼠标取点操作以及对相关图像的处理,将共享单车以数据点的形式呈现,并且对数据点进行K值聚类找到最佳的中心点。

图1-1 一周的数据点位移展示图

PART 1 导入图片并对图片进行取点操作

下面是对tif型的正方形图片进行取点操作(其他形状或者格式的图片可以,即将ylim注释掉),将所要进行操作的图片拖入工作区执行下面的代码:

%% 建立主函数
function BTBU_mouse_track()  %BTBU_mouse_track() 运行时只要运行函数名即可
in = imread('照片名称.tif');  %imread函数为读取图像的函数
figure,imshow(in);
%% 显示坐标系,以及画平行于x轴与y轴的水平线,将图片分为四个区域
axis on;  % 打开(显示)坐标系
hold on;  plot([550,550],[0,1100],'r-'); %ylim 用于绘制y轴的取值范围
hold on;  plot([0,1100],[550,550],'r-'); %m-- 用于描述线型,粉色,虚线
BTBUbikedata = zeros(0,2);   %保存所取得点,并且以mat形式储存
save BTBUbikedata BTBUbikedata;
set(gcf,'WindowButtonDownFcn',@BTBU_ButttonDownFcn);

%% 回调函数
function [x,y]=BTBU_ButttonDownFcn(src,event)
load('BTBUbikedata.mat');
pt = get(gca,'CurrentPoint');
x = pt(1,1);
y = pt(1,2);
BTBUbikedata(end+1,1)=round(y); %每次新产生的坐标加到BTBUbikedata中,注意figure中的x,y坐标跟实际的是反过来的
BTBUbikedata(end,2)=round(x);  %由于图像放大会产生非整数坐标,这里取整
[len,~] = size(BTBUbikedata);
fprintf('单车编号=%d,x=%f,y=%f\n',len,y,x);
save BTBUbikedata BTBUbikedata;

PART 2 对数据进行K值聚类

接着在先导入需要在上面展示数据点的底图,执行下列代码,可以得到图1-2所示的展示图

load('BTBUbikedata.mat');  %% 导入数据
x=BTBUbikedata(:,2);       y=BTBUbikedata(:,1);
in = imread('图片底层.tif');%% 导入需要在图片上显示点的底图
figure,imshow(in);         axis on;  
hold on;  plot([550,550],[0,1100],'r-');   %ylim 用于绘制y轴的取值范围
hold on;  plot([0,1100],[550,550],'r-');   %m-- 用于描述线型,粉色,虚线
hold on;  plot(x,y,'ro'); xlim([0,1100]); ylim([0,1100]);%对X轴和Y轴设定显示范围 
title('研究样本散点分布图')
图1-2 将所取点在图上展示
图1-3 二类聚类的轮廓图

执行下列代码可以得到图1-3 二类聚类的轮廓图,由轮库图可以知道第一类数据大部分在0.8以下,而第二类的数据则比较集中,随后采用分层聚类进一步验证,根据分层聚类的方法得出的树状图可以看出,有两大类具有明显差异性的数据,而第三类则是也具有差异但数目极少的数据,因此可以分成明显的两类。

[cidx2,cmeans2,sumd2,D2] = kmeans(BTBUbikedata,2,'dist','sqEuclidean'); %二类K值
P2 = figure;clf;
[silh2,h2] = silhouette(BTBUbikedata,cidx2,'sqeuclidean'); 
eucD = pdist(BTBUbikedata,'euclidean'); %分层聚类
clustTreeEuc = linkage(eucD,'average');
cophenet(clustTreeEuc,eucD);
P3 = figure;clf;
[h,nodes] =  dendrogram(clustTreeEuc,20);
set(gca,'TickDir','out','TickLength',[.002 0],'XTickLabel',[]);  % 尝试用三类K值聚类分析
[cidx3,cmeans3,sumd3,D3] = kmeans(BTBUbikedata,3,'dist','sqEuclidean');
P4 = figure;clf;
[silh3,h3] = silhouette(BTBUbikedata,cidx3,'sqeuclidean');
图1-4 分层聚类的树状图
图1-5 生成的二类的聚类中心点

PART 3 对数据进行可视化操作

然后将中心化的点再现在更加清晰可见的底图上

A=xlsread('BTBUbikedaily0801.xls');  %读取Excel表格数据
x=A(:,2); y=A(:,1);
x1=A(:,4); y1=A(:,3); 
x2=A(:,6); y2=A(:,5); 
x3=A(:,8); y3=A(:,7);
in = imread('图片.tif');   figure,imshow(in);    axis on;  
hold on;  p1=plot([550,550],[0,1100],'r-'); %ylim 用于绘制y轴的取值范围
hold on;  p2=plot([0,1100],[550,550],'r-'); %m-- 用于描述线型,粉色,虚线
hold on;  p3=plot(x,y,'yo','MarkerFaceColor','y');   %绘制x和y的图像
hold on; p4=plot(x1,y1,'ro','MarkerFaceColor','r'); %MarkerFaceColor表示实心点
hold on; p5=plot(x2,y2,'bo','MarkerFaceColor','b');
hold on; p6=plot(x3,y3,'go','MarkerFaceColor','g');
legend([p3,p4,p5,p6],'昨日时间段03','时间段01','时间段02','时间段03','Location','northoutside','Orientation','horizontal');  %图例,注意图例会展示展示出所有前面plot所画的图像,包括所画的直线,因此采用[pi,pn]来限制图例的展示
title(legend,'0801各个时间段');    xlim([0,1100]);  ylim([0,1100]); %对X和Y轴设定显示范围 
set(gca,'YDir','reverse');        %将x轴方向设置为反向(从上到下递增)。
title('显示同一天的三个时间段样本散点分布图');
图1-6 对总共21个时间段的中心点展示
图1-7 最终的再聚类点在地图上的展示

其中使用的单车数据BTBUbikedata.xlsx下载可以访问:https://github.com/ChenQihome9/CSDN-Data-Library

 

  • 10
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值