基于颜色聚类的实现图像分割

简介: 基于颜色聚类的实现图像分割

第一步:将彩色图像从RGB转化到lab色彩空间


close all;
clear all;
clc;
I_rgb = imread('a.jpg');
figure(1);
%将彩色图像从RGB转化到lab色彩空间
C = makecform('srgb2lab');%设置转换格式
I_lab = applycform(I_rgb, C);



第二步:取出lab空间的a分量和b分量


ab = double(I_lab(:,:,2:3));
nrows = size(ab,1);
ncols = size(ab,2);
ab = reshape(ab,nrows*ncols,2);


第三步:设定分割的区域个数进行分割


nColors = 2;  %分割的区域个数,可进行修改
[cluster_center,cluster_idx,mindist,q2,quality] = kmeanss(ab,nColors,2);
pixel_labels = reshape(cluster_idx,nrows,ncols);
figure(1);
imshow(pixel_labels,[],'border','tight','InitialMagnification','fit');
title('聚类结果');


其中的kmeanss如下:

function [centers,mincenter,mindist,q2,quality] = kmeanss(data,initcenters,method)
tic
if nargin < 3 method = 2; end
[n,dim] = size(data);
if max(size(initcenters)) == 1
    k = initcenters;
    [centers, mincenter, mindist, lower, computed] = anchors(mean(data),k,data);
    total = computed;
    skipestep = 1;
else 
    centers = initcenters;
    mincenter = zeros(n,1);
    total = 0;
    skipestep = 0;
    [k,dim2] = size(centers);    
    if dim ~= dim2 error('dim(data) ~= dim(centers)'); end;
end
nchanged = n;
iteration = 0;
oldmincenter = zeros(n,1);
while nchanged > 0
    % do one E step, then one M step
    computed = 0;
    if method == 0 & ~skipestep
        for i = 1:n
            for j = 1:k
                distmat(i,j) = calcdist(data(i,:),centers(j,:));
            end
        end
        [mindist,mincenter] = min(distmat,[],2);
        computed = k*n;
    elseif (method == 1 | (method == 2 & iteration == 0)) & ~skipestep
        mindist = Inf*ones(n,1);
        lower = zeros(n,k);
        for j = 1:k
           jdist = calcdist(data,centers(j,:));
           lower(:,j) = jdist;
           track = find(jdist < mindist);
           mindist(track) = jdist(track);
           mincenter(track) = j;
        end
        computed = k*n;
    elseif method == 2 & ~skipestep 
        computed = 0;
% for each center, nndist is half the distance to the nearest center
% if d(x,center) < nndist then x cannot belong to any other center
% mindist is an upper bound on the distance of each point to its nearest center
        nndist = min(centdist,[],2);
% the following usually is not faster        
%        ldist = min(lower,[],2);
%        mobile = find(mindist > max(nndist(mincenter),ldist));
        mobile = find(mindist > nndist(mincenter));
% recompute distances for point i and center j 
%       only if j can possibly be the new nearest center
% for speed, the first check has been optimized by modifying centdist
% swapping the order of the checks is slower for data with natural clusters
        mdm = mindist(mobile);
        mcm = mincenter(mobile);
        for j = 1:k
% the following is incorrect: for j = unique(mcm)'
            track = find(mdm > centdist(mcm,j));
            if isempty(track) continue; end
            alt = find(mdm(track) > lower(mobile(track),j));          
            if isempty(alt) continue; end
            track1 = mobile(track(alt));
% calculate exact distances to the mincenter
% recalculate separately for each jj to avoid copying too much of data
% redo may be empty, but we don't need to check this
            redo = find(~recalculated(track1));
            redo = track1(redo);
            c = mincenter(redo);
            computed = computed + size(redo,1);
            for jj = unique(c)'
                rp = redo(find(c == jj));
                udist = calcdist(data(rp,:),centers(jj,:));
                lower(rp,jj) = udist;
                mindist(rp) = udist;
            end
            recalculated(redo) = 1;
            track2 = find(mindist(track1) > centdist(mincenter(track1),j));
            track1 = track1(track2);
            if isempty(track1) continue; end
            % calculate exact distances to center j
            track4 = find(lower(track1,j) < mindist(track1));
            if isempty(track4) continue; end
            track5 = track1(track4);
            jdist = calcdist(data(track5,:),centers(j,:));
            computed = computed + size(track5,1);
            lower(track5,j) = jdist;
            % find which points really are assigned to center j
            track2 = find(jdist < mindist(track5));
            track3 = track5(track2);
            mindist(track3) = jdist(track2);
            mincenter(track3) = j;
        end % for j=1:k
    end % if method
    oldcenters = centers;
    diff = find(mincenter ~= oldmincenter);
    diffj = unique([mincenter(diff);oldmincenter(diff)])';
    diffj = diffj(find(diffj > 0));
    if size(diff,1) < n/3 & iteration > 0
         for j = diffj
            plus = find(mincenter(diff) == j);
            minus = find(oldmincenter(diff) == j);
            oldpop = pop(j);
            pop(j) = pop(j) + size(plus,1) - size(minus,1);
            if pop(j) == 0 continue; end
            centers(j,:) = (centers(j,:)*oldpop + sum(data(diff(plus),:),1) - sum(data(diff(minus),:),1))/pop(j); 
        end
    else
        for j = diffj
            track = find(mincenter == j);
            pop(j) = size(track,1);
            if pop(j) == 0 continue; end
% it's correct to have mean(data(track,:),1) but this can make answer worse!
            centers(j,:) = mean(data(track,:),1);
        end
    end
    if method == 2
        for j = diffj
            offset = calcdist(centers(j,:),oldcenters(j,:));
            computed = computed + 1;
            if offset == 0 continue; end
            track = find(mincenter == j);
            mindist(track) = mindist(track) + offset;
            lower(:,j) = max(lower(:,j) - offset,0);
        end
        recalculated = zeros(n,1);
        realdist = alldist(centers);
        centdist = 0.5*realdist + diag(Inf*ones(k,1));
        computed = computed + k + k*(k-1)/2;   
    end
    nchanged = size(diff,1) + skipestep;
    iteration = iteration+1;
    skipestep = 0;
    oldmincenter = mincenter;
    [iteration toc nchanged computed]
    total = total + computed;
end % while nchanged > 0
udist = calcdist(data,centers(mincenter,:));
quality = mean(udist);
q2 = mean(udist.^2);
[iteration toc quality q2 total]


在kmeanss 中的calcdist如下所示:

function distances = calcdist(data,center)
%  input: vector of data points, single center or multiple centers
% output: vector of distances
[n,dim] = size(data);
[n2,dim2] = size(center);
% Using repmat is slower than using ones(n,1)
%   delta = data - repmat(center,n,1);
%   delta = data - center(ones(n,1),:);
% The following is fastest: not duplicating the center at all
if n2 == 1
    distances = sum(data.^2, 2) - 2*data*center' + center*center';
elseif n2 == n
    distances = sum( (data - center).^2 ,2);
else
    error('bad number of centers');
end
% Euclidean 2-norm distance:
distances = sqrt(distances);
% Inf-norm distance:
% distances = max(abs(distances),[],2);


在kmeanss 中的anchors如下所示:

function [centers, mincenter, mindist, lower, computed] = anchors(firstcenter,k,data)
% choose k centers by the furthest-first method
[n,dim] = size(data);
centers = zeros(k,dim);
lower = zeros(n,k);
mindist = Inf*ones(n,1);
mincenter = ones(n,1);
computed = 0;
centdist = zeros(k,k);
for j = 1:k
    if j == 1
        newcenter = firstcenter;
    else
        [maxradius,i] = max(mindist);
        newcenter = data(i,:);
    end
    centers(j,:) = newcenter;
    centdist(1:j-1,j) = calcdist(centers(1:j-1,:),newcenter);
    centdist(j,1:j-1) = centdist(1:j-1,j)';
    computed = computed + j-1;
    inplay = find(mindist > centdist(mincenter,j)/2);
    newdist = calcdist(data(inplay,:),newcenter);
    computed = computed + size(inplay,1);
    lower(inplay,j) = newdist;
    move = find(newdist < mindist(inplay));
    shift = inplay(move);
    mincenter(shift) = j;
    mindist(shift) = newdist(move);
end


在kmeanss 中的alldist如下所示:

function centdist = alldist(centers)
% output: matrix of all pairwise distances
% input: data points (centers)
k = size(centers,1);
centdist = zeros(k,k);
for j = 1:k
    centdist(1:j-1,j) = calcdist(centers(1:j-1,:),centers(j,:));
end
centdist = centdist+centdist';


第四步:显示分割后的各个区域


dst = cell(1,nColors);
rgb_label = repmat(pixel_labels,[1 1 3]);
for k = 1:nColors
    color = I_rgb;
    color(rgb_label ~= k) = 0;
    dst{k} = color;
end
for i=1:nColors
figure(i+2);
imshow(dst{i});
title('分割结果');
end 


相关文章
|
XML 算法 Java
基于雪花算法解决Mybatis-Plus id主键生成的问题
基于雪花算法解决Mybatis-Plus id主键生成的问题
2251 0
|
7月前
|
机器学习/深度学习 人工智能 自动驾驶
当AI学会“想象”:世界模型如何重塑产业智能化格局?
2026年,世界模型爆发式发展:腾讯、阿里相继发布3D世界模型,World Labs、AMI Labs获超10亿美元融资。它让AI从“处理数据”跃升为“理解并预测世界”,需数字孪生提供高保真仿真舞台。凡拓数创以自研AI 3D引擎与全链条能力,筑牢产业落地底座。
|
7月前
|
数据采集 网络协议 算法
IPv6地理库如何建设?从被动探测到主动订阅的实践解析
全球IPv4枯竭加速IPv6部署,我国IPv6活跃用户已超8亿。本文解析IPv6地理定位三大挑战,揭示IP数据云等平台如何依托Geofeed订阅、BGP解析等主动溯源技术,构建高精度、日更级IPv6地理库。
|
8月前
|
人工智能 物联网 C++
深耕多领域,赋能新科技——C++的核心运用与时代价值
自1983年诞生以来,C++语言凭借高效的执行性能、灵活的内存控制和强大的兼容性,历经四十余年迭代,始终在编程语言领域占据核心地位。
503 0
|
11月前
|
人工智能 运维 安全
2025年远程控制软件排行榜:安全性能哪家强?ToDesk/TeamViewer/向日葵等对比
2025年远程控制软件排行榜:安全性能哪家强?ToDesk/TeamViewer/向日葵等对比
1251 11
2025年远程控制软件排行榜:安全性能哪家强?ToDesk/TeamViewer/向日葵等对比
|
10月前
|
缓存 JSON 数据安全/隐私保护
58 同城 item_get - 获取详情数据接口对接全攻略:从入门到精通
58同城item_get接口通过item_id获取房产、招聘、二手车等本地生活信息详情,支持HTTPS+签名认证、JSON/XML返回,具备实时性强、字段丰富、权限分级等特点。本指南涵盖接口认知、权限申请、开发对接、调试优化及生产级最佳实践,助力构建本地生活服务平台与数据中台。
|
数据采集 缓存 API
小红书笔记详情 API 实战指南:从开发对接、场景落地到收益挖掘(附避坑技巧)
本文详解小红书笔记详情API的开发对接、实战场景与收益模式,涵盖注册避坑、签名生成、数据解析全流程,并分享品牌营销、内容创作、SAAS工具等落地应用,助力开发者高效掘金“种草经济”。
小红书笔记详情 API 实战指南:从开发对接、场景落地到收益挖掘(附避坑技巧)
|
11月前
|
Go
蓝易云:如何在Go语言的HTTP请求中设置使用代理服务器
确保代理服务器功能正常且无任何网络故障。以上步骤展示了如何在Go的HTTP请求中配置和使用代理,步骤直接、实用且易于理解。你可以根据自己的需要进行适配,使用不同的请求方法或是处理请求和响应。记得错误处理是很重要的部分,确保在实际部署时将错误进行适当地记录和处理。
276 0
|
机器学习/深度学习 数据采集 自然语言处理
25_T5的统一框架:文本到文本转换的创新范式
自然语言处理(NLP)领域长期面临的一个核心挑战是任务多样性。传统上,不同的NLP任务(如机器翻译、文本分类、问答系统等)往往需要设计特定的模型架构和损失函数。这种碎片化的方法不仅增加了研究和开发的复杂性,还限制了模型在不同任务间的知识迁移能力。
689 0

热门文章

最新文章