Преобразуйте угловые количественные данные в качественные изображения
Я кристаллограф, пытаюсь проанализировать ориентацию кристаллов из 5000 файлов. Может ли Matlab преобразовать значения углов в таблицу, которая выглядит следующим образом:
В таблицу, которая выглядит следующим образом?
2 ответа
Вот более конкретный пример, основанный на идее Лакеша. Тем не менее, это будет обрабатывать любое количество вращения. Сначала начните с базового круглого изображения с полосой посередине. Как только вы это сделаете, просто запустите 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, это просто вопрос вставки 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
как видно из предыдущего примера, я получаю это изображение сейчас:
Обратите внимание, что левый верхний элемент матрицы имеет угол 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)