如何将一个矩形图像变形为一个梯形( 或者说是任意四边形)?有源代码的话最好。

xuxiake2012 2007-10-15 06:16:06
如何将一个矩形图像变形为一个梯形( 或者说是任意四边形)?有源代码的话最好。


...全文
2319 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
chengzhe 2007-10-28
  • 打赏
  • 举报
回复
呵呵 不错
xuxiake2012 2007-10-24
  • 打赏
  • 举报
回复
如何给分啊?
xuxiake2012 2007-10-17
  • 打赏
  • 举报
回复
谢谢1楼的大哥。

请问怎么给分啊?

另外能不能说一下是什么原理啊?
bs2x418 2007-10-17
  • 打赏
  • 举报
回复
MARK
jun_01 2007-10-17
  • 打赏
  • 举报
回复
try Win32 API:PlgBlt
laoma_hbu 2007-10-15
  • 打赏
  • 举报
回复
真是牛人呀!!!
上面的算法,太高深了,俺对楼主的问题也很感兴趣
我想问一下楼上大哥,其原理是:
得到四个对应点,然后用双线性方建立变换关系吗?
能不能简单给小弟介绍一个其原理呀?

tufaqing 2007-10-15
  • 打赏
  • 举报
回复
// 白像素
#define HIGH 255

// 黑像素
#define LOW 0

// π值
#define PI 3.14159265f

/*------matrix--------矩阵计算------------------------------
l: 输入矩阵1
m: 输入矩阵2
n: 输出矩阵
-----------------------------------------------------------*/
inline 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 += l[i][k] * m[k][j];
n[i][j] = p;
}
}
}

/*------param_pers-------计算透视变换的参数-----------------
xsize: 图像宽度
ysize: 图像高度
k: 变换参数
a: 放大率(x方向)
b: 放大率(y方向)
x0: 移动量(x方向)
y0: 移动量(y方向)
z0: 移动量(z方向)
x: 回转角(x方向)
y: 回转角(y方向)
z: 回转角(z方向)
t: 视点位置(z)
s: 屏幕位置(z)
-----------------------------------------------------------*/
inline void param_pers(int xsize, int ysize, float k[9], float a, float b, float x0, float y0, float z0, float x, float y, float z, 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);

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);

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);

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;
}

/*------Perspective-------透视变换(双线性内插法)----------
image_in: 输入图像数据指针
image_out: 输出图像数据指针
xsize: 图像宽度
ysize: 图像高度
ax: 放大率(x方向)
ay: 放大率(y方向)
px: 移动量(x方向)
py: 移动量(y方向)
pz: 移动量(z方向)
rx: 回转角(x方向)
ry: 回转角(y方向)
rz: 回转角(z方向)
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 rx, float ry, float rz, 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, rx, ry, rz, v, s);

for(j = -ys; j < ys; j++)
{
for(i = -xs; i < xs; i++)
{
w = k[0] * i + k[1] * j + k[2];
x = k[3] * i + k[4] * j + k[5];
y = k[6] * i + k[7] * j + 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(q >= 1)
{
q -= 1; m += 1;
}
if(p >= 1)
{
p -= 1; n += 1;
}

if(m >= -ys && m < ys - 1 && n >= -xs && n < xs - 1)
d = (int) ((1 - q) * ((1 - p) * *(image_in + (m + ys) * xsize + n + xs) +
p * *(image_in + (m + ys) * xsize + n + xs + 1)) +
q * ((1 - p) * *(image_in + (m + ys + 1) * xsize + n + xs) +
p * *(image_in + (m + ys + 1) * xsize + n + xs + 1)));
else
d = LOW;

if(d < LOW)
d = LOW;
else if(d > HIGH)
d = HIGH;

*(image_out + (j + ys) * xsize + i + xs) = d;
}
}
}

上面程序只对灰度图处理(一个象素占一个字节),没有考虑一行4字节对齐,LZ可以自行修改(彩色图可以根据d的求法同样求RGB)

19,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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