이 질문을 팔로우합니다.
- 팔로우하는 게시물 피드에서 업데이트를 확인할 수 있습니다.
- 정보 수신 기본 설정에 따라 이메일을 받을 수 있습니다.
Converting 3D to 2D cloud of points
조회 수: 6 (최근 30일)
이전 댓글 표시
Alfonso
2018년 6월 30일
I am trying to convert a set of data which is a cloud of points from 3D to 2D, I am using this code:
% Function from 3D to 2D
function [D,R,T]=dimred(X)
T = repmat(mean(X),[size(X,1),1]);
XX = X-T;
[R,N]=eig(XX'*XX);
D=XX*R;
D=D(:,2:end);
Q=[zeros(size(D,2),1) eye(size(D,2))];
R=Q*R';
return
% 3D to 2D
[nodes_2D,R,T]=dimred(newnodes1) % R = rot matrix, T = Translation matrix
The data correctly converts to 2D, in this case, looking at the image the 3D points are rotated to the left, but for a different cloud of points it rotates it to the right. My question is the next, is there any way of forcing to apply the rotation always in the same direction? (without manually reversing the 2D red plot).
I have attached the figure and the .mat containing the cloud of points in 3D.
Thank you for any help.
댓글 수: 10
Walter Roberson
2018년 6월 30일
I notice you use the eigenvectors as returned. Any scalar multiple of an eigenvector acts the same way, including negative multiples. As I do not see any code in there to explicitly normalize, I wonder if the difficulty you are facing is that some of your eigenvectors just happen to be coming out with the negative of the sign you are expecting for the purposes of rotation ?
Alfonso
2018년 6월 30일
편집: Alfonso
2018년 6월 30일
Hello Walter, you are right, the eigenvectors are in SOME cases coming up with the opposite sign that I want them to, and I don't know why this happens, it seems that depending on the initial 3D data, it gets flattened to the left or to the right. My objective is to always get the same "2D view" of my 3D cloud of points (always flattened to the right for example).
These are the 2 only possibilities of 2D result from the 3D blue data. Currently for this dataset, I obtain the red 2D plot, but I want the magenta one which I have been able to plot reversing the R (rotation matrix). The problem as I said, is that the result obtained (red or magenta) changes for each 3D dataset, so I don't know how to detect before seeing the plots if the rotation has been the one I want (magenta) or not.
I hope my explanation does not look too messy,
Thank you
Walter Roberson
2018년 6월 30일
편집: Walter Roberson
2018년 6월 30일
Can you divide each eigenvector by its first non-zero element, so that the leading entries are all 0 or positive ?
Alfonso
2018년 6월 30일
For this 3D dataset using the code I posted I get the following:
% R = Eigenvalues
R =
0.0600 0.3950 -0.9167
0.4589 0.8047 0.3768
% N = Right Eigenvectors
N =
1.0e+05 *
0.0000 0 0
0 2.4094 0
0 0 3.1734
So right eigenvectors result in 0/+ when dividing by the 1st element, did you mean this or am I getting confused?
I also uploaded the .mat file with the 3D data in the initial post.
Walter Roberson
2018년 6월 30일
I meant like
for K = 1 : size(R,2)
firstR = find(R(:,K),1,'first');
R(:,K) = R(:,K) ./ firstR;
end
... Of course there are ways to vectorize this, but it is simply not worth the trouble.
Alfonso
2018년 6월 30일
In order for the division to be +/0 all values of each column in R should have the same sign, this never or rarely happens as I have seen for other 3D datasets.
Walter Roberson
2018년 6월 30일
Perhaps it is only one particular one of the dimensions that needs to be positive and you can divide by the sign of that particular dimension?
Note: your comments are reversed above, R is the eigenvectors and diag(N) are the eigenvalues.
Alfonso
2018년 6월 30일
When I try to transform from 3D to 2D several datasets, in some of them I get the correct 2D view but the ones I don't get correctly are always reversed in Y. So if for example I do this:
R(:,2) = R(:,2) * -1;
And then transform to 2D, I obtain the correct 2D view (in the case the first result was the wrong view).
Maybe the sign of one of the values of the eigenvector corresponding to Y axis determines if it is flattened to the right or left, I have to take a look, but could this be?
Walter Roberson
2018년 6월 30일
for K = 1 : size(R,2)
s = sign(R(2,K));
R(:,K) = R(:,K) .* s;
end
You need to transform the entire eigenvector.
Alfonso
2018년 7월 1일
Hello Walter, it does not seem to work. For a 3D dataset 1 it flattens it to the left side, whereas for a 3D dataset 2 of the same plane as dataset 1 it flattens it to the right (same behaviour I had).
3D dataset1:
3D dataset2:
채택된 답변
Matt J
2018년 6월 30일
편집: Matt J
2018년 6월 30일
normal=null(XX);
normal=normal(:,end)*sign(normal(1,end));
rotaxis=-cross([0,0,1].',normal);
theta=asind(norm(rotaxis));
[D,R,~] = AxelRot(XX.', theta, rotaxis, []);
댓글 수: 11
Alfonso
2018년 6월 30일
편집: Alfonso
2018년 6월 30일
Hello Matt, as you are using XX I assume the code you wrote must go inside the function I posted after: XX = X-T?
I have tried this:
X = newnodes1;
T = repmat(mean(X),[size(X,1),1]);
XX = X-T;
normal=null(XX);
normal=normal(:,end)*sign(normal(1,end));
rotaxis=-cross([0,0,1].',normal);
theta=asind(norm(rotaxis));
[2D_data,R,~] = AxelRot(XX.', theta, rotaxis, []);
but the transformation from 3D to 2D does nor perform correctly, surely I am misunderstanding something.
Matt J
2018년 6월 30일
편집: Matt J
2018년 6월 30일
"2D_data" is not a valid Matlab variable name. That will surely throw an error.
Try this,
X = newnodes1;
T = repmat(mean(X),[size(X,1),1]);
XX = X-T;
normal=null(XX);
normal=normal(:,end);
rotaxis=cross(normal,[0,0,1].');
s=-sign(mean(sign(rotaxis(1:2)))); %decide which way is "left"
rotaxis=s*rotaxis;
theta=acosd(s*normal(3));
[D,R,~] = AxelRot(XX.', theta, rotaxis, []);
D=D(1:2,:).';
Alfonso
2018년 7월 1일
편집: Alfonso
2018년 7월 1일
Hello Matt, I am testing it with all my 3D datasets right now. If I have understood correctly, if I mantain the sign of 's' as, say +, it will always force the rotation to go the same way, so the 3D data will always flatten in this direction (what is what I'm looking for),
I'll let you know when I finish testing the datasets,
Thank you.
Alfonso
2018년 7월 1일
편집: Alfonso
2018년 7월 1일
Works perfectly as I want to with the 3D dataset I initially posted and also work right for 3D datasets that belong to the same plane as the initial dataset, but I have tried with a different 3D cloud of points that belong to another plane and all values in the resulting 2D data are NaN, do you know what might be the problem?
Seems to me maybe the problem is in here (I am not sure)
s=-sign(mean(sign(rotaxis(1:2))));
rotaxis(1:2)=
0.0000
-0.4472
% So the sign will be the mean between 1 and -1, which is 0
rotaxis=s*rotaxis; % will give [0;0;0]
also warning messages appear:
Warning: Matrix is singular, close to singular or badly scaled. Results may be inaccurate. RCOND = NaN.
> In AxelRot (line 94)
> In AxelRot (line 63)
I have attached the 3D dataset,
Thank you.
Matt J
2018년 7월 1일
편집: Matt J
2018년 7월 1일
You need to give us a more precise and general definition of "rotate to the left". Which way is "left", in general, if the 3D orientation of the cloud can be arbitrary? Perhaps this?
normal=null(XX);
normal=normal(:,end);
rotaxis=cross(normal,[0,0,1].');
[~,idx]=max(abs(rotaxis));
s=-sign(rotaxis(idx)); %decide which way is "left"
Alfonso
2018년 7월 1일
I will try this code. In order to understand what I mean, I have attached two figures, one represents que 3D data converted to 2D rotated to the "left" and the other figure is rotated to the "right". Manually rotate the figures and that way I think you will know what I mean by left/right.
Thank you.
Matt J
2018년 7월 1일
편집: Matt J
2018년 7월 1일
OK, well see if you like my last implementation.
However, your attached .fig files don't clear up the ambiguity. Your notions of "right" and "left" appear to depend arbitrarily on the plot camera angle. For example, if we were to rotate the plot perspective 180 degrees about the z-axis, so that we were viewing the original blue points from the opposite side, then left would become right and right would become left.
To put it another way, suppose your blue points lay entirely in the xz-plane. I know you want the points rotated clockwise all the time about a consistent axis, and I know that axis is either the positive x-axis or the negative x-axis, but which one is it? Similarly, what about if the data is in the yz-plane. Do we rotate clockwise about y or about -y?
Alfonso
2018년 7월 1일
편집: Alfonso
2018년 7월 1일
Yes, it is quite ambiguous, but it's hard to explain. Look at this view, I want the the 2D data to be like the 3D data in this view. The result is the magenta plot, which is like if you pushed the top part of the blue plot with your hand about 90º. This is the 2D "view" I am looking for for all my 3D datasets.
I have tried your new code and seems to work right. I have 3 type of 3D data planes, for one I get the 2D view I want with - sign for the second one with + sign, and the third one is a horizontal plane so I just put the angle of rotation to 0 and I get the correct view.
I will test it with more 3D datasets of this 3 planes to see if for all datasets of the same plane it satisfies the same sign (-/+), but at the moment it looks like it works just as I wanted.
for example this is what I should get (a general sign for all datasets of the same plane):
All 3D datasets of plane1: correct view with sign -
All 3D datasets of plane2: correct view with sign +
Matt J
2018년 7월 2일
편집: Matt J
2018년 7월 2일
which is like if you pushed the top part of the blue plot with your hand about 90º
That is not consistent with your original post. In your original post we were pulling, not pushing. And the point to be clarified is still how you decide whether to push or pull.
Alfonso
2018년 7월 4일
Hello Matt, with a few modifications I think I finally got it to work right. Thank you for your help.
추가 답변 (0개)
참고 항목
카테고리
Help Center 및 File Exchange에서 Point Cloud Processing에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!오류 발생
페이지가 변경되었기 때문에 동작을 완료할 수 없습니다. 업데이트된 상태를 보려면 페이지를 다시 불러오십시오.
웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 MathWorks 사이트 방문이 최적화되지 않았습니다.
미주
- América Latina (Español)
- Canada (English)
- United States (English)
유럽
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
아시아 태평양
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)