#include <QCoreApplication>
#include<iostream>
#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
using namespace std;
using namespace cv;
struct Face5P
{
Point2f leye;
Point2f reye;
Point2f lmouse;
Point2f rmouse;
Point2f nose;
};
Mat getwarpAffineImg(Mat &src, Face5P & menglu)
{
Mat oral;
src.copyTo(oral);
Mat CeImg;
oral.copyTo(CeImg);
/*for (int j = 0; j < landmarks.size(); j++)
{
circle(oral, landmarks[j], 5, Scalar(255, 0, 0));
}*/
circle(oral, menglu.leye, 5,Scalar(255, 0, 0));
circle(oral, menglu.reye, 5, Scalar(255, 0, 0));
circle(oral, menglu.lmouse, 5,Scalar(255, 0, 0));
circle(oral, menglu.rmouse, 5, Scalar(255, 0, 0));
circle(oral, menglu.nose, 5, Scalar(255, 0, 0));
line(oral, menglu.leye, menglu.reye, Scalar(255, 0, 0), 1);
line(oral, menglu.lmouse, menglu.rmouse, Scalar(255, 0, 0),1);
//计算两眼中心点,按照此中心点进行旋转, 第31个为左眼坐标,36为右眼坐标
Point2i eyesCenter = Point2i((menglu.leye.x + menglu.reye.x) * 0.5f, (menglu.leye.y + menglu.reye.y) * 0.5f);
Point2i mouseCenter = Point2i((menglu.lmouse.x + menglu.rmouse.x) * 0.5f, (menglu.lmouse.y + menglu.rmouse.y) * 0.5f);
cout<<"yuaneye"<<eyesCenter.x<<" "<<eyesCenter.y<<endl;
cout<<"yuanmouth"<<mouseCenter.x<<" "<<mouseCenter.y<<endl;
cout<<"==================================="<<endl;
Point2i P0, P1;
P0.x= eyesCenter.x - src.size().width / 2;
P0.y = eyesCenter.y - src.size().height / 2;
circle(oral, eyesCenter, 3, Scalar(255, 255, 0));
circle(oral, mouseCenter, 3,Scalar(255, 255, 0));
cv::imshow("liu", oral);
waitKey();
// 计算两个眼睛间的角度
double dy = (menglu.reye.y - menglu.leye.y);
double dx = (menglu.reye.x - menglu.leye.x);
double angle = atan2(dy, dx) * 180.0 / CV_PI; // Convert from radians to degrees.
//P1.x = P0.x*cos(angle) - P0.y*sin(angle)+
float resize_scale = 48.0 / (mouseCenter.y-eyesCenter.y);
cout << "centermouse and centereye distance: " << (mouseCenter.y - eyesCenter.y) << endl;
cout<< "resizescale is" << resize_scale << endl;
Mat rot_mat = getRotationMatrix2D(eyesCenter, angle, resize_scale);
//由eyesCenter, andle, scale按照公式计算仿射变换矩阵,此时1.0表示不进行缩放
//Mat rot_mat = getRotationMatrix2D(eyesCenter, angle, 1.0); //旋转中心点、旋转角度、缩放因子
//imshow("rot_mat",rot_mat);
Mat rot;
// 进行仿射变换,变换后大小为src的大小
warpAffine(src, rot, rot_mat, src.size());
//vector<Point2i> marks;
Point2i Aleye;
Point2i Areye;
Point2i Almouse;
Point2i Armouse;
//按照仿射变换矩阵,计算变换后各关键点在新图中所对应的位置坐标。
//变换后的眼睛的坐标及中心点坐标
Aleye.x = rot_mat.ptr<double>(0)[0] *menglu.leye.x + rot_mat.ptr<double>(0)[1] * menglu.leye.y + rot_mat.ptr<double>(0)[2];
Aleye.y = rot_mat.ptr<double>(1)[0] * menglu.leye.x + rot_mat.ptr<double>(1)[1] * menglu.leye.y + rot_mat.ptr<double>(1)[2];
Areye.x = rot_mat.ptr<double>(0)[0] * menglu.reye.x + rot_mat.ptr<double>(0)[1] * menglu.reye.y + rot_mat.ptr<double>(0)[2];
Areye.y = rot_mat.ptr<double>(1)[0] * menglu.reye.x + rot_mat.ptr<double>(1)[1] * menglu.reye.y + rot_mat.ptr<double>(1)[2];
Point2i AeyeCenter = Point2i((Aleye.x+Areye.x)*0.5f,(Aleye.y+Areye.y)*0.5f );
//变换后的嘴角的坐标及中心点坐标
Almouse.x = rot_mat.ptr<double>(0)[0] * menglu.lmouse.x + rot_mat.ptr<double>(0)[1] * menglu.lmouse.y + rot_mat.ptr<double>(0)[2];
Almouse.y = rot_mat.ptr<double>(1)[0] * menglu.lmouse.x + rot_mat.ptr<double>(1)[1] * menglu.lmouse.y + rot_mat.ptr<double>(1)[2];
Armouse.x = rot_mat.ptr<double>(0)[0] * menglu.rmouse.x + rot_mat.ptr<double>(0)[1] * menglu.rmouse.y + rot_mat.ptr<double>(0)[2];
Armouse.y = rot_mat.ptr<double>(1)[0] * menglu.rmouse.x + rot_mat.ptr<double>(1)[1] * menglu.rmouse.y + rot_mat.ptr<double>(1)[2];
Point2i AmouseCenter = Point2i((Almouse.x+Armouse.x)*0.5f, (Almouse.y+Armouse.y)*0.5f);
cout<<"aftereye"<<AeyeCenter.x<<AeyeCenter.y<<endl;
cout<<"aftermouth"<<AmouseCenter.x<<AmouseCenter.y<<endl;
cout<<"======================================="<<endl;
// forehand
Point2i Aforehand;
Point2i LAforehand;
Point2i RAforehand;
Point2i Jaw;
int DisEye;
DisEye = abs(Areye.x - Aleye.x);
Aforehand = Point2i(AeyeCenter.x, AeyeCenter.y-DisEye);
LAforehand = Point2i(AeyeCenter.x - abs(Areye.x - Aleye.x), AeyeCenter.y - abs(Areye.x - Aleye.x));
RAforehand = Point2i(AeyeCenter.x + abs(Areye.x - Aleye.x), AeyeCenter.y - abs(Areye.x - Aleye.x));
Jaw = Point2i(AmouseCenter.x, AmouseCenter.y+abs(Armouse.x-Almouse.x));
//for (int n = 0; n < landmarks.size(); n++)
//{
// Point2f p = Point2f(0, 0);
// p.x = rot_mat.ptr<double>(0)[0] * landmarks[n].x + rot_mat.ptr<double>(0)[1] * landmarks[n].y + rot_mat.ptr<double>(0)[2];
// p.y = rot_mat.ptr<double>(1)[0] * landmarks[n].x + rot_mat.ptr<double>(1)[1] * landmarks[n].y + rot_mat.ptr<double>(1)[2];
// marks.push_back(p);
//}
//标出关键点
//for (int j = 0; j < landmarks.size(); j++)
//{
// circle(rot, marks[j], 2, Scalar(0, 0, 255));
//}
Mat CutImg;
rot.copyTo(CutImg);
circle(rot, Aleye, 3, Scalar(0, 0, 255));
circle(rot, Areye, 3, Scalar(0, 0, 255));
circle(rot, AeyeCenter, 2, Scalar(0, 0, 255));
circle(rot, Almouse, 3, Scalar(0, 0, 255));
circle(rot, Armouse, 3, Scalar(0, 0, 255));
circle(rot, Aforehand,2, Scalar(255, 0, 255));
circle(rot, Jaw, 2, Scalar(0, 0, 255));
line(rot, Aleye, Areye, Scalar(0, 255, 0), 1);
line(rot, Almouse, Armouse, Scalar(0, 255, 0), 1);
line(rot, LAforehand, RAforehand, Scalar(0, 255, 0), 1);
int crop_size=128;
int ec_y=40;
int crop_y;
int crop_x;
crop_y=AeyeCenter.y-ec_y;
crop_x=AeyeCenter.x-crop_size/2;
cout<<"crop "<<crop_x<<" "<<crop_y<<endl;
//return rot;
//Mat meng=Mat::zeros(Jaw.y - Aforehand.y, 2 * DisEye, CV_8UC3);
//meng = rot(Range(LAforehand.y, Jaw.y),Range(LAforehand.x, RAforehand.x));
//*************************//
//cv::Rect rect=cv::Rect(LAforehand.x, LAforehand.y, 2 * DisEye, Jaw.y - Aforehand.y);
cv::Rect rect=cv::Rect(crop_x,crop_y, crop_size, crop_size);
Mat meng=CutImg(rect);
//imwrite("D:\\qtTest\\facealignment\\liu.jpg",meng);
imshow("Meng",meng);
vector<int> compression_params;
compression_params.push_back(IMWRITE_PNG_COMPRESSION);
compression_params.push_back(9);
imwrite("im.jpg",meng,compression_params);
waitKey();
//cvSetImageROI(rot, cvRect(LAforehand.x, LAforehand.y, 2*DisEye, Jaw.y-Aforehand.y));
//return oral;
return rot;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Mat OriImg, reImg;
Face5P mengFace;
// mengFace.leye.x = 279.0;
// mengFace.leye.y = 95.0;
// mengFace.reye.x = 326.0;
// mengFace.reye.y = 106.0;
// mengFace.nose.x = 296.0;
// mengFace.nose.y = 124.0;
// mengFace.lmouse.x = 270.0;
// mengFace.lmouse.y = 144.0;
// mengFace.rmouse.x = 308.0;
// mengFace.rmouse.y = 151.0;
mengFace.leye.x = 337.0;
mengFace.leye.y = 270.0;
mengFace.reye.x = 401.0;
mengFace.reye.y = 266.0;
mengFace.nose.x = 371.0;
mengFace.nose.y = 299.0;
mengFace.lmouse.x = 353.0;
mengFace.lmouse.y = 334.0;
mengFace.rmouse.x = 394.0;
mengFace.rmouse.y = 333.0;
OriImg = imread("D:\\qtTest\\build-thread-Desktop_Qt_5_8_0_MSVC2013_32bit-Debug\\yuantu.jpg");
// OriImg = imread("D:\\qtTest\\facealignment\\7.jpg");
reImg = getwarpAffineImg(OriImg, mengFace);
imshow("mengl", reImg);
waitKey();
return a.exec();
}
opencv仿射变换
最新推荐文章于 2024-09-03 22:40:37 发布