kaf*_*hau 13 c c++ image image-scaling
缩放2D图像阵列的最佳方法是什么?例如,假设我有一个1024 x 2048字节的图像,每个字节都是一个像素.每个像素都是从0到255的灰度级.我希望能够通过任意因子缩放此图像并获得新图像.因此,如果我将图像缩放0.68倍,我应该得到一个大小为0.68*1024 x 0.68*2048的新图像.一些像素将相互折叠.并且,如果我按比例缩放3.15,我会得到一个更大的图像,像素被复制.那么,实现这一目标的最佳方法是什么?
接下来,我希望能够将图像旋转任意角度,范围为0到360度(0 - 2Pi).旋转后裁剪图像不是问题.最好的方法是什么?
Ski*_*izz 13
有许多方法可以缩放和旋转图像.最简单的扩展方法是:
dest[dx,dy] = src[dx*src_width/dest_width,dy*src_height/dest_height]
Run Code Online (Sandbox Code Playgroud)
但是当减小尺寸时增加尺寸和丢失细节会产生块效应.有一些方法可以产生更好看的结果,例如,双线性滤波.
对于旋转,可以使用旋转矩阵计算src像素位置:
sx,sy = M(dx,dy)
Run Code Online (Sandbox Code Playgroud)
其中M是将目标像素映射到源图像的矩阵.同样,您需要进行插值以产生非块状结果.
但是如果你不想进入图像处理的数学,那么有很多库可用.
Mar*_*som 10
您正在做的是将一组输入点映射到一组输出点.问题的第一部分是确定调整大小或旋转的映射; 第二部分是处理不完全位于像素边界上的点.
调整大小的映射很容易:
x' = x * (width' / width)
y' = y * (height' / height)
Run Code Online (Sandbox Code Playgroud)
轮换映射只是稍微困难一点.
x' = x * cos(a) + y * sin(a)
y' = y * cos(a) - x * sin(a)
Run Code Online (Sandbox Code Playgroud)
用于确定位于网格之外的像素值的技术称为插值.有许多这样的算法,范围广泛,速度和最终图像质量.其中一些质量/时间递增的顺序是最近邻,双线性,双三次和Sinc滤波器.
复制或丢弃像素并不是调整图像大小的最佳方法,因为结果会显示像素化和锯齿状。为了获得最佳结果,您应该对图像重新采样,这将使生成的图像看起来更加平滑。重采样的方法有很多,比如双线性、双三次、lanczos 等。
看一下wxWidgets 中的ResampleBicubic函数。它适用于所有类型的图像,不仅是灰度图像,而且您应该能够根据您的需求进行调整。然后还有来自 VirtualDub 的重采样代码。Google Codesearch 可能会透露更多相关代码。
编辑:链接在预览中看起来很好,但在发布时被破坏。这很奇怪。去google codesearch,分别查询“wxwidgets resamplebicubic”和“virtualdub resample”,得到相同的结果。
归档时间: |
|
查看次数: |
64209 次 |
最近记录: |