Obecnie muszę napisać program używający matlab do transformacji macierzy za pomocą jednorodnych współrzędnych, takich jak ta
% for translation
T = [1 0 dx; 0 1 dy; 0 0 1];
Na przykład:
A =
92 99 1 8 15 67 74 51 58 40
98 80 7 14 16 73 55 57 64 41
4 81 88 20 22 54 56 63 70 47
85 87 19 21 3 60 62 69 71 28
86 93 25 2 9 61 68 75 52 34
17 24 76 83 90 42 49 26 33 65
23 5 82 89 91 48 30 32 39 66
79 6 13 95 97 29 31 38 45 72
10 12 94 96 78 35 37 44 46 53
11 18 100 77 84 36 43 50 27 59
>> I = translate(A, 4, 4)
I =
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN 92 99 1 8 15 67
NaN NaN NaN NaN 98 80 7 14 16 73
NaN NaN NaN NaN 4 81 88 20 22 54
NaN NaN NaN NaN 85 87 19 21 3 60
NaN NaN NaN NaN 86 93 25 2 9 61
NaN NaN NaN NaN 17 24 76 83 90 42
Gdzie NaN
komórki oznaczają „puste spacje”. Jak widać, macierz A
przesunęła 4 jednostki na osi x
i 4 jednostki na osi y
, pozostawiając wartości NaN
. Macierz wyjściowa I
musi mieć taki sam rozmiar jak A
.
Jednak mój obecny program nie działa poprawnie przy użyciu obrazów (nie umieszcza wartości „NaN” w pustych miejscach, umieszcza „1”):
Oto mój program:
function t_matrix = translate(input_matrix, dx, dy)
[rows cols] = size(input_matrix);
t_matrix = input_matrix;
t_matrix(:) = NaN;
T = [1 0 dx; 0 1 dy; 0 0 1];
for n = 1:numel(input_matrix)
[x y] = ind2sub([rows cols], n);
v = [x y 1]';
v = T*v;
a = floor(v(1));
b = floor(v(2));
if a > 0 && b > 0
t_matrix(a, b) = input_matrix(x,y);
end
end
t_matrix = t_matrix(1:rows, 1:cols);
Jak w łatwiejszy sposób zaimplementować transformację jednorodną za pomocą programu Matlab?
Jedyne ograniczenie: nadal używaj tej matrycy:
% for translation
T = [1 0 dx; 0 1 dy; 0 0 1];
I zachowaj wartości NaN dla pustych przestrzeni.
2 odpowiedzi
Problem z twoim kodem może polegać na tym, że operujesz na liczbach całkowitych, a NaN jest wartością podwójną. Nie możesz przypisać input_matrix do t_matrix. Powinieneś utworzyć t_matrix za pomocą funkcji nan:
t_matrix = nan(size(input_matrix));
Poniżej znajduje się bezpośrednie tłumaczenie twojego kodu, właśnie usunąłem pętlę
function I = translate(input_matrix, dx, dy)
% get matrix dimensions
[rows cols] = size(input_matrix);
T = [1 0 dx; 0 1 dy; 0 0 1];
% create a nan's output matrix
I = nan(size(input_matrix));
% create row-column index pairs
[R C] = meshgrid(1:cols, 1:rows);
% append 1 at the end
IDX = [R(:) C(:) ones(numel(input_matrix),1)]';
% transform coordinates
V = floor(T*IDX);
% find indices that fall into [rows, cols] range
keep = find(V(1,:)>0 & V(1,:)<=rows & V(2,:)>0 & V(2,:)<=cols);
% assign output only to the correct indices
I(sub2ind([rows cols], V(1,keep), V(2,keep))) = input_matrix(sub2ind([rows cols], R(keep), C(keep)))
end
Z drugiej strony możesz uzyskać ten sam wynik, co w pytaniu, po prostu uruchamiając następującą funkcję (choć bez macierzy T..)
function I = translate(A, dx, dy)
I = nan(size(A));
I(dx+1:end, dy+1:end) = A(1:end-dx, 1:end-dy);
end
Najłatwiejszym sposobem osiągnięcia tego celu, jeśli masz zestaw narzędzi do przetwarzania obrazu, jest użycie wbudowanych funkcji maketform
i imtransform
:
I = imread('cameraman.tif');
dx = 40;
dy = 100;
tform = maketform('affine',[1 0 0; 0 1 0; dx dy 1]); %#Create a translation matrix
J = imtransform(I,tform,'XData',[0 size(I,2)+dx],'YData',[0 size(I,1)+dy]);
imshow(I), figure, imshow(J)
- Macierz podana jako dane wejściowe do
maketform
jest transpozycją twojej macierzy - Ważne jest, aby ustawić
XData
iYData
, w przeciwnym razie nie uzyskasz "efektu tłumaczenia", ponieważimtransform
znajduje najmniejszy zakres wyjściowy. - Jeśli chcesz uzyskać taki sam rozmiar jak obraz początkowy, użyj następującej składni:
.
J = imtransform(I,tform,'XData',[0 size(I,2)],'YData',[0 size(I,1)]);
Obraz przed:
Obraz po:
Obraz po (zachowując ten sam rozmiar):
Podobne pytania
Nowe pytania
matlab
MATLAB to język wysokiego poziomu i interaktywne środowisko programistyczne do obliczeń numerycznych i wizualizacji opracowane przez MathWorks. Nie używaj zarówno tagów [matlab], jak i [octave], chyba że pytanie wyraźnie dotyczy podobieństw lub różnic między nimi. Używając tego tagu, podaj wersję MATLAB, z którą pracujesz (np. R2017a).