没有合适的资源?快使用搜索试试~ 我知道了~
计算机视觉测试报告2
需积分: 0 0 下载量 167 浏览量
2022-08-03
16:13:07
上传
评论
收藏 8.93MB PDF 举报
温馨提示
试读
17页
//获取中间每一帧的三角形网格//获取每一帧图与源图网格的变换矩阵2. 中间帧生成对其中一个三角形对来说,中间帧的生成过程是这样的:1) 通过变换矩阵T,求得三
资源详情
资源评论
资源推荐
计算机视觉测试报告
16340220 王培钰 电子政务
实现过程:
1. 网格的生成
将源图像和目标图像通过建立特征点,形成点集,然后通过三角剖分的方法形成三角形网络
1)把源图像中形成的三角形和目标图像生成的三角形(三角形对)对应起来。(对整体的源图像和目标图像来
说,他们划分出网格之后,应该是同构的。)
因此将源图和目标图中需要建立网格的同构点存到两个文本中,再将所需要建立的图片的三角形网格对应的坐标位
置存储在另一个文本中:
//读入源图中面部特征点
ifstream filePoint;
filePoint.open("source.txt");
string s;
int x = 0, y = 0;
while (getline(filePoint, s)) {
stringstream ss(s);
ss >> x >> y;
point p(x, y);
source_point.push_back(p);
}
filePoint.close();
//读入目标图中面部特征点
filePoint.open("target.txt");
while (getline(filePoint, s)) {
stringstream ss(s);
ss >> x >> y;
point p(x, y);
target_point.push_back(p);
}
filePoint.close();
//读入需要建立的仿射变换网格点
filePoint.open("grid.txt");
int p1 = 0, p2 = 0, p3 = 0;
while (getline(filePoint, s)) {
vector<int> p;
stringstream ss(s);
ss >> p1 >> p2 >> p3;
p.push_back(p1);
p.push_back(p2);
p.push_back(p3);
triangle_grid.push_back(p);
}
2)通过源三角形和目标三角形的顶点坐标值,使用仿射变换求出变换从源三角形到目标三角形的变换矩阵T。
filePoint.close();
//获取中间每一帧图片的三角形网格
void ImageMorphing::get_middleGrid() {
//存储每一帧中间图的点
vector <vector<point>> mid_point;
int i = 0, j = 0;
for (i = 0; i < frame; ++i) {
vector<point> temp;
for (j = 0; j < source_point.size(); ++j) {
int x = float(source_point[j].x) + float(float(i + 1) / (frame + 1)) *
float(target_point[j].x - source_point[j].x);
int y = float(source_point[j].y) + float(float(i + 1) / (frame + 1)) *
float(target_point[j].y - source_point[j].y);
point p(x, y);
temp.push_back(p);
}
mid_point.push_back(temp);
}
//获取中间每一帧的三角形网格
for (i = 0; i < frame; ++i) {
vector<triangle> temp;
for (j = 0; j < triangle_grid.size(); ++j) {
triangle t(mid_point[i][triangle_grid[j][0]], mid_point[i][triangle_grid[j][1]],
mid_point[i][triangle_grid[j][2]]);
temp.push_back(t);
}
mid_triangle.push_back(temp);
}
}
void ImageMorphing::AffineTransform() {
//获取每一帧图与源图网格的变换矩阵
int i = 0, j = 0, k = 0;
for (i = 0; i < frame; ++i) {
vector<CImg<float>> temp;
for (j = 0; j < triangle_grid.size(); ++j) {
triangle src = mid_triangle[i][j];
triangle dst = source_triangle[j];
CImg<float> A(3, 3, 1, 1, 1);
CImg<float> y1(1, 3, 1, 1, 0), y2(1, 3, 1, 1, 0);
CImg<float> c1(1, 3, 1, 1, 0), c2(1, 3, 1, 1, 0);
A(0, 0) = src.a.x; A(1, 0) = src.a.y;
A(0, 1) = src.b.x; A(1, 1) = src.b.y;
A(0, 2) = src.c.x; A(1, 2) = src.c.y;
y1(0, 0) = dst.a.x; y2(0, 0) = dst.a.y;
y1(0, 1) = dst.b.x; y2(0, 1) = dst.b.y;
y1(0, 2) = dst.c.x; y2(0, 2) = dst.c.y;
c1 = y1.solve(A);
c2 = y2.solve(A);
2. 中间帧生成
对其中一个三角形对来说,中间帧的生成过程是这样的:
1)通过变换矩阵T,求得三角形对的对应像素点坐标。
2)定位源三角形内部像素点P0的RGB值,经过线型插值运算:Pinternal=(1-1/n)P0+(1/n)P1(Pinternal是中间帧
像素点RGB值,P1是目标像素点RGB值,n为变形动画的帧数)获得中间帧中点Pinternal的RGB值。
CImg<float> transform(3, 3, 1, 1, 0);
for (k = 0; k < 3; ++k) {
transform(k, 0) = c1(0, k);
transform(k, 1) = c2(0, k);
}
transform(2, 2) = 1;
temp.push_back(transform);
}
source_matrix.push_back(temp);
//temp.clear();
}
//获取每一帧图与目标图网格的变换矩阵
for (i = 0; i < frame; ++i) {
vector<CImg<float>> temp;
for (j = 0; j < triangle_grid.size(); ++j) {
triangle src = mid_triangle[i][j];
triangle dst = target_triangle[j];
CImg<float> A(3, 3, 1, 1, 1);
CImg<float> y1(1, 3, 1, 1, 0), y2(1, 3, 1, 1, 0);
CImg<float> c1(1, 3, 1, 1, 0), c2(1, 3, 1, 1, 0);
A(0, 0) = src.a.x; A(1, 0) = src.a.y;
A(0, 1) = src.b.x; A(1, 1) = src.b.y;
A(0, 2) = src.c.x; A(1, 2) = src.c.y;
y1(0, 0) = dst.a.x; y2(0, 0) = dst.a.y;
y1(0, 1) = dst.b.x; y2(0, 1) = dst.b.y;
y1(0, 2) = dst.c.x; y2(0, 2) = dst.c.y;
c1 = y1.solve(A);
c2 = y2.solve(A);
CImg<float> transform(3, 3, 1, 1, 0);
for (k = 0; k < 3; ++k) {
transform(k, 0) = c1(0, k);
transform(k, 1) = c2(0, k);
}
transform(2, 2) = 1;
temp.push_back(transform);
}
target_matrix.push_back(temp);
//temp.clear();
}
}
通过以上方法,求得其余三角形的中间帧点Pinternal的RGB值,并将他们写入中间帧缓存中,最终生成中间帧图
像。
//对图片进行变换处理
void ImageMorphing::Morphing_process() {
int i = 0, j = 0;
result.push_back(source);
for (i = 0; i < frame; ++i) {
float k = float(i + 1) / (frame + 1);
CImg<float> middle(target.width(), target.height(), 1,3,0);
cimg_forXY(middle, x, y) {
for (j = 0; j < mid_triangle[0].size(); ++j) {
point p(x, y);
if (IsTriangle(p, mid_triangle[i][j])) {
CImg<float> x0(1, 3, 1, 1, 1);
CImg<int> b1(1, 3, 1, 1, 1), b2(1, 3, 1, 1, 1);
x0(0, 0) = x;
x0(0, 1) = y;
CImg<float> A1 = source_matrix[i][j];
CImg<float> A2 = target_matrix[i][j];
b1 = A1 * x0;
b2 = A2 * x0;
middle(x, y, 0) = (1 - k) * source(b1(0, 0), b1(0, 1), 0) + k * target(b2(0,
0), b2(0, 1), 0);
middle(x, y, 1) = (1 - k) * source(b1(0, 0), b1(0, 1), 1) + k * target(b2(0,
0), b2(0, 1), 1);
middle(x, y, 2) = (1 - k) * source(b1(0, 0), b1(0, 1), 2) + k * target(b2(0,
0), b2(0, 1), 2);
break;
}
}
}
result.push_back(middle);
}
result.push_back(target);
//保存结果的gif动图
result.save_gif_external("a.gif");
//存储每一帧图片
for (i = 0; i < result.size(); i++) {
string s = to_string(i + 1);
s += ".bmp";
result[i].save_bmp(s.c_str());
}
}
//判断点是否在该三角形网格内
//若点p在ABC组成的三角形内,则p = A + u * (C – A) + v * (B - A)
//u >= 0 v >= 0 u + v <= 1
bool IsTriangle(point p, triangle t) {
float x0 = t.c.x - t.a.x, y0 = t.c.y - t.a.y;
float x1 = t.b.x - t.a.x, y1 = t.b.y - t.a.y;
float x2 = p.x - t.a.x, y2 = p.y - t.a.y;
剩余16页未读,继续阅读
maXZero
- 粉丝: 26
- 资源: 303
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0