Creation of binary coded image from a matrix

4 visualizaciones (últimos 30 días)
Dror Aizik
Dror Aizik el 5 de Ag. de 2024
Comentada: Stephen23 el 6 de Ag. de 2024
Hi
I am looking for a fast code to do the following:
  • get a matrix with elements between 0 and 15
  • create a new matrix, double the size (both rows and columns)
  • for each element in the first matrix, set the binary representation of this element in the new matrix, in a 2x2 way.
first example
for a 1x1 input matrix:
A =
7
The result will be:
B =
0 1
1 1
Second example
for a 2x2 input matrix:
A =
0 2
1 3
The result will be:
B =
0 0 0 0
0 0 1 0
0 0 0 0
0 1 1 1
=
Currently, I do this with a slow for loop.
I would greatly apreciate your help.
Dror
  2 comentarios
Walter Roberson
Walter Roberson el 5 de Ag. de 2024
for a 2x2 input matrix:
A =
0 2
1 3
The result will be:
B =
0 0 0 0
0 0 1 0
0 0 0 0
0 1 1 1
I do not understand the logic for that.
If the binary is intended to go across rows, then you have two outputs that are 0 0 0 0 which would require two elements that are the same, but no input elements are the same as each other.
If the binary is intended to go down columns, then you have two outputs that are [0; 0; 0; 1] which would require two elements that are the same, but no input elements are the same as each other.
Voss
Voss el 5 de Ag. de 2024
Editada: Voss el 5 de Ag. de 2024
Each element of the input becomes a 2x2 square in the output, e.g.
0 -> [0 0 0 0] -> [0 0; 0 0]
1 -> [0 0 0 1] -> [0 0; 0 1]
2 -> [0 0 1 0] -> [0 0; 1 0]
3 -> [0 0 1 1] -> [0 0; 1 1]
4 -> [0 1 0 0] -> [0 1; 0 0]
5 -> [0 1 0 1] -> [0 1; 0 1]
6 -> [0 1 1 0] -> [0 1; 1 0]
7 -> [0 1 1 1] -> [0 1; 1 1]
etc.

Iniciar sesión para comentar.

Respuesta aceptada

Voss
Voss el 5 de Ag. de 2024
Here's one way, which will work for any non-empty matrix A.
A = [0 2; 1 3]
A = 2x2
0 2 1 3
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
B = getB(A);
disp(B)
0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 1
A larger example:
A = randi([0,15],5,6)
A = 5x6
10 12 7 7 3 9 9 11 10 9 12 2 2 12 3 0 5 14 5 4 10 14 8 5 5 9 4 8 13 2
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
B = getB(A);
disp(B)
1 0 1 1 0 1 0 1 0 0 1 0 1 0 0 0 1 1 1 1 1 1 0 1 1 0 1 0 1 0 1 0 1 1 0 0 0 1 1 1 1 0 0 1 0 0 1 0 0 0 1 1 0 0 0 0 0 1 1 1 1 0 0 0 1 1 0 0 0 1 1 0 0 1 0 1 1 0 1 1 1 0 0 1 0 1 0 0 1 0 1 0 0 0 0 1 0 1 1 0 0 1 1 0 1 1 0 0 0 1 0 1 0 0 0 0 0 1 1 0
function B = getB(A)
[r,c] = size(A);
M = dec2bin(A,4)-'0';
B = NaN(2*r,2*c);
B(1:2:end,1:2:end) = reshape(M(:,1),r,[]);
B(1:2:end,2:2:end) = reshape(M(:,2),r,[]);
B(2:2:end,1:2:end) = reshape(M(:,3),r,[]);
B(2:2:end,2:2:end) = reshape(M(:,4),r,[]);
end
  3 comentarios
Voss
Voss el 6 de Ag. de 2024
You're welcome!
Stephen23
Stephen23 el 6 de Ag. de 2024
+1 very neat use of matrices and indexing.

Iniciar sesión para comentar.

Más respuestas (2)

Stephen23
Stephen23 el 6 de Ag. de 2024
Editada: Stephen23 el 6 de Ag. de 2024
A = [0,2;1,3;7,14]
A = 3x2
0 2 1 3 7 14
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Method one: BLOCKPROC (requires image toolbox, probably not very fast):
F = @(s)reshape(dec2bin(s.data,4)-'0',2,2).';
B = blockproc(A,[1,1],F)
B = 6x4
0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 1 0 1 1 1 1 1 1 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Method two: RESHAPE, PERMUTE (should be reasonably fast):
S = size(A);
M = dec2bin(A(:),4)-'0';
B = reshape(permute(reshape(M,[S,2,2]),[4,1,3,2]),2*S)
B = 6x4
0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 1 0 1 1 1 1 1 1 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>

Sahas
Sahas el 6 de Ag. de 2024
From what I gather, you would like to transform an integer matrix into a binary-coded matrix with a specific pattern.
I was able to get the required matrix in a more efficient manner by using MATLAB’s “vectorization” of arrays method where I could get the required result in a much more optimized way, without using for-loops.
function B = bin_coded_matrix(A)
% Get the size of the input matrix
[m, n] = size(A);
%Converting it to a column vector
A_col = A(:);
%Converting each element into 4-bit binary
binRep = dec2bin(A_col, 4) - '0';
%Reshaping the binary representation to 2x2 blocks as per the
%requirement
binMatrix = reshape(binRep.', 2, 2, []);
binMatrix = permute(binMatrix, [2, 1, 3]);
%Pre-allocating matrices for much faster results
B = zeros(2*m, 2*n);
%Placing the 2x2 binary blocks in the appropriate places in output
for k = 1:numel(A_col)
%Get the row and column indices for the output matrix
[i, j] = ind2sub([m, n], k);
%Placing the 2x2 binary block in the output matrix
B(2*i-1:2*i, 2*j-1:2*j) = binMatrix(:, :, k);
end
end
%Examples and timings
tic;
A3 = [7];
B3 = bin_coded_matrix(A3)
toc;
tic;
A4 = [0 2; 1 3];
B4 = bin_coded_matrix(A4)
toc;
tic;
A6 = [0 1 2 3; 4 5 6 7; 8 9 10 11; 12 13 14 15];
B6 = bin_coded_matrix(A6)
toc;
Here is a snippet of the output matrices with different sizes and their execution times.
For learning more about vectorization, decimal to binary conversion and reshaping the matrix, refer to the MathWorks documentations below:
  1 comentario
Image Analyst
Image Analyst el 6 de Ag. de 2024
"without using for-loops"???
" for k = 1:numel(A_col)"
Not that for loops are slow. It may have been true decades ago but it's a myth now. I've done tens of millions of iterations in less than a second.

Iniciar sesión para comentar.

Categorías

Más información sobre Logical en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by