6

我正在做一个需要实施图像矫正的项目。我有一个想法来做这件事。我将 SeekBar 上的图像旋转为 -10 到 +10 度。当我旋转时,它是由白色背景可见的。因此,我们还需要实现缩放功能,使其看起来像图像拉直,如下所示。请根据您的建议提出建议。

在此处输入图像描述

在此处输入图像描述

示例代码

float a = (float) Math.atan(bmpHeight/bmpWidth);
// the length from the center to the corner of the green
float len1 = (float) ((bmpWidth/2)/Math.cos(a-Math.abs(curRotate)));
// the length from the center to the corner of the black (^ = power)
float len2 = (float) Math.sqrt((bmpWidth/2)^2 + (bmpHeight/2)^2);
// compute the scaling factor
curScale = len2 / len1;
Matrix matrix = new Matrix();
matrix.postScale(curScale, curScale);
Bitmap resizedBitmap = Bitmap.createBitmap(bitmaprotate, 0, 0, bmpWidth, bmpHeight, matrix, true);
mainImage.setImageBitmap(resizedBitmap);
4

2 回答 2

11

在下图中,绿色矩形是旋转图像的有效部分。我们需要确定的是使绿色区域与原始图像大小相同的比例因子。从图中我们可以看出,这个比例因子是 的len2比值len1

在此处输入图像描述

使用图表和一些基本的三角函数,我们可以找到len1len2。以下类似 c 的伪代码描述了该解决方案。

// theta  : the angle of rotation of the image
// width  : the width (number of columns) of the image
// height : the height (number of rows) of the image

a = atan(height/width);

// the length from the center to the corner of green region
len1 = (width/2)/cos(a-abs(theta));
// the length from the center to the corner of original image
len2 = sqrt(pow(width/2,2) + pow(height/2,2));
// compute the scaling factor
scale = len2 / len1;

就是这样。假设所有的变换都是相对于图像的中心完成的,那么scale在执行旋转之后只需按 的值缩放图像。

注意:提供的方程式假设height > width. 否则在等式中width替换为。heightlen1

更新:Amulya Khare 在这里发布了一个示例实现

于 2013-09-18T09:46:12.357 回答
3

基于来自jodag的解决方案,这里有一种计算 iOS / OS X 矫直的方法:

CG_INLINE CGAffineTransform CGAffineTransformMakeStraightening(CGSize size, CGFloat rotation)
{
    CGAffineTransform transform = CGAffineTransformIdentity;

    // Apply the rotation
    transform = CGAffineTransformRotate(transform, rotation);

    // theta  : the angle of rotation of the image
    // minSide: the min side of the size

    CGFloat a = atan(size.height/size.width);        
    CGFloat minSide = MIN(size.width, size.height);

    // the length from the center to the corner of the green
    CGFloat len1 = (minSide/2)/cos(a-fabs(rotation));

    // the length from the center to the corner of the black
    CGFloat len2 = sqrt(pow(size.width/2, 2) + pow(size.height/2, 2));

    // compute the scaling factor
    CGFloat scale = len2 / len1;

    // Apply the scale
    transform = CGAffineTransformScale(transform, scale, scale);

    return transform;
}
于 2015-06-17T13:48:02.717 回答