回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>这是PIL中的一个基本转换问题。我至少试过几次
在过去的几年里,为了正确地执行这一点,似乎有
我不太了解PIL中的Image.transform。我想
在可以的地方实现相似性转换(或仿射转换)
清楚地说明图像的限制。为了确保我的方法有效,我
在Matlab中实现。</p>
<p>Matlab实现如下:</p>
<pre><code>im = imread('test.jpg');
y = size(im,1);
x = size(im,2);
angle = 45*3.14/180.0;
xextremes = [rot_x(angle,0,0),rot_x(angle,0,y-1),rot_x(angle,x-1,0),rot_x(angle,x-1,y-1)];
yextremes = [rot_y(angle,0,0),rot_y(angle,0,y-1),rot_y(angle,x-1,0),rot_y(angle,x-1,y-1)];
m = [cos(angle) sin(angle) -min(xextremes); -sin(angle) cos(angle) -min(yextremes); 0 0 1];
tform = maketform('affine',m')
round( [max(xextremes)-min(xextremes), max(yextremes)-min(yextremes)])
im = imtransform(im,tform,'bilinear','Size',round([max(xextremes)-min(xextremes), max(yextremes)-min(yextremes)]));
imwrite(im,'output.jpg');
function y = rot_x(angle,ptx,pty),
y = cos(angle)*ptx + sin(angle)*pty
function y = rot_y(angle,ptx,pty),
y = -sin(angle)*ptx + cos(angle)*pty
</code></pre>
<p>这和预期的一样。这是输入:</p>
<p><img src="https://i.stack.imgur.com/phudR.jpg" alt="enter image description here"/></p>
<p>这是输出:</p>
<p><img src="https://i.stack.imgur.com/5qEy8.jpg" alt="enter image description here"/></p>
<p>这是实现相同功能的Python/PIL代码
转换:</p>
<pre><code>import Image
import math
def rot_x(angle,ptx,pty):
return math.cos(angle)*ptx + math.sin(angle)*pty
def rot_y(angle,ptx,pty):
return -math.sin(angle)*ptx + math.cos(angle)*pty
angle = math.radians(45)
im = Image.open('test.jpg')
(x,y) = im.size
xextremes = [rot_x(angle,0,0),rot_x(angle,0,y-1),rot_x(angle,x-1,0),rot_x(angle,x-1,y-1)]
yextremes = [rot_y(angle,0,0),rot_y(angle,0,y-1),rot_y(angle,x-1,0),rot_y(angle,x-1,y-1)]
mnx = min(xextremes)
mxx = max(xextremes)
mny = min(yextremes)
mxy = max(yextremes)
im = im.transform((int(round(mxx-mnx)),int(round((mxy-mny)))),Image.AFFINE,(math.cos(angle),math.sin(angle),-mnx,-math.sin(angle),math.cos(angle),-mny),resample=Image.BILINEAR)
im.save('outputpython.jpg')
</code></pre>
<p>这是Python的输出:</p>
<p><img src="https://i.stack.imgur.com/KWl71.jpg" alt="enter image description here"/></p>
<p>这些年来,我在多个操作系统上尝试了几种版本的Python和PIL,结果基本上是一样的。</p>
<p>这是说明问题的最简单的可能情况,我知道如果这是我想要的旋转,我可以使用im.rotate调用进行旋转,但我也希望剪切和缩放,这只是说明问题的示例。我想得到所有仿射变换的相同输出。我希望能把事情做好。</p>
<p><strong>编辑:</strong></p>
<p>如果将转换线更改为:</p>
<pre><code>im = im.transform((int(round(mxx-mnx)),int(round((mxy-mny)))),Image.AFFINE,(math.cos(angle),math.sin(angle),0,-math.sin(angle),math.cos(angle),0),resample=Image.BILINEAR)
</code></pre>
<p>这是我得到的输出:</p>
<p><img src="https://i.stack.imgur.com/ucjma.jpg" alt="enter image description here"/></p>
<p><strong>编辑2</p>
<p>我旋转了-45度,将偏移量更改为-0.5*mnx和-0.5*mny,得到:</p>
<p><img src="https://i.stack.imgur.com/ynXT1.jpg" alt="enter image description here"/></p>