scipy.ndimage.interpolate.affine_transform fails
<p>This code:</p>

<pre><code>from scipy.ndimage.interpolation import affine_transform
import numpy as np
...
nzoom = 1.2
newimage = affine_transform(self.image, matrix=np.array([[nzoom, 0],[0, nzoom]]))
</code></pre>

<p>fails with:</p>

<pre><code>RuntimeError: affine matrix has wrong number of rows
</code></pre>

<p>What's the problem with the matrix? I also tried <code>matrix=[nzoom, nzoom]</code>, which according to my reading of documentation should do the same, and it fails the same way.</p>

<p>The reason why the original code does not work with a 2x2 matrix is because the image in question is 3-dimensional. Mind you, the 3rd dimension is<code>[R,G,B]</code>, but <code>scipy.ndimage</code> does not know about non-spatial dimensions; it treats all dimensions as spatial. The examples using 2x2 matrices were all 2D "gray" images.</p>

<p><strong>Solution #1:</strong></p>

<p><code>affine_transform</code> maps output coordinates <code>o</code> to source (input) coordinates <code>s</code> as:</p>

<pre><code>s = numpy.dot(matrix,o) + offset
</code></pre>

<p>where <code>matrix</code> and <code>offset</code> are arguments to <code>affine_transform</code>. In the case of a multichannel image we don't want to transform the 3rd dimension. I.e., we want the source coordinates corresponding to an output point </p>

<pre><code>o == [x, y, z]  # column vector
</code></pre>

<p>to be</p>

<pre><code>s == [c00*x + c01*y + dx, c10*x + c11*y + dy, z]  # column vector
</code></pre>

<p>To achieve that result we need</p>

<pre><code>matrix = [[ c00, c01,  0],
          [ c10, c11,  0],
          [   0,   0,  1]]

offset = [dx, dy, 0]  # column vector
</code></pre>

<p><strong>Solution #2:</strong></p>

<p>An alternative solution is to split the RGB image in 3 channels, transform each channel separately, and combine them together,</p>

<pre><code>r = rgb[..., 0]
g = rgb[..., 1]
b = rgb[..., 2]
matrix = np.array([[c00, c01], [c10, c11]])
offset = [dx dy]
r = affine_transform(r, matrix=matrix, offset=offset)
g = affine_transform(g, matrix=matrix, offset=offset)
b = affine_transform(b, matrix=matrix, offset=offset)
rgb = np.dstack((r, g, b))
</code></pre>

<p>I have not timed either solution, but I expect #2 to be slower that #1.</p>

python scipy affinetransform