3D点云人脸鼻尖检测算法

最近一直在做3D人脸鼻尖识别项目,因为之前没有相关经验,所以前后花了一个半月才做完。

在此记录一下自己的思路:

1.读取人脸点云数据,代码为Matlab代码:

clc;
read_file = importdata('C:\myfiles\xyz\test1\test3\3.xyz'); %读取文件
file_x = read_file(:,1);
file_y = read_file(:,2);
file_z = read_file(:,3);
set(figure,'name','点云');
plot3(file_x,file_y,file_z,'.')

 显示的点云:

 

2.对人脸数据做插值处理,这里直接做的网格化。

[X,Y,Z] = griddata(file_x,file_y,file_z,linspace(min(file_x),max(file_x),200)',linspace(min(file_y),max(file_y),20),'cubic'); %插值
set(figure,'name','网格');
surf(Z);  %显示三维曲面

 网格化:

3.对每个Y轴的切片做半圆相交处理(这里我选择用半圆,因为人脸的俯视图是凹的,这跟深度摄像头采集的数据有关,FRGC数据集里面的人脸俯视图是凸的),圆心在切片上滑动,半径采用固定值(我用的是30),相交得到两个交点,计算这两个点和圆心组成的三角形中,以这两个点为底的三角形高H。H的值就是鼻尖置信点的值

这里我写了一个演示代码,方便大家理解这个在切片上做圆,找鼻尖置信点的过程:

% 单层切片遍历所有点,标出鼻尖置信点和两个交点
clc;
read_file = importdata('C:\myfiles\xyz\test1\test3\3.xyz'); %读取文件
file_x = read_file(:,1);
file_y = read_file(:,2);
file_z = read_file(:,3);
% set(figure,'name','点云');
% plot3(file_x,file_y,file_z,'.')
[X,Y,Z] = griddata(file_x,file_y,file_z,linspace(min(file_x),max(file_x),200)',linspace(min(file_y),max(file_y),20),'cubic'); %插值
% set(figure,'name','网格');
% surf(Z);  %显示三维曲面

xz = Z(13,:); %获取水平切片,这里的13是自己随便取的一层切片
x = 1:200;
yqu = xz(1,x);
set(figure,'name','切片');
plot(x,yqu);
%画圆
I = find(~isnan(xz)); %获取水平切片非空位置
[x_s,~] = min(I); %水平切片有效起始位置
[x_e,~] = max(I); %水平切片有效终止位置
%r = round((x_e-x_s)/5); %自适应因切圆半径(效果并不好)
r = 30; %指定切圆的半斤,效果更好
h_gaos = []; %切片中每个点作为圆心和切片形成的交点所形成的三角形的高集合
for x1 = x_s+r:x_e-r %圆心的可取值范围
    if x1>1 %避免水平切片太小
        z1 = xz(1,x1); %切片中对应z的坐标
        i = x1-r:x1+r; %圆心的取值范围
        y2 = sqrt(r.^2-(i-x1).^2)+z1; %切圆的z坐标(上半圆)
        y = xz(1,i);
        cy = y2-y;
        pos = cy>0;
        neg = cy<=0;
        %确定变号位置
        fro = diff(pos)~=0; %变号的前导位置
        rel = diff(neg)~=0; %变号的尾巴位置
        zpf = find(fro==1); %记录索引
        zpr = find(rel==1)+1; %记录索引
        zpfr = [zpf,zpr];
        x0 = (i(zpr).*(y2(zpf)-y(zpf))-i(zpf).*(y2(zpr)-y(zpr)))./(y(zpr)+y2(zpf)-y(zpf)-y2(zpr));
        y0 = y(zpf)+(x0-i(zpf)).*(y(zpr)-y(zpf))./(i(zpr)-i(zpr)-i(zpf));
        x0 = [x0 x0].';
        y0 = [y0 y0].';
        jie = unique(
  • 8
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 26
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值