Verfasst am: 31.01.2010, 12:49
Titel: Matrix drehen oder Geradengleichung in Matrix einbauen
Tach auch!
Sorry erstmal für den komischen Thread-Namen, kann mich momentan nicht besser Ausdrücken...
Zu meinem Problem:
Ich möchte gerne eine Matrix der Dimension 1024x1024 erstellen, die mit Nullen und Einsen besetzt ist. Die Matrixeinträge sollen dabei Winkelabhängig sein, d.h. abhängig vom Winkel sollen die Einsen umsortiert werden. Hatte dabei an eine Geradengleichung gedacht.
Eine 45° Gerade habe ich schon hinbekommen, hier mein Code:
Ich möchte aber gerne die Möglichkeit haben, noch andere Winkel einzustellen, habe aber Momentan ein Brett vorm Kopf.
Vielleicht weiß ja jemand einen schnellen Ansatz.
Danke erstmal für die schnelle Antwort. Leider bringt die Funktion imrotate nicht die geüwnschte Funktion mit sich. Die Funktion nimmt sich den Bereich der Einsen und dreht diesen entsprechend. Ich hab nen Bild angehangen um das Problem zu zeigen.
die Rotation ist in der Tat nicht einfach. Zunächst sollte man sich darüber einigen, was bei der Rotation passieren soll.
Wenn man ein rechteckiges Bild hat, das z.B. un 20° gedreht wird, dann wird die Bildgröße des Ergebnisbildes von der des Originalbildes abweichen.
Benötigt man die gleiche Bildgröße, dann muss eine Cropping-Funktion implementiert werden.
Mein Vorschlag:
Sei Z dein Bild, dann erzeuge Matrizen X und Y, die die Bildpositionen darstellen.
Danach die Rotation auf diese Matrizen X und Y derart anwenden, daß neue Positionen enthalten sind [cos(phi), sin(phi)].
Jedem Bildpunkt Z entspricht nun eine neue Koordinate x0, y0.
Achtung: Diese "Pixelpositionen" können zu Leerstellen oder Doppelbesetzungen der neuen Bildmatrix führen.
Danach müsste man entscheiden ob eine neue Pixelposition durch Mittelwertbildung oder Extrapolation von Bildpixeln erzeugt wird.
Hier könnten Dir auch die Sparse-Funktionen von MatLab helfen.
Verfasst am: 04.02.2010, 14:43
Titel: Eine Alternative zu imrotate
Hi,
für die vorhandene Aufgabenstellung habe ich mal schnell was in QtOctave eingehämmert, was auch schön zu funktionieren scheint.
Eigentlich müsste der Code 1:1 funktionieren. Bei Octave gibt es jedoch die Sparse-Funktion mit einem optionalen Argument "unique". Hier wird bei Mehrfachzuweisungen das Maximum der Elemente, die auf eine Position zugewiesen werden, verwendet.
Damit es keinen Konflikt mit der Funktion "imrotate" gibt, habe ich die Funktion picrotate genannt.
Code:
function Arot=picrotate(A,ang,modus);
%% picrotate - Rotate a Matrix (Picture) by the angle ang [rad]
%%
%% Arot=picrotate(A,ang,[modus])
%%
%% At first the position of non-zero elements are determined.
%% On the positions we perform the rotation. The rotated picture
%% will have other dimensions (depending on the angle), so that
%% a further normalization to new pixel positions will be performed.
%%
%% A new assignment to the pixel with help of sparse functions is done.
%% The filling of possible gaps is done by mean value calculation of
%% surrounding non-zero elements.
%%
%% The optional input argument modus determines, who multiple assigned
%% positions and gaps after rotation are handled:
%%
%% modus=0 (Default) : The mean value ist taken
%% modus=1 : The maximum value is used
%%
%% A.J. Geissler, February 2010, Seeheim-Jugenheim, Germany
[Z,S]=size(A); % Determine the size of the input picture [pz,ps,V]=find(A); % Determine positions of non-zero elements
PosOld=[pz.';ps.']; % Represent positions as matrix
R=[cos(ang),-sin(ang);sin(ang),cos(ang)]; % The Transformation Matrix
PosNew=(R*(PosOld-1)).'; % New Positions by multiplication with TR-Matrix
pz2=PosNew(:,1); % Extract new lines and columns from the result
ps2=PosNew(:,2);
Zneu=(Z-1)*abs(cos(ang)) + (S-1)*abs(sin(ang)); % Calculate the new dimensions of the rotated picture
Sneu=(Z-1)*abs(sin(ang)) + (S-1)*abs(cos(ang));
pz3=floor(Zneu* (pz2 - min(pz2)) ./(max(pz2) - min(pz2))) + 1; % Normalize the new coordinates to new
ps3=floor(Sneu* (ps2 - min(ps2)) ./(max(ps2) - min(ps2))) + 1; % dimensions. Take Care: GAPS !
Zneu=Zneu+1; % Here we adopt the range to starting index 1
Sneu=Sneu+1; % of lines and columns
if modus!=0,
Arot=full(sparse(pz3,ps3,V,Zneu,Sneu,"unique")); % Assign the pixel values to new coordinates % with the option "unique", the max value of pixels % which are assigned to one position is taken else
Nput=full(sparse(pz3,ps3,ones(size(pz3)),Zneu,Sneu)); % Number of Assignments to new positions
Arot=full(sparse(pz3,ps3,V,Zneu,Sneu)); % Assign pixel values to new coordinates
Arot(Nput!=0)=Arot(Nput!=0) ./Nput(Nput!=0); % If several pixels are assigned to one position, % we take the mean value of them.
endif
Z=zeros(Zneu-2,Sneu-2); % Now we determine the number of empty positions % by analysis of its 8 neighbours for p=-1:1:1,
for s=-1:1:1,
if !(p==0 & s==0), % Don't take the origin pixel !
Aakt=Arot(2+p:1:Zneu-1+p,2+s:1:Sneu-1+s);
Z=Z + (Aakt==0); % If a neighbour pixel is zero, we increment
endif % the counter
endfor
endfor
[pz,ps]=find(Z); % These are the positions of gaps [Zneu,Sneu]=size(Arot);
ArotVek=Arot.'; % The rotated picture is vectorized in order
ArotVek=ArotVek(:); % to perform further sub-indices-adressings
Z=[zeros(1,Sneu-2);Z;zeros(1,Sneu-2)]; % Here we fit the dimension of the Gap-Counter
Z=[zeros(Zneu,1),Z,zeros(Zneu,1)]; % matrix to the size of the rotated picture
Zvek=Z.'(:); % Vectorize -> Subadressing
for p=-1:1:1, % Empty pixels will be filled with the for s=-1:1:1, % mean value of non-empty pixels. if !(p==0 & s==0),
pzm=pzm0+p;
psm=psm0+s;
indices=psm + (pzm -1) .*Sneu;
if modus==0,
Sfill(indices0)=Sfill(indices0) + (ArotVek(indices) ./(8-Zvek(indices0)));
else
Sfill(indices0)=max(Sfill(indices0),ArotVek(indices));
endif
endif
endfor
endfor
Arot=reshape(Sfill,Sneu,Zneu).'; % Convert back to picture
vielen Dank erstmal für deine Mühen, find ich echt super wie du dich reinhängst
Nach langer Auszeit bin ich nun wieder mit dem Projekt beschäftigt und habe mir deinen Quellcode mal angeschaut. So ganz steige ich aber leider nicht durch, viele Operationen in der Matlab-File kann Matlab nicht so ganz verstehen. Vermutlich Inkompatibilität zwischen Octave und Matlab.
Habe schon so einiges auf Matlab-Syntax angepasst, habe aber an einigen Stellen Probleme mit dem Verständnis des Codes.
die Zeile b=a.'( macht eigentlich das Gleiche wie in MatLab.
Dort ist halt die direkte Zusammensetzung nicht möglich sondern Klammern werden benötigt.
Bsp.:
a=[1,2,3;4,5,6];
Nun wird erst transponiert
a.'=[1 4
2 5
3 6]
Danach wird ein Vektor erzeugt
b=[1
2
3
4
5
6]
_________________
Andreas Geißler
Einstellungen und Berechtigungen
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.