我们在网上可以看到大量优秀的摄影作品,如何利用机器从网上获取大量的图片,从中提取出最佳的摆拍姿势供拍照时参考?首先我们得有大量的优秀摄影图片。然后,需要思考如何获得摄影作品中人物姿势的数据?待下文慢慢道来:
阅读难度:★★★☆☆
技能要求:机器学习、前端基础
字数:1250字
阅读时长:5分钟
STEP1
爬虫获取大量的图片
STEP2
获取人体姿势数据
使用tensorflowJS(下文简写为tfjs)的posenet扩展库提取图片中人体的姿势数据
关于posenet扩展库,可查阅:
在html可以很方便地引用tfjs及posenet库:
html
posenet的调用也非常简单:
js
posenet.load().then(function(net){//这里把图片传入netreturnnet.estimateMultiplePoses(img)
}).then(function(_pose){varkeyPoints=getKeypoints(_pose);//这里把keyPoints保存下来,传入pose2vec函数varvec=pose2vec();//把vec都保存下来,最后用余弦相似度进行计算
});
获取的大量图片的姿势数据:
不熟悉tfjs?不要紧,这里给出一个入门路径供参考:
T1
熟悉JS的基本代码
T2
熟悉图像分类、姿势识别、文本分类
采用html引用tfjs包的形式,熟悉加载已训练好的模型进行练习。
T3
会用tfjs写线性回归、cnn、lstm等
T4
熟悉使用tfjs的迁移学习
经过4个基本的练习,整个tfjs的使用就差不多可以掌握了,剩下的遇到问题再查询tfjs的官方api文档即可,根据实际情况再选择深入了解机器学习相关的知识。
STEP3
pose2vec
把坐标点按照顺序转化为向量
这里不知大家还记得之前文章提到的word2vec吗?一个把文本映射到向量空间的算法,通过向量运算,可以用于发现化学元素、英文单词的近义词、推荐歌曲、挖掘影视剧的人物关系、挖掘作家文章观点、提炼色彩搭配关系等等。这里类似的道理,把人体姿势的关键点映射到向量空间,然后就可以方便我们进行一些向量运算(例如加减乘除)。
不记得word2vec,可以点击以下卡片回顾:
转化为向量的时候注意,每个关键点都是固定的位置,向量的长度也是固定的。若不存在此关键点,则对应的值取0。
functionpose2vec(keypoints){varkpObj={
"nose":,
"leftEye":1,
"rightEye":2,
"leftEar":3,
"rightEar":4,
"leftShoulder":5,
"rightShoulder":6,
"leftElbow":7,
"rightElbow":8,
"leftWrist":9,
"rightWrist":10,
"leftHip":11,
"rightHip":12,
"leftKnee":13,
"rightKnee":14,
"leftAnkle":15,
"rightAnkle":16};
varres=[];for(leti=;i
varkps=newArray(17);
for(letj= 0;j
constk=ks[j];
//只框选出人,size是这个人的区域所在
varp=[(k.position.x -size.x),
(k.position.y -size.y)];
kps[kpObj[k.part]]= p;
};
kps =kps.toString().split(',');
res.push(kps);
};
};
STEP4
如何找出相似的摄影姿势?
大家可以思考下,有什么方法?
在机器学习和数据挖掘中,我们经常需要知道个体间差异的大小,进而评价个体的相似性和类别。相似性我们一般通过距离来判断,类别我们有分类和聚类算法,如 K 最近邻(KNN)和 K 均值(K-Means)等。而距离度量,常见的有:
闵可夫斯基距离
欧几里得距离
曼哈顿距离
切比雪夫距离
马氏距离
余弦相似度
皮尔逊相关系数
汉明距离
杰卡德相似系数
编辑距离
DTW 距离
KL 散度
本文采用余弦相似度(Cosine similarity):
余弦相似度与向量的幅值无关,只与向量的方向相关,在文档相似度(TF-IDF)和图片相似性(histogram)计算上都有它的身影。需要注意一点的是,余弦相似度受到向量的平移影响,为了消除平移影响我们可以引入皮尔逊相关系数(Pearson correlation)皮尔逊相关系数具有平移不变性和尺度不变性。
余弦相似度,用tfjs实现下:
x=tf.tensor1d([,1,1,1]);
y=tf.tensor1d([1,2,3,4]);
p1=tf.sqrt(x.mul(x).sum());
p2=tf.sqrt(y.mul(y).sum());
p12=x.mul(y).sum();
score=p12.div(p1.mul(p2));
score.print();
根据实际情况进行封装即可。
STEP5
产品原型
一些计算结果:
以上为全文,本文是mixlab无界社区超级节点MLN-003的指南:
前端玩转AI之Tensorflow.JS workshop:
我们会在本节点开展包括基础的JS练习指南,进阶的各种应用指南,还有线下的workshop活动。
如何加入,微信公众号回复:超级节点。
近期活动推荐:
谷歌开发者社区与mixlab无界社区联合主办的千人大会:
--------------------------------------
mixlab 无界社区是一所面向未来的实验室,它提倡“跨界创新,开放成长”的理念。——跨界 开放 互助 学习 思维 创新。详细介绍点击以下卡片:
mixlab期待您的加入!
让你具备无限可能……
不赞赏下?
不点下广告?
不转发下?
荐书:
开复老师最近新出的一本书
领取专属 10元无门槛券
私享最新 技术干货