用C++实现图像旋转变换

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

用C++实现图像旋转变换

(代码较长,

本人使用C++实现了一个类似GDI+ Matrix的C++几何变换类TransformMatrix。

略,参见我的BLOG文章《实现完整的图像平面几何变换》)。

我所说的“实现完整的图像平面几何变换”,是指可以通过TransformMatrix::Multiply函数或者更直接的变换矩阵成员设置去实现“完整的”图像

几何变换,除非其不能使用平面几何变换矩阵进行描述(如梯形变换我就没想到怎么实现,

也许其超出了平面几何变换矩阵范畴?),或者不能进行实际的几何变换(不可逆);“实现

完整的图像几何变换”的另一层含义是下面的图像变换执行函数可实现TransformMatrix

所能表示的任意图像几何变换,而不必去写一个个具体的,如缩放、旋转变换函数等。

C/C++ code

// 获取子图数据

BOOL GetSubBitmapData(CONST BitmapData *data, INT x, INT y, INT width, INT height, BitmapDa {

if (x < 0)

{

width += x;

x = 0;

}

if (x + width > (INT)data->Width)

width = (INT)data->Width - x;

if (width <= 0) return FALSE;

if (y < 0)

{

height += y;

y = 0;

}

if (y + height > (INT)data->Height)

height = (INT)data->Height - y;

if (height <= 0) return FALSE;

sub->Width = width;

sub->Height = height;

sub->Stride = data->Stride;

sub->Scan0 = (CHAR*)data->Scan0 + y * data->Stride + (x << 2);

return TRUE;

}

// 执行图像数据几何变换

VOID Transform(BitmapData *dest, INT x, INT y, CONST BitmapData *source, TransformMatrix *m {

// 复制几何变换矩阵对象

TransformMatrix m(matrix);

// 几何变换矩阵绝对增加平移量x, y

m.GetElements().dx += x;

m.GetElements().dy += y;

// 按几何变换矩阵计算并获取目标图像数据子数据

float fx, fy, fwidth, fheight;

m.GetTransformSize(source->Width, source->Height, fx, fy, fwidth, fheight);

BitmapData dst;

if (!GetSubBitmapData(dest, (INT)fx, (INT)fy,

(INT)(fwidth + 0.999999f), (INT)(fheight + 0.999999f), &dst))

return;

// 获取几何变换逆矩阵

if (!m.Invert()) return;

// 如果子图数据与目标图像原点不一致,几何变换矩阵相对增加平移量fx, fy

if (fx > 0.0f || fy > 0.0f)

{

if (fx < 0.0f) fx = 0.0f;

else if (fy < 0.0f) fy = 0.0f;

m.Translate(fx, fy);

}

// 设置子图扫描线指针及行偏移宽度

UINT *pix = (UINT*)dst.Scan0;

INT dstOffset = (dst.Stride >> 2) - dst.Width;

// 几何变换逆矩阵的平移量为与子图原点对应的源图起始坐标点

MatrixElements e = m.GetElements();

float xs = e.dx;

float ys = e.dy;

// 逐点计算并复制源图几何变换后的数据到目标子图

for (y = 0; y < (INT)dst.Height; y ++, pix += dstOffset, xs += e.m21, ys += e.m22)

{

float xs0 = xs;

float ys0 = ys;

for (x = 0; x < (INT)dst.Width; x ++, pix ++, xs0 += e.m11, ys0 += e.m12)

{

INT x0 = xs0 < 0.0f? (INT)(xs0 - 0.5f) : (INT)(xs0 + 0.5f);

INT y0 = ys0 < 0.0f? (INT)(ys0 - 0.5f) : (INT)(ys0 + 0.5f);

if (y0 >= 0 && y0 < (INT)source->Height && x0 >= 0 && x0 < (INT)source->Width) *pix = *(UINT*)((CHAR*)source->Scan0 + y0 * source->Stride + (x0 << 2));

}

}

}

函数特点:

1、可以实现任意的图像几何变换(只要TransformMatrix能正确表达的,即变换矩阵

可逆);

2、采用了GDI+ 的BitmapData结构(转换为32位ARGB像素格式),而并非任何具体

相关文档
最新文档