【问题标题】:Rotated picture looks like it's missing pixels旋转后的图片看起来缺少像素
【发布时间】:2014-02-08 05:12:01
【问题描述】:

我正在使用 PIL 和转换矩阵来了解简单的 2D 图像处理背后的原理。

在我尝试尽可能“低级”旋转图像(即不使用任何rotate(degrees) 函数,而是进行数学运算)时,我决定使用顺时针旋转矩阵旋转图像的每个像素:

旋转正常,但图像现在看起来缺少一些像素。

原始图像,绘制在 435x353 黑色背景上:

顺时针旋转 45° 并向右移动 300 像素:

奇怪的是,将图片顺时针旋转 90°(并向右移动 400 像素)时不会出现此问题:

这可能是什么原因造成的?使用Image.Image.rotate 工作得很好,所以我想问题出在我的代码上。值得一提的是,原图是透明背景,上传到这里时压缩丢失了。但是,我对 jpeg(非透明)图像做了完全相同的操作,结果是一样的。

用于进行旋转的代码:

import Image, ImageDraw
from scipy import misc
import math

WHITE = (255,255,255)
BLACK = (0,0,0)
W, H = 435, 353
im = Image.new('RGBA', (W, H), BLACK)
draw = ImageDraw.Draw(im)
bitmap = misc.imread('Image.png')

def affine_t(x, y, a, b, c, d, e, f):
    """Returns ((a, b), (c, d))*((x), (y)) + ((e), (f)).""" 
    return a*x + b*y + e, c*x + d*y + f

def crotate(x, y, r):
    """Rotate (x, y) clockwise by r radians."""
    # And move 300 px to the right for this example
    return affine_t(
        x, y, math.cos(-r), math.sin(-r), -math.sin(-r), math.cos(-r), 300, 0
    )

x, y = 0, 0
angle = math.pi/4
for row in bitmap:
    for pt in row:
        draw.point([crotate(x, y, angle),],fill=tuple(pt))
        x+= 1
    x = 0
    y += 1

im.save('out.png')

【问题讨论】:

标签: python image image-processing matrix python-imaging-library


【解决方案1】:

对于每个目标像素,您需要计算源像素,反之则不然。由于四舍五入,您有多个源像素映射到同一个目标像素。这就是为什么如果没有插值,您实际上无法获得良好的 45° 旋转。我的建议实际上是最近邻插值。

【讨论】:

  • Bilinear interpolation 在每个逆变换的目标像素的对应源像素之间会比简单地使用最近的邻居提供更好的结果。这在image scaling 上的维基百科文章中有说明。
  • RotSprite 算法更适合旋转和缩放。
  • RotSprite 看起来非常优雅和高效,感谢您的链接。
  • 我可以推荐 George Wolberg 的书 Digital Image Warping,以了解有关该主题的更多信息。 www-cs.ccny.cuny.edu/~wolberg/diw.html
  • 是的,只要目标图像的每个像素都是源图像的某个像素,实际上就不会进行插值,这称为“最近邻”。当你插入一些东西时,你实际上可以获得原始图像上没有的颜色。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多