【问题标题】:Outputting Regionprops to csv in MATLAB在 MATLAB 中将 Regionprops 输出到 csv
【发布时间】:2016-01-25 16:31:33
【问题描述】:

我目前正在对很多图片进行一些数据分析,我运行的代码如下:

close all
clear all
clc

A=imread('Ring_1_frame_120.jpg');       %Load picture
                                        %A01-A010 = xmin ymin width height 
                                        %for all vials
A001=imcrop(A,[65 159 95 332]);
A002=imcrop(A,[182 161 95 332]);
A003=imcrop(A,[297 164 95 332]);
A004=imcrop(A,[402 165 90 332]);
A005=imcrop(A,[495 168 90 332]);
A006=imcrop(A,[606 166 90 332]);
A007=imcrop(A,[705 171 90 332]);
A008=imcrop(A,[808 175 90 332]);
A009=imcrop(A,[922 175 90 332]);
A0010=imcrop(A,[1031 175 90 332]);

w = who; % returns the names of all your current variables in a cell.

for i = 1:numel(w)
    % A00 is unique to all the variables you want to process.
    if ~isempty(strfind(w{i}, 'A00')) 
        % hard coding greenChannel and extracting the second plane.
        eval(['greenChannel = ',w{i},'(:,:,2)']); 
        BW = edge(greenChannel,'Prewitt');
           %figure, imshow(BW);

    %Dialate Lines
       se90 = strel('line', 3, 90);
       se0 = strel('line', 3, 0);
       BWsdil = imdilate(BW, [se90 se0]);
            %figure, imshow(BWsdil), title('dilated gradient mask');

    %Fill Lines
      BWdfill = imfill(BWsdil, 'holes');
            %figure, imshow(BWdfill), title('binary image with filled holes');
    %Clean up borders  
      BWnobord = imclearborder(BWdfill, 4);
            %figure, imshow(BWnobord), title('cleared border image');
    %Final cleanup
      seD = strel('diamond',1);
      BWfinal = imerode(BWnobord,seD);
      BWfinal = imerode(BWfinal,seD);
            figure, imshow(BWfinal), title('segmented image');

      L = bwlabel(BWfinal);
      s = regionprops(L,'centroid');
      data(:,:,i) = s; %save the xy coords as data matrix 
    end
end

我试图实现的目标是将变量 s 放入 csv 文件中,但由于它不起作用,我被困在最后一行。它不断地覆盖自己。 s 是一个从 3x1 到 5x1 的结构,我也尝试过使用 struct2cell 和 mat2cell,但没有成功。

【问题讨论】:

    标签: image matlab csv image-processing data-extraction


    【解决方案1】:

    s是一个结构体,所以你需要做的是解压结构体,让它变成一个矩阵,然后你可以将矩阵保存到文件中。 s 包含一个名为 Centroid 的字段,因此您需要访问该字段。

    但是,在我解决这一点之前,检查工作区中有多少变量,以便确定循环必须迭代多少次......是非常糟糕的做法。特别是如果您将每个变量名称作为单独的事件进行处理。我强烈建议您使用一种结构来封装这个或某种单元数组。

    如果我能提供一个规范的帖子,请咨询用户Adriaanexcellent post,了解如何避免动态变量名称,并阐明我要在这里讨论的内容。

    这样的东西可以代替。我将使用单元阵列,因为(至少对我而言)它更容易。将你想要的坐标放在一个二维矩阵中,其中每一行是你要处理的图像中位置的左上角以及宽度和高度(基本上适合imcrop),然后循环遍历每组坐标并将裁剪后的图像作为元素放置在元胞数组中。元胞数组的使用很重要,因为每个裁剪图像的尺寸不同,因此您不能在此处使用普通矩阵:

    A=imread('Ring_1_frame_120.jpg');       %Load picture
                                            %A01-A010 = xmin ymin width height 
    
    coords = [65 159 95 332; 182 161 95 332; 297 164 95 332; 402 165 90 332;...
              495 168 90 332; 606 166 90 332; 705 171 90 332; 808 175 90 332;...
              922 175 90 332; 1031 175 90 332];
    
    numImages = size(coords,1);
    images = cell(1,numImages);
    
    for ii = 1 : numImages
        images{ii} = imcrop(A,coords(ii,:));
    end
    

    images 现在是属于图像A 的裁剪图像的元胞数组。要访问正确的图像,您可以使用images 这样做:

    img = images{ii};
    

    ii 是您要访问的图像编号。我想说的另一条评论是您对eval 的使用。在您的循环中也确实不建议这样做......这就是我决定改变逻辑的原因。

    改为这样做:

    for ii = 1 : numImages
        % hard coding greenChannel and extracting the second plane.
        greenChannel = images{ii}(:,:,2); %// Change for green channel
    
        %// Now code is the same as before
        BW = edge(greenChannel,'Prewitt'); 
        %figure, imshow(BW);
    
        %Dilate Lines
        se90 = strel('line', 3, 90);
        se0 = strel('line', 3, 0);
        BWsdil = imdilate(BW, [se90 se0]);
        %figure, imshow(BWsdil), title('dilated gradient mask');
    
        %Fill Lines
        BWdfill = imfill(BWsdil, 'holes');
        %figure, imshow(BWdfill), title('binary image with filled holes');
    
        %Clean up borders  
        Wnobord = imclearborder(BWdfill, 4);
        %figure, imshow(BWnobord), title('cleared border image');
    
        %Final cleanup
        seD = strel('diamond',1);
        BWfinal = imerode(BWnobord,seD);
        BWfinal = imerode(BWfinal,seD);
        figure, imshow(BWfinal), title('segmented image');
    
       ...
    end
    

    好的,那么现在我们如何获取质心的坐标并将它们保存到文件中呢?您只需解压缩结构并获取质心坐标。确保在顶部声明 data 现在是一个元胞数组:

    data = cell(1, numImages);
    

    您需要一个元胞数组的原因(再次)是因为您不知道您正在查看的每个裁剪图像有多少分段组件。现在终于在循环结束时:

    for ii = 1 : numImages
       %// Your code...
       %//...
    
       L = bwlabel(BWfinal);
       s = regionprops(L,'centroid');
    
       %// New code
       data{ii} = reshape([s.Centroid],2,[]).';
    end
    

    现在您已将每个裁剪图像的质心坐标存储在一个元胞数组中,您可以创建多个 CSV,其中每个 CSV 包含每个裁剪图像的每个检测到的对象的质心,或者您可以将所有质心连接在一起单个矩阵。

    所以,做任何一个:

    for ii = 1 : numImages
        csvwrite(sprintf('data%d.csv', ii), data{ii});
    end
    

    ... 或

    out = cat(1, data{:});
    csvwrite('data.csv', out);
    

    我不确定您要使用哪种方法写入文件,但其中任何一种都应该有效。

    【讨论】:

      【解决方案2】:

      您需要使用 s(i).Centroid 访问结构元素,作为一个最小示例,

      a =imread('circlesBrightDark.png');
      bw = a < 100;
      s = regionprops(bw,'centroid');
      
      for i =1:size(s)
          data(:,:,i) = s(i).Centroid
      end
      

      【讨论】:

        猜你喜欢
        • 2013-01-05
        • 1970-01-01
        • 1970-01-01
        • 2016-01-09
        • 1970-01-01
        • 2015-10-15
        • 2011-06-16
        • 1970-01-01
        • 2015-01-17
        相关资源
        最近更新 更多