【OpenCV】人脸旋转角度计算


// SeetaFacesTest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <iostream>  
#include <cstdint>
#include <fstream>
#include <string>
#include <cmath>

#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/imgproc/imgproc.hpp>  // Gaussian Blur

#include "face_detection.h"
#include "face_alignment.h"


using namespace cv;
using namespace std;

int main()
{
	// Initialize face detection model
	seeta::FaceDetection detector("seeta_fd_frontal_v1.0.bin");
	detector.SetMinFaceSize(80);
	detector.SetScoreThresh(2.f);
	detector.SetImagePyramidScaleFactor(0.8f);
	detector.SetWindowStep(4, 4);

	// Initialize face alignment model 
	seeta::FaceAlignment point_detector("seeta_fa_v1.1.bin");

	//load image
	const char* picturename = "10.jpg";

	cv::Mat img_grayscale = cv::imread(picturename, 0);
	cv::Mat img_color = cv::imread(picturename, 1);
	if (img_grayscale.empty())
	{
		return 0;
	}

	seeta::ImageData img_data;
	img_data.data = img_grayscale.data;
	img_data.width = img_grayscale.cols;
	img_data.height = img_grayscale.rows;
	img_data.num_channels = 1;


	// Detect faces
	std::vector<seeta::FaceInfo> faces = detector.Detect(img_data);
	int32_t face_num = static_cast<int32_t>(faces.size());

	if (face_num == 0)
	{
		return 0;
	}

	// Detect 5 facial landmarks
	seeta::FacialLandmark points[5];
	point_detector.PointDetectLandmarks(img_data, faces[0], points);

	Rect face_rect;
	face_rect.x = faces[0].bbox.x;
	face_rect.y = faces[0].bbox.y;
	face_rect.width = faces[0].bbox.width;
	face_rect.height = faces[0].bbox.height;

	cv::Mat img_rect(img_grayscale, face_rect);  //截取脸部
	cv::namedWindow("img_grayscale", CV_WINDOW_NORMAL);
	cv::imshow("img_grayscale", img_rect);

	

	//-------计算角度--------
	int x1 = points[0].x;
	int y1 = points[0].y;
	int x2 = points[1].x;
	int y2 = points[1].y;
	cout << "0: " << x1 << ", " << y1 << endl;
	cout << "1: " << x2 << ", " << y2 << endl;
	double dX = (double)(x2 - x1);
	double dY = (double)(y2 - y1);
	float nAngle = (float)(atan(dY / dX)*180/3.1415926);
	cout << "nAngle:" << nAngle << endl;

	RotatedRect rrect(cvPoint(points[2].x, points[2].y), Size(face_rect.width, face_rect.height), nAngle);
	Point2f vertices[4];
	rrect.points(vertices);
	for (int i = 0; i < 4; i++){
		line(img_color, vertices[i], vertices[(i + 1) % 4], Scalar(0, 255, 150));
	}

		
	// Visualize the results
	cv::rectangle(img_color, face_rect, Scalar(150, 255, 0), 5, 8, 0);
	for (int i = 0; i < 5; i++)
	{
		cout << i << ": " << points[i].x << ", " << points[i].y << endl;
		cv::circle(img_color, cvPoint(points[i].x, points[i].y), 10, CV_RGB(0, 255, 0), CV_FILLED);
	}
	cv::namedWindow("result", CV_WINDOW_NORMAL);
	cv::resizeWindow("result", 484, 644);
	cv::imshow("result", img_color);
	cv::waitKey(0);
	cv::imwrite("result.jpg", img_color);


	return 0;
}


// SeetaFacesTest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <iostream>  
#include <cstdint>
#include <fstream>
#include <string>
#include <cmath>

#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/imgproc/imgproc.hpp>  // Gaussian Blur

#include "face_detection.h"
#include "face_alignment.h"


using namespace cv;
using namespace std;

//逆时针旋转图像degree角度(原尺寸)  
void rotateImage(const cv::Mat src, const cv::Mat& img_rotate, double degree)
{
	//旋转中心为图像中心  
	Point2f center;
	center.x = float(src.cols / 2.0 + 0.5);
	center.y = float(src.rows / 2.0 + 0.5);
	int length = 0;
	length = sqrt(src.cols*src.cols + src.rows*src.rows);
	//计算二维旋转的仿射变换矩阵
	Mat M = getRotationMatrix2D(center, degree, 1);
	warpAffine(src, img_rotate, M, Size(length, length));//仿射变换
}

int main()
{
	// Initialize face detection model
	seeta::FaceDetection detector("seeta_fd_frontal_v1.0.bin");
	detector.SetMinFaceSize(80);
	detector.SetScoreThresh(2.f);
	detector.SetImagePyramidScaleFactor(0.8f);
	detector.SetWindowStep(4, 4);

	// Initialize face alignment model 
	seeta::FaceAlignment point_detector("seeta_fa_v1.1.bin");

	//load image
	const char* picturename = "10.jpg";

	cv::Mat img_grayscale = cv::imread(picturename, 0);
	cv::Mat img_color = cv::imread(picturename, 1);
	if (img_grayscale.empty())
	{
		return 0;
	}

	seeta::ImageData img_data;
	img_data.data = img_grayscale.data;
	img_data.width = img_grayscale.cols;
	img_data.height = img_grayscale.rows;
	img_data.num_channels = 1;


	// Detect faces
	std::vector<seeta::FaceInfo> faces = detector.Detect(img_data);
	int32_t face_num = static_cast<int32_t>(faces.size());

	if (face_num == 0)
	{
		return 0;
	}

	// Detect 5 facial landmarks
	seeta::FacialLandmark points[5];
	point_detector.PointDetectLandmarks(img_data, faces[0], points);

	//Rect face_rect;
	//face_rect.x = faces[0].bbox.x;
	//face_rect.y = faces[0].bbox.y;
	//face_rect.width = faces[0].bbox.width;
	//face_rect.height = faces[0].bbox.height;

	//---------------------
	Rect face_rect;
	int tempx0 = points[0].x < points[3].x ? points[0].x : points[3].x;
	int tempx1 = points[1].x > points[4].x ? points[1].x : points[4].x;
	int nfaceW = (int)((tempx1 - tempx0)*2.2);
	int tempy0 = points[0].y > points[1].y ? points[0].y : points[1].y;
	int tempy1 = points[3].y > points[4].y ? points[3].y : points[4].y;
	int nfaceH = (int)((tempy1 - tempy0)*2.2);
	//int FaceWidth = (nfaceW > nfaceH ? nfaceW : nfaceH) * 1.3;
	int x0 = points[2].x - nfaceW / 2;
	int y0 = points[2].y - nfaceW / 2;
	int w0 = nfaceW;
	int h0 = nfaceW;
	face_rect.x = x0;
	face_rect.y = y0;
	face_rect.width = w0;
	face_rect.height = h0;

	cv::Mat img_rect(img_color, face_rect);  //截取脸部
	cv::circle(img_rect, cvPoint(img_rect.cols / 2, img_rect.rows / 2), 10, CV_RGB(0, 255, 0), CV_FILLED);

	cv::namedWindow("img_rect", CV_WINDOW_NORMAL);
	cv::imshow("img_rect", img_rect);
	cout << "img_rect : " << img_rect.cols << ", " << img_rect.rows << endl;

	//-------计算角度--------
	int x1 = points[0].x;
	int y1 = points[0].y;
	int x2 = points[1].x;
	int y2 = points[1].y;
	cout << "0: " << x1 << ", " << y1 << endl;
	cout << "1: " << x2 << ", " << y2 << endl;
	double dX = (double)(x2 - x1);
	double dY = (double)(y2 - y1);
	float Angle = (float)(atan(dY / dX)*180/3.1415926);
	cout << "nAngle:" << Angle << endl;

	//--------------------------------
	int length = 0;
	length = sqrt(img_rect.cols*img_rect.cols + img_rect.rows*img_rect.rows);
	cv::Mat tempImg(length, length, img_rect.type());//临时图像,大小和输出图像一样大
	int ROI_x = length / 2 - img_rect.cols / 2;//ROI矩形左上角的x坐标  
	int ROI_y = length / 2 - img_rect.rows / 2;//ROI矩形左上角的y坐标  
	Rect ROIRect(ROI_x, ROI_y, img_rect.cols, img_rect.rows);//ROI矩形  
	Mat tempImgROI2(tempImg, ROIRect);//tempImg的中间部分
	img_rect.copyTo(tempImgROI2);//将原图复制到tempImg的中心
	cv::namedWindow("tempImg", CV_WINDOW_NORMAL);
	cv::imshow("tempImg", tempImg);

	cv::Mat dst_image;
	Point2f center(float(length / 2.0), float(length / 2.0));//旋转中心
	Mat M = getRotationMatrix2D(center, (double)Angle, 1);//计算旋转的仿射变换矩阵
	warpAffine(tempImg, dst_image, M, Size(length, length));//仿射变换
	cout << "dst_image : " << dst_image.cols << ", " << dst_image.rows << endl;
	cv::circle(dst_image, cvPoint(dst_image.cols / 2, dst_image.rows / 2), 10, CV_RGB(150, 255, 0), CV_FILLED);

	cv::namedWindow("dst_image", CV_WINDOW_NORMAL);
	cv::imshow("dst_image", dst_image);

	//-----------------------
	int ndstfaceW = (int)((float)nfaceW/2.2*1.5);
	Rect dst_rect;
	dst_rect.x = dst_image.cols / 2 - ndstfaceW / 2;
	dst_rect.y = dst_image.rows / 2 - ndstfaceW / 2;
	dst_rect.width = ndstfaceW;
	dst_rect.height = ndstfaceW;

	cv::Mat img_dst_face(dst_image, dst_rect);  //截取脸部
	cv::namedWindow("img_dst_face", CV_WINDOW_NORMAL);
	cv::imshow("img_dst_face", img_dst_face);

	//-------------------
	RotatedRect rrect(cvPoint(points[2].x, points[2].y), Size(face_rect.width, face_rect.height), Angle);
	Point2f vertices[4];
	rrect.points(vertices);
	for (int i = 0; i < 4; i++){
		line(img_color, vertices[i], vertices[(i + 1) % 4], Scalar(0, 255, 150));
	}
		
	// Visualize the results
	cv::rectangle(img_color, face_rect, Scalar(150, 255, 0), 5, 8, 0);
	for (int i = 0; i < 5; i++)
	{
		cout << i << ": " << points[i].x << ", " << points[i].y << endl;
		cv::circle(img_color, cvPoint(points[i].x, points[i].y), 10, CV_RGB(0, 255, 0), CV_FILLED);
	}
	cv::namedWindow("result", CV_WINDOW_NORMAL);
	cv::resizeWindow("result", 484, 644);
	cv::imshow("result", img_color);
	cv::waitKey(0);
	cv::imwrite("result.jpg", img_color);


	return 0;
}


评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值