将角度定量数据转换为定性图像

时间:2014-10-15 17:40:32

标签: image matlab image-processing angle quantitative

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

enter image description here

进入一个看起来像这样的表?:

enter image description here

2 个答案:

答案 0 :(得分:4)

这是一个基于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;

通过以上所述,这就是我得到的:

enter image description here

现在,您需要做的就是创建一个最终输出图像,其中包含与矩阵中的行和列一样多的图像。假设您的旋转矩阵值存储在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

enter image description here


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

编辑以在角度为0

时不显示线条

如果您希望使用上面的代码,如果角度大约为0,则只显示黑色圆圈,只需在if循环内插入for语句即可创建另一个图像,其中包含一个没有条带的黑色圆圈。满足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 <= angle <= tol内的任何内容都绘制了黑色圆圈。这是为了在比较时允许浮点容差,因为直接用浮点值执行相等运算永远不是一个好主意。通常,可以接受的做法是在一定程度的容差范围内进行比较,以确定您要测试的平等程度。

使用上面修改过的代码和角度M矩阵,如上例所示,我现在得到这个图像:

enter image description here

请注意,矩阵的左上角条目的角度为0,因此可视化为黑色圆圈,没有像我们期望的那样通过它。

答案 1 :(得分:0)

解决问题的一般想法:

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)