Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 如何在二值图像中找到像素簇的质心_Matlab_Image Processing_Centroid - Fatal编程技术网

Matlab 如何在二值图像中找到像素簇的质心

Matlab 如何在二值图像中找到像素簇的质心,matlab,image-processing,centroid,Matlab,Image Processing,Centroid,我在MATLAB中编写了一些代码,使用设置的阈值将(恒星)图像转换为二值图像,然后标记高于该阈值的每个像素簇(恒星)。标签生成一个输出: e、 g [1 1 1 0 0 0 0 0 1 1 0 0 0 2 2 2 0 0 0 0 3 3 0 2 0 0 0 0 0 3 3 0 0 0 0] 所以每个1、2、3等星团代表一颗恒星。我使用了这个链接提供的答案:标记像素。 我也不能使用图像处理工具箱。 到目前为止,我的代码如下所示 现在如何找到图像中每个像素簇的质心 clc clear all cl

我在MATLAB中编写了一些代码,使用设置的阈值将(恒星)图像转换为二值图像,然后标记高于该阈值的每个像素簇(恒星)。标签生成一个输出: e、 g

[1 1 1 0 0 0 0 0
1 1 0 0 0 2 2 2 0
0 0 0 3 3 0 2 0 0
0 0 0 3 3 0 0 0 0]
所以每个1、2、3等星团代表一颗恒星。我使用了这个链接提供的答案:标记像素。 我也不能使用图像处理工具箱。 到目前为止,我的代码如下所示

现在如何找到图像中每个像素簇的质心

clc
clear all
close all
img=imread('star.jpg');
binary_image=convert2binary(img);
imshow(binary_image);
visited = false(size(binary_image));
[rows, cols] = size(binary_image);
B = zeros(rows, cols);
ID_counter = 1;
for row = 1:rows
    for col = 1:cols
        if binary_image(row, col) == 0
            visited(row, col) = true;
        elseif visited(row, col)
            continue;
        else
            stack = [row col];

            while ~isempty(stack)
                loc = stack(1,:);
                stack(1,:) = [];

                if visited(loc(1),loc(2))
                    continue;
                end

                visited(loc(1),loc(2)) = true;
                B(loc(1),loc(2)) = ID_counter;

                [locs_y, locs_x] = meshgrid(loc(2)-1:loc(2)+1, loc(1)-1:loc(1)+1);
                locs_y = locs_y(:);
                locs_x = locs_x(:);

                out_of_bounds = locs_x < 1 | locs_x > rows | locs_y < 1 | locs_y > cols;
                locs_y(out_of_bounds) = [];
                locs_x(out_of_bounds) = [];
                is_visited = visited(sub2ind([rows cols], locs_x, locs_y));

                locs_y(is_visited) = [];
                locs_x(is_visited) = [];

                is_1 = binary_image(sub2ind([rows cols], locs_x, locs_y));
                locs_y(~is_1) = [];
                locs_x(~is_1) = [];

                stack = [stack; [locs_x locs_y]];
            end

            ID_counter = ID_counter + 1;
        end
    end
end

function [binary] = convert2binary(img)

    [x, y, z]=size(img);
    if z==3
        img=rgb2gray(img);
    end

    img=double(img);
    sum=0;
    for i=1:x
        for j=1:y
            sum=sum+img(i, j);
        end
    end


    threshold=100  % or sum/(x*y);
    binary=zeros(x,y);

    for i=1:x
        for j=1:y
            if img(i, j) >= threshold
                binary(i, j) = 1;
            else
                binary(i, j)=0;
            end
        end
    end
end
clc
清除所有
全部关闭
img=imread('star.jpg');
二进制图像=转换二进制(img);
imshow(二进制图像);
访问=假(大小(二进制图像));
[行,列]=大小(二进制图像);
B=零(行、列);
ID_计数器=1;
对于行=1:行
对于col=1:cols
如果二进制图像(行、列)==0
访问(行、列)=真;
访问过的其他人(世界其他地区、哥伦比亚)
继续;
其他的
堆栈=[行列];
而~isempty(堆栈)
loc=堆栈(1,:);
堆栈(1,:)=[];
如果访问(loc(1),loc(2))
继续;
结束
访问(loc(1),loc(2))=真实;
B(loc(1),loc(2))=ID_计数器;
[locs_y,locs_x]=网格网格(loc(2)-1:loc(2)+1,loc(1)-1:loc(1)+1);
locs_y=locs_y(:);
locs_x=locs_x(:);
超出边界=locs_x<1 | locs_x>行| locs_y<1 | locs_y>列;
locs_y(超出范围)=[];
locs_x(超出范围)=[];
is_visted=visted(sub2ind([rows cols],locs_x,locs_y));
地点(是否到访)=[];
locs_x(被访问)=[];
is_1=二进制图像(sub2ind([rows cols],locs_x,locs_y));
locs_y(~is_1)=[];
locs_x(~is_1)=[];
堆栈=[stack;[locs_x locs_y]];
结束
ID_计数器=ID_计数器+1;
结束
结束
结束
函数[二进制]=转换器2二进制(img)
[x,y,z]=尺寸(img);
如果z==3
img=rgb2gray(img);
结束
img=双(img);
总和=0;
对于i=1:x
对于j=1:y
sum=sum+img(i,j);
结束
结束
阈值=100%或总和/(x*y);
二进制=零(x,y);
对于i=1:x
对于j=1:y
如果img(i,j)>=阈值
二元(i,j)=1;
其他的
二元(i,j)=0;
结束
结束
结束
结束

质心是一阶矩。由

sum(x*v)/sum(v) , sum(y*v)/sum(v)
对于二进制图像,您可以这样做(我使用的是一个简单的循环,而不是矢量化代码,因此我们可以稍后轻松地对其进行扩展):

img=[11100
1 1 0 0 0 2 2 2 0
0 0 0 3 3 0 2 0 0
0 0 0 3 3 0 0 0 0]; % Op的示例数据
bin=img==1;%二值图像
%算法
和v=0;
sum_iv=0;
sum_jv=0;
对于jj=1:尺寸(箱,2)
对于ii=1:尺寸(料仓,1)
sum_v=sum_v+bin(ii,jj);
sum_iv=sum_iv+ii*bin(ii,jj);
sum_jv=sum_jv+jj*bin(ii,jj);
结束
结束
质心=[sum_iv,sum_jv]/sum_v;
当然,您可以迭代标记图像的每个标签
img
,并应用上述代码。但这是非常低效的。相反,我们可以在图像中循环一次,同时计算所有质心。我们将
sum\u v
等转换为向量,每个标签包含一个运行总和:

N=max(img(:);%标签数量
和v=零(N,1);
sum_iv=零(N,1);
sum_jv=零(N,1);
对于jj=1:尺寸(img,2)
对于ii=1:尺寸(img,1)
指数=img(ii,jj);
如果索引>0
总和v(指数)=总和v(指数)+1;
sum_iv(指数)=sum_iv(指数)+ii;
sum_jv(指数)=sum_jv(指数)+jj;
结束
结束
结束
质心=[sum_iv,sum_jv]。/sum_v;

谢谢您的帮助,效果很好!但是我注意到,当我运行它时,它现在在命令窗口中列出了一个数组中的质心,y坐标在左列,x坐标在右列。我不明白它为什么这么做?它应该像[x y]一样列出它们?我可以通过将最后一行更改为[sum_jv,sum_iv]./sum_v来交换它们,但我不确定为什么会这样。@KarlDilkington:在MATLAB中,第一个索引
I
是行号(y坐标),第二个索引
j
是列号(x坐标)。此外,索引从1开始。我遵守了那个惯例。如果愿意,您可以在上面的
i
j
中进行交换。