人脸crop
2015-08-17 15:29
429 查看
转载自:http://jasonding1354.github.io/2014/12/02/Machine%20Learning/【计算机视觉】对检测的人脸进行剪切和归一化/
基本思路如下:
根据两眼的倾斜角度对图像进行旋转校正
根据两眼在图片中的实际距离和自定义的偏移量进行图片的缩放
下面是剪切的效果图,最终的图片是100*100像素,偏移量是0.3
其代码为:
解释一下代码:
偏移量是指眼睛到图片上边界和左右边界的距离比例,比如0.3的偏移量,那么左眼到左边界,右眼到右边界的长度占所剪切的人脸图片宽度为0.3,同理到上边界的距离也占图片高度的0.3。
根据两眼的实际距离和两眼依偏移量所应占据图片宽度的比例对图片进行缩放,比如实际距离是求一个欧式距离eye_distance,参考的距离eye_reference是输出的宽度outputWidth减去左眼到左边界的0.3 outputWidth,再减去右眼到右边界的0.3 outputWidth。
由于最终要做人脸识别,需要输出灰度图,所以,最后的返回值是经过灰度化并且直方图均衡化了的图片
这里涉及到了仿射变换,可以参考OpenCV官方文档,放射变换。
这里我以左眼的中心点作为旋转的输入原点,cv::getRotationMatrix2D()生成了表示仿射变换的2 * 3矩阵。
人脸剪切的策略
这里我设想的最基本的人脸剪切方法是根据人眼的位置进行人脸的旋转和校正的。基本思路如下:
根据两眼的倾斜角度对图像进行旋转校正
根据两眼在图片中的实际距离和自定义的偏移量进行图片的缩放
下面是剪切的效果图,最终的图片是100*100像素,偏移量是0.3
其代码为:
12345678910111213141516171819202122232425262728293031323334353637383940 | cv::Mat FaceClassifer::cropFacesBasedOnEye(cv::Rect faceRect, cv::Point leftEye,cv::Point rightEye, float offset,int outputWidth,int outputHeight){ int offset_h = floor(offset * outputWidth); int offset_v = floor(offset * outputHeight); int eyegap_h = rightEye.x-leftEye.x; int eyegap_v = rightEye.y-leftEye.y; float eye_distance = sqrt(pow(eyegap_h,2)+pow(eyegap_v,2)); float eye_reference = outputWidth - 2*offset_h; float scale = eye_distance/eye_reference; //rotate original around the left eye cv::Mat rotatedImage; if(eyegap_v != 0) { double rotation = atan2f((float)eyegap_v,(float)eyegap_h); double degree = rotation*180/CV_PI; rotateFace(_image, leftEye, degree, rotatedImage); } //crop the rotated image cv::Point crop_xy(leftEye.x-scale*offset_h,leftEye.y-scale*offset_v); cv::Size crop_size(outputWidth*scale, outputHeight*scale); cv::Rect crop_area(crop_xy, crop_size); cv::Mat cropFace; if(eyegap_v == 0) cropFace = _image(crop_area); else cropFace = rotatedImage(crop_area); //resize the face cv::resize(cropFace,cropFace,cv::Size(outputWidth,outputHeight)); cv::Mat croppedGray; cv::cvtColor(cropFace,croppedGray,CV_BGR2GRAY); cv::equalizeHist(croppedGray, croppedGray); return croppedGray;} |
偏移量是指眼睛到图片上边界和左右边界的距离比例,比如0.3的偏移量,那么左眼到左边界,右眼到右边界的长度占所剪切的人脸图片宽度为0.3,同理到上边界的距离也占图片高度的0.3。
根据两眼的实际距离和两眼依偏移量所应占据图片宽度的比例对图片进行缩放,比如实际距离是求一个欧式距离eye_distance,参考的距离eye_reference是输出的宽度outputWidth减去左眼到左边界的0.3 outputWidth,再减去右眼到右边界的0.3 outputWidth。
由于最终要做人脸识别,需要输出灰度图,所以,最后的返回值是经过灰度化并且直方图均衡化了的图片
图片旋转的API
这里图片旋转用到了OpenCV的函数,warpAffine()。这里涉及到了仿射变换,可以参考OpenCV官方文档,放射变换。
12345 | void FaceClassifer::rotateFace(cv::Mat& src,cv::Point& pt,double angle,cv::Mat& dst){ cv::Mat r = cv::getRotationMatrix2D(pt, angle, 1.0); cv::warpAffine(src, dst, r, cv::Size(src.cols,src.rows));} |
相关文章推荐
- linux 下定时connect实现在线检测
- Tomcat系统架构及启动分析
- Hadoop实战之温度排序
- Nginx---基础知识. Nginx特色
- Linux下SVG浏览存在问题及解决方法
- linux上安装配置vsftpd
- 做网站用UTF-8还是GB2312?
- sqoop基本 操作
- Linux环境Nginx安装与调试以及PHP安装
- Linux写时拷贝技术(copy-on-write)
- 浅析电子政务工程建设项目的建章立制
- Apache 的BeanUtils 拷贝日期对象转换问题
- Linux____用户和群组进阶学习笔记
- stretchableImageWithLeftCapWidth: topCapHeight:拉伸图
- [转]部署war包到tomcat的几个问题
- linux基础之find初认识
- UVA_10739_StringToPalindrome
- 修复OpenStack-Horizon遇到的UnicodeDecodeError
- OpenGL ES 雾
- LINUX创建本地yum源