У меня есть два образца трехмерного облака точек человеческого лица.Синее облако точек обозначает целевую грань, а красное облако точек обозначает шаблон.На рисунке ниже показано, что цель и грань шаблона выровнены в разных направлениях (грань цели примерно вдоль оси x, грань шаблона примерно вдоль оси y).
Рисунок 1:
Область вокруг носа показана на рисунке 1.
Я хочу повернуть целевое лицо (синее лицо) кончиком носа, какцентр вращения (я перевел цель на шаблон до рисунка 1, так что кончик носа, то есть centerpt
, для обеих граней накладывается), чтобы он выровнялся с гранью шаблона (красная грань).Я повернул целевую грань следующим кодом MATLAB:
% PCA for the target face
targetFaceptfmt = pointCloud(targetFace); % Convert to point cloud format
point = [templateFace(3522, 1), templateFace(3522, 2), templateFace(3522, 3)]; % The 3522th point in the templateFace is the nasal tip point used as center of rotation later on
radius = 20; % 20mm
[NNTarIndex, NNTarDist] = findNeighborsInRadius(Locationptfmt, point, radius); % Find all vertices within 20 of the nasal tip point on the target face
NNTar = select(Locationptfmt, NNTarIndex); % Select the identified points for PCA
[TarVec,TarSCORE,TarVal] = pca(NNTar.Location); % Do PCA for target face using vertices close to the nasal tip
% PCA for the template face
templateFaceptfmt = pointCloud(templateFace); % Convert to point cloud format
[NNTemIndex, NNTemDist] = findNeighborsInRadius( templateFaceptfmt, point, radius); % Find all vertices within 20 of the nasal tip point on the template
NNTem = select(templateFaceptfmt, NNTemIndex); % Select the identified points for PCA
[TemVec,TemSCORE,TemVal] = pca(NNTem.Location); % Do PCA for template face using vertices close to the nasal tip
% Rotate target face with nasal tip point as the center of rotation
targetFace_r = R * (targetFace-cenertpt)' + centerpt';
targetFace_new = targetFace_r';
, где targetFace
и templateFace
содержат координаты для необращенной целевой грани и грани шаблона соответственно.targetFace_r
содержит координаты для целевой грани после поворота вокруг кончика носа, R
- матрица вращения, рассчитанная с помощью PCA (см. здесь для определения формулы вращения), а centerpt
- носовойнаконечник, который используется в качестве центра вращения.Затем я построил транспонированную targetFace_r
, то есть targetFace_new
, с нормалями, добавленными к каждой вершине:
Рисунок 2: ![enter image description here](https://i.stack.imgur.com/ImMO2.jpg)
Перед вращением,нормали для целевой грани и грани шаблона обычно указывают в одинаковых направлениях (рисунок 1).После поворота цель и грань шаблона выровнены вдоль оси y (что я и хочу), однако нормали для целевой грани и грани шаблона указывают в противоположные стороны.Принимая во внимание, что не было никаких изменений в грани шаблона, я понял, что нормалей целевой грани, вычисленных после вращения, перевернуты.Но я не знаю почему. Я использовал функцию checkFaceOrientation
пакета Rvcg в R, чтобы проверить, увеличивает ли расширение по нормали размер центроида.Мне вернули значение ИСТИНА для грани шаблона, но ЛОЖЬ для целевой грани, которая подтверждает, что нормали вершин для целевой грани были перевернуты.
Нормы вершин были вычислены в MATLAB следующим образом:
TR = triangulation(Faces, Vertices); % Triangulation based on face and vertex information
VN = vertexNormal(TR); % Calculate vertext normal
где Faces
содержит информацию о лице, т. е. список связности, а Vertices
содержит координаты для вершин.Для целевой грани перед вращением, целевой грани после вращения и грани шаблона нормали вершин вычислялись отдельно.Я использовал те же самые данные Faces
для вычисления нормали вершины до и после вращения целевой грани.
Перевернутые нормали вершины привели к ошибкам для дальнейшего анализа.В результате я должен вручную перевернуть нормали, чтобы они указывали аналогично нормали на лицевой стороне шаблона.
Рисунок 3:
На рисунке 3 показано, что после переворачивания нормалей вручнуюнормали целевого лица и грани шаблона обычно указывают одинаково в направлении.
Мой вопрос: почему нормали целевого лица, вычисленные после поворота, перевернулись?В каком случае вращение трехмерного облака точек приводит к перевороту нормалей вершин?
Дополнительная информация, которая может оказаться полезной: полученная мной матрица вращения R
выглядит следующим образом:
0.0473096146726546 0.867593376108813 -0.495018720950670
0.987013081649028 0.0355601323276586 0.156654567895508
-0.153515396665006 0.496001220483328 0.854643675613313
С trace(R) = 1 + 2cos(alpha)
я вычислил альфа через acos((trace(R)-1)/2)*180/pi
, что дало угол поворота 91,7904 относительно точки кончика носа.