【问题标题】:Convert angle quantitative data into qualitative images将角度定量数据转换为定性图像
【发布时间】:2014-12-10 21:27:50
【问题描述】:

我是一名晶体学家,试图从多达 5000 个文件中分析晶体取向。 Matlab 能否在如下所示的表格中转换角度值:

变成这样的表?:

【问题讨论】:

    标签: image matlab image-processing angle quantitative


    【解决方案1】:

    这里有一个基于 Lakesh 想法的更具体的例子。但是,这将处理任何数量的旋转。首先从中间有一条带的基本圆形图像开始。完成此操作后,只需运行 for 循环,将所有这些旋转图像堆叠在一个网格中,该网格类似于我们在该矩阵中看到的每个旋转角度的旋转值矩阵中看到的角度。

    诀窍是弄清楚如何定义基本方向图像。因此,让我们定义一个白色正方形,中间有一个黑色圆圈。我们还将在中间定义一个红色条带。现在,我们假设基本方向图像是 51 x 51。因此,我们可以这样做:

    %// Define a grid of points between -25 to 25 for both X and Y
    [X,Y] = meshgrid(-25:25,-25:25);
    
    %// Define radius
    radius = 22;
    
    %// Generate a black circle that has the above radius
    base_image = (X.^2 + Y.^2) <= radius^2;
    
    %// Make into a 3 channel colour image
    base_image = ~base_image;
    base_image = 255*cast(repmat(base_image, [1 1 3]), 'uint8');
    
    %// Place a strip in the middle of the circle that's red
    width_strip = 44;
    height_strip = 10;
    strip_locs = (X >= -width_strip/2 & X <= width_strip/2 & Y >= -height_strip/2 & Y <= height_strip/2);
    base_image(strip_locs) = 255;
    

    有了以上内容,我得到了:

    现在,您需要做的就是创建一个最终输出图像,其中包含与矩阵中的行和列一样多的图像。鉴于您的旋转矩阵值存储在M 中,我们可以使用图像处理工具箱中的imrotate 并指定'crop' 标志以确保输出图像与原始图像大小相同。但是,对于imrotate,旋转后图像中未出现的任何值都默认为0。您希望它在您的示例中显示为白色,因此我们将不得不做一些工作。您需要做的是创建一个与输入图像大小相同的logical 矩阵,然后以与基本图像相同的方式旋转它。在这个旋转的白色图像中,无论像素显示为黑色(也是false),这些都是我们需要设置为白色的值。因此:

    %// Get size of rotation value matrix
    [rows,cols] = size(M);
    
    %// For storing the output image
    output_image = zeros(rows*51, cols*51, 3);
    
    %// For each value in our rotation value matrix...
    for row = 1 : rows
        for col = 1 : cols
            %// Rotate the image
            rotated_image = imrotate(base_image, M(row,col), 'crop');
    
            %// Take a completely white image and rotate this as well.
            %// Invert so we know which values were outside of the image
            Mrot = ~imrotate(true(size(base_image)), M(row,col), 'crop');
    
            %// Set these values outside of each rotated image to white
            rotated_image(Mrot) = 255;
    
            %// Store in the right slot.
            output_image((row-1)*51 + 1 : row*51, (col-1)*51 + 1 : col*51, :) = rotated_image;
        end
    end
    

    让我们尝试几个角度以确保这是正确的:

    M = [0 90 180; 35 45 60; 190 270 55];
    

    使用上面的矩阵,这就是我得到的图像。这存储在output_image:


    如果您想将此图像保存到文件,只需执行imwrite(output_image, 'output.png');,其中output.png 是您要保存到磁盘的文件的名称。我选择了PNG,因为它是无损的,并且与其他无损标准相比文件大小相对较小(保存 JPEG 2000)。

    编辑以在角度为 0 时不显示线

    如果您希望使用上面的代码,如果您只想在角度为 0 时显示一个黑色圆圈,只需在 for 循环内插入一个 if 语句并创建另一个图像包含一个没有条纹的黑色圆圈。当满足if 条件时,您会将这个新图像放置在正确的网格位置,而不是带有红色条带的黑色圆圈。

    因此,使用上面的代码作为基线做这样的事情:

    %// Define matrix of sample angles
    M = [0 90 180; 35 45 60; 190 270 55];
    
    %// Define a grid of points between -25 to 25 for both X and Y
    [X,Y] = meshgrid(-25:25,-25:25);
    
    %// Define radius
    radius = 22;
    
    %// Generate a black circle that has the above radius
    base_image = (X.^2 + Y.^2) <= radius^2;
    
    %// Make into a 3 channel colour image
    base_image = ~base_image;
    base_image = 255*cast(repmat(base_image, [1 1 3]), 'uint8');
    
    %// NEW - Create a black circle image without the red strip
    black_circle = base_image;
    
    %// Place a strip in the middle of the circle that's red
    width_strip = 44;
    height_strip = 10;
    strip_locs = (X >= -width_strip/2 & X <= width_strip/2 & Y >= -height_strip/2 & Y <= height_strip/2);
    base_image(strip_locs) = 255;
    
    %// Get size of rotation value matrix
    [rows,cols] = size(M);
    
    %// For storing the output image
    output_image = zeros(rows*51, cols*51, 3);
    
    %// NEW - define tolerance
    tol = 5;
    
    %// For each value in our rotation value matrix...
    for row = 1 : rows
        for col = 1 : cols
    
            %// NEW - If the angle is around 0, then draw a black circle only
            if M(row,col) >= -tol && M(row,col) <= tol
                rotated_image = black_circle;
            else %// This is the logic if the angle is not around 0
                 %// Rotate the image
                rotated_image = imrotate(base_image, M(row,col), 'crop');
    
                %// Take a completely white image and rotate this as well.
                %// Invert so we know which values were outside of the image
                Mrot = ~imrotate(true(size(base_image)), M(row,col), 'crop');
    
                %// Set these values outside of each rotated image to white
                rotated_image(Mrot) = 255;                
            end
    
             %// Store in the right slot.
            output_image((row-1)*51 + 1 : row*51, (col-1)*51 + 1 : col*51, :) = rotated_image;
        end
    end
    

    上述代码中的变量tol 定义了一个公差,其中-tol &lt;= angle &lt;= tol 内的任何内容都绘制了黑色圆圈。这是为了在比较时允许浮点容差,因为直接对浮点值执行相等运算从来都不是一个好主意。通常,在您想要测试相等性的地方进行比较是公认的做法。

    将上述修改后的代码与前面示例中看到的角度矩阵 M 一起使用,我现在得到了这个图像:

    请注意,矩阵的左上角条目的角度为 0,因此可以将其可视化为一个黑色圆圈,如我们预期的那样,没有条纹穿过它。

    【讨论】:

    • 嗨 Rayryeng,你的代码对我的研究很有帮助,我想知道是否可以稍微调整一下。当值为零时,是否可以告诉您的程序显示一个没有线条的黑色圆圈
    • @Mosawi 下午好。是的,这应该很容易适应。我现在修改代码。
    • @Mosawi 已更改。祝你好运。
    【解决方案2】:

    解决您的问题的总体思路:

    1. Store two images, 1 for 0 degrees and 180 degrees and another for 90 and 270 degrees.
    
    2. Read the data from the file
    
    3. if angle = 0 || angle == 180
          image = image1
       else 
          image = image2
       end
    

    处理任何角度:

    1. Store one image. E.g image = imread('yourfile.png')
    2. angle = Read the data from the file
    3. B = imrotate(image,angle)
    

    【讨论】:

    • 这也应该能够处理任意旋转。 0、90 和 180 只是一个特例。
    • 谢谢lakesh,但是你如何在matlab中存储图像
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-13
    • 1970-01-01
    • 1970-01-01
    • 2016-10-28
    • 2014-11-10
    • 2018-09-29
    • 1970-01-01
    相关资源
    最近更新 更多