今天有幸看到任意四点变形的讨论,有趣!

大可山人
博客专家认证
2005-10-10 09:49:23
http://61.186.252.131/expert/topic/886/886049.xml?temp=.9779779
我相信我的问题可以解决了,http://www.sz-qb.com/ttmmpp/t.htm
可惜我的数学太菜,哪位可给出实现的源代码,100分相送。
...全文
200 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
大可山人 2005-10-14
  • 打赏
  • 举报
回复
楼上兄弟有MSN吗?我们没有办法上QQ。
我的MSN:a3news#hotmail.com
HUNTON 2005-10-14
  • 打赏
  • 举报
回复
HUNTON_2002@hotmail.com
HUNTON 2005-10-13
  • 打赏
  • 举报
回复
四点到四点的变换很早就讨论过了就是算一个8阶矩阵的逆。都是一些矩阵不好输入,要知道详细,跟我联系吧。QQ:67607325
zzwu 2005-10-11
  • 打赏
  • 举报
回复
我已在复你的短信中说了:所用的数学变换是一致的,但图像->图像的变换不是单个点->点的变换.
大可山人 2005-10-11
  • 打赏
  • 举报
回复
这里有一段C++进行透视变换的代码,但是它是使用XYZ坐标变换的方式,很不简洁。(出于黑魔方丛书《C++实用图像处理》书)

List 10.7 透视变换(双线性内插法)

#include "StdAfx.h"
#include "BaseList.h"
#include <math.h>

void param_pers(int xsize, int ysize, float k[9], float a, float b, float x0,
float y0, float z0, float z, float x, float y, float t, float s);
void matrix(double l[4][4], double m[4][4], double n[4][4]);

/*--- Perspective --- 透视变换(双线性内插法)--------------------------------------
image_in: 输入图像数据指针
image_out: 输出图像数据指针
xsize: 图像宽度
ysize: 图像高度
ax: 放大率(横向)
ay: 放大率(纵向)
px: 移动量(x)
py: 移动量(y)
pz: 移动量(z)
rz: 回转角(z轴)
rx: 回转角(x轴)
ry: 回转角(y轴)
v: 视点位置(z)
s: 屏幕位置(z)
-----------------------------------------------------------------------------*/
void Perspective(BYTE *image_in, BYTE *image_out, int xsize, int ysize, float ax, float ay,
float px, float py, float pz, float rz,
float rx, float ry, float v, float s)
{
int i, j, m, n;
float x, y, w, p, q;
float k[9];
int xs = xsize/2;
int ys = ysize/2;
int d;

param_pers(xsize, ysize,k,ax,ay,px,py,pz,rz,rx,ry,v,s); //计算变换参数
for (i = -ys; i < ys; i++) {
for (j = -xs; j < xs; j++) {
w = k[0]*j + k[1]*i + k[2];
x = k[3]*j + k[4]*i + k[5];
y = k[6]*j + k[7]*i + k[8];
x = x/w;
y = y/w;
if (y > 0) m = (int)y;
else m = (int)(y-1);
if (x > 0) n = (int)x;
else n = (int)(x-1);
q = y - m;
p = x - n;
if ( (m >= -ys) && (m < ys) && (n >= -xs) && (n < xs) )
d = (int)((1.0-q)*((1.0-p)*(*(image_in + (m +ys)*xsize + n + xs))
+ p*(*(image_in + (m +ys)*xsize + n+1+xs)))
+ q*((1.0-p)*(*(image_in + (m+1+ys)*xsize + n +xs))
+ p*(*(image_in + (m+1+ys)*xsize + n+1+xs))));
else
d = 0;
if (d < 0) d = 0;
if (d > 255) d = 255;
*(image_out + (i+ys)*xsize + j+xs) = d;
}
}
}

/*--- param_pers --- 计算透视变换的参数 ---------------------------------
xsize: 图像宽度
ysize: 图像高度
k: 变换参数
a: 放大率(x方向)
b: 放大率(y方向)
x0: 移动量(x方向)
y0: 移动量(y方向)
z0: 移动量(z方向)
z: 回转角(z方向 度)
x: 回转角(x方向 度)
y: 回转角(y方向 度)
v: 视点位置(z)
s: 屏幕位置(z)

-----------------------------------------------------------------------------*/
void param_pers(int xsize, int ysize, float k[9], float a, float b, float x0,
float y0, float z0, float z, float x, float y, float t, float s)
{
double l[4][4],m[4][4],n[4][4];
float k1,k2,k3,k4,k5,k6,k7,k8,k9;
double u,v,w;
int xs = xsize/2;
int ys = ysize/2;

u=x*PI/180.0; v=y*PI/180.0; w=z*PI/180.0;
l[0][0]= 1.0/xs; l[0][1]= 0; l[0][2]= 0; l[0][3]= 0;
l[1][0]= 0; l[1][1]= -1.0/xs; l[1][2]= 0; l[1][3]= 0;
l[2][0]= 0; l[2][1]= 0; l[2][2]= 1; l[2][3]= 0;
l[3][0]= 0; l[3][1]= 0; l[3][2]= 0; l[3][3]= 1;
m[0][0]= a; m[0][1]= 0; m[0][2]= 0; m[0][3]= 0;
m[1][0]= 0; m[1][1]= b; m[1][2]= 0; m[1][3]= 0;
m[2][0]= 0; m[2][1]= 0; m[2][2]= 1; m[2][3]= 0;
m[3][0]= 0; m[3][1]= 0; m[3][2]= 0; m[3][3]= 1;
matrix(l,m,n); //正规化矩阵 乘 放大缩小矩阵
l[0][0]= 1; l[0][1]= 0; l[0][2]= 0; l[0][3]= 0;
l[1][0]= 0; l[1][1]= 1; l[1][2]= 0; l[1][3]= 0;
l[2][0]= 0; l[2][1]= 0; l[2][2]= 1; l[2][3]= 0;
l[3][0]= x0; l[3][1]= y0; l[3][2]= z0; l[3][3]= 1;
matrix(n,l,m); //乘 移动矩阵
n[0][0]= cos(w); n[0][1]= sin(w); n[0][2]= 0; n[0][3]= 0;
n[1][0]= -sin(w); n[1][1]= cos(w); n[1][2]= 0; n[1][3]= 0;
n[2][0]= 0; n[2][1]= 0; n[2][2]= 1; n[2][3]= 0;
n[3][0]= 0; n[3][1]= 0; n[3][2]= 0; n[3][3]= 1;
matrix(m,n,l); // 乘 z轴旋转矩阵
m[0][0]= 1; m[0][1]= 0; m[0][2]= 0; m[0][3]= 0;
m[1][0]= 0; m[1][1]= cos(u); m[1][2]= sin(u); m[1][3]= 0;
m[2][0]= 0; m[2][1]= -sin(u); m[2][2]= cos(u); m[2][3]= 0;
m[3][0]= 0; m[3][1]= 0; m[3][2]= 0; m[3][3]= 1;
matrix(l,m,n); // 乘 x轴旋转矩阵
l[0][0]= cos(v); l[0][1]= 0; l[0][2]= sin(v); l[0][3]= 0;
l[1][0]= 0; l[1][1]= 1; l[1][2]= 0; l[1][3]= 0;
l[2][0]= -sin(v); l[2][1]= 0; l[2][2]= cos(v); l[2][3]= 0;
l[3][0]= 0; l[3][1]= 0; l[3][2]= 0; l[3][3]= 1;
matrix(n,l,m); //乘 y轴旋转矩阵
n[0][0]= 1; n[0][1]= 0; n[0][2]= 0; n[0][3]= 0;
n[1][0]= 0; n[1][1]= 1; n[1][2]= 0; n[1][3]= 0;
n[2][0]= 0; n[2][1]= 0; n[2][2]= -1; n[2][3]= 0;
n[3][0]= 0; n[3][1]= 0; n[3][2]= t; n[3][3]= 1;
matrix(m,n,l); // 乘 视点坐标变换矩阵
m[0][0]= 1; m[0][1]= 0; m[0][2]= 0; m[0][3]= 0;
m[1][0]= 0; m[1][1]= 1; m[1][2]= 0; m[1][3]= 0;
m[2][0]= 0; m[2][1]= 0; m[2][2]= 1/s; m[2][3]= 1/s;
m[3][0]= 0; m[3][1]= 0; m[3][2]= -1; m[3][3]= 0;
matrix(l,m,n); // 乘 透视变换矩阵
l[0][0]= xs; l[0][1]= 0; l[0][2]= 0; l[0][3]= 0;
l[1][0]= 0; l[1][1]= -xs; l[1][2]= 0; l[1][3]= 0;
l[2][0]= 0; l[2][1]= 0; l[2][2]= 1; l[2][3]= 0;
l[3][0]= 0; l[3][1]= 0; l[3][2]= 0; l[3][3]= 1;
matrix(n,l,m); // 乘 正规化逆矩阵
k1=(float)(m[0][3]); k2=(float)(m[1][3]); k3=(float)(m[3][3]);
k4=(float)(m[0][0]); k5=(float)(m[1][0]); k6=(float)(m[3][0]);
k7=(float)(m[0][1]); k8=(float)(m[1][1]); k9=(float)(m[3][1]);
k[0]=k7*k2-k8*k1; k[1]=k5*k1-k4*k2; k[2]=k4*k8-k7*k5;
k[3]=k8*k3-k9*k2; k[6]=k9*k1-k7*k3; k[4]=k6*k2-k5*k3;
k[7]=k4*k3-k6*k1; k[5]=k5*k9-k8*k6; k[8]=k7*k6-k4*k9;
}

/*--- matrix --- 矩阵计算 ---------------------------------------------
l: 输入矩阵1
m: 输入矩阵2
n: 输出矩阵
-----------------------------------------------------------------------------*/
void matrix(double l[4][4], double m[4][4], double n[4][4])
{
int i, j, k;
double p;

for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
p = 0;
for (k = 0; k < 4; k++) p = p + l[i][k]*m[k][j];
n[i][j] = p;
}
}
}
寻开心 2005-10-10
  • 打赏
  • 举报
回复
三点变形: 仿射坐标变换即可
凸四点变形:双线性插值
凹四点变形:拆成两个三点变换吧
大可山人 2005-10-10
  • 打赏
  • 举报
回复
zzwu(未名) :Why?
zzwu 2005-10-10
  • 打赏
  • 举报
回复
2个问题确实有关.
但仅仅利用解决 http://61.186.252.131/expert/topic/886/886049.xml?temp=.9779779
问题的源码,无法用来解决http://www.sz-qb.com/ttmmpp/t.htm问题.

4,445

社区成员

发帖
与我相关
我的任务
社区描述
图形图像/机器视觉
社区管理员
  • 机器视觉
  • 迪菲赫尔曼
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧