5
$\begingroup$

I want to essentially take an image with $n \times n$ pixels and expand it into a sparse array, spacing out the pixels by a factor $2$ or $3$. Each pixel in the input image occupies one of the corners of a cell of $2 \times 2$ or $3 \times 3$ new pixels in the expanded image, with the other $n \times (n - 1)$ pixels (in each cell) set to $0$.

So, I want to create a padded array where:

If one line of data is

WXYZ

then the output should be

W0 X0 Y0 Z0  
00 00 00 00

I think Mathematica's SparseArray might be the way to go, but I'm not sure how to go about implementing this.

$\endgroup$

2 Answers 2

7
$\begingroup$

A straightforward way to tackle this problem is to use Upsample, a function designed to do exactly this kind of array manipulation. Suppose m is a 2 by 3 array. These can be spaced out by padding each entry with zeros in both the x- and y-directions.

m = RandomInteger[{0, 10}, {2, 3}];
ArrayPlot[Upsample[m, {3, 3}]]

enter image description here

The {3,3} parameter tells the function how much padding to do in each direction. Looking at the documentation for Upsample shows that there is a third parameter (the offset) that allows placement of the nonzero terms in any desired location. For instance, to {2,2} places it in the middle of each 3x3 block:

{ArrayPlot[m], ArrayPlot[Upsample[m, {3, 3}, {2, 2}]]}

enter image description here

$\endgroup$
1
  • $\begingroup$ Wow thanks. This gave me a factor of 25 speed boost. I was surprised that I couldn't locate something like Upsample. $\endgroup$
    – Abhi
    Nov 27, 2013 at 6:07
5
$\begingroup$
l = {{2, 3, 4}, {4, 5, 6}}; 
a = SparseArray[{i_, j_} /; (Mod[{i, j}, 3] == {1, 1}) :> 
                             l[[Sequence @@ (Quotient[{i, j}, 3] + 1)]], 3 Dimensions@l]
MatrixPlot /@ {l, a}

(*Or the same thing by using Replace[], without SparseArray[] *)

f[p_] := Replace[p, x_ -> Sequence @@ {x, 0, 0}]
MatrixPlot@Transpose@f@Transpose@f@l

enter image description here

Edit

Answering your comment "How should I modify the code to step through the positions in each cell and fill each of the 3x3 pixels i.e. rather than the 1,1 location"

l = {{2, 3, 4}, {4, 5, 6}};
a = SparseArray[{i_, j_} :> l[[Sequence @@ (1 + Quotient[{i, j} - 1, 3])]], 3 Dimensions@l]
MatrixPlot /@ {l, a}

enter image description here

$\endgroup$
5
  • $\begingroup$ Thanks that worked perfectly :). Question - How should I modify the code to step through the positions in each cell and fill each of the 3x3 pixels i.e. rather than the 1,1 location. $\endgroup$
    – Abhi
    Nov 26, 2013 at 4:46
  • $\begingroup$ @Abhi See edit, please $\endgroup$ Nov 26, 2013 at 4:59
  • $\begingroup$ Oops I meant in successive steps. So essentially creating a1, a2, ... a9 different matrices. And in each Matrix the value of the pixel will be in the following cell. Sorry for the confusion. $\endgroup$
    – Abhi
    Nov 26, 2013 at 5:16
  • $\begingroup$ @Abhi Have you tried writing it yourself? $\endgroup$ Nov 26, 2013 at 6:09
  • $\begingroup$ I've been fighting with it for the past hour :). I've only used Mathematica very sparingly and the symbolic scripting has me very confused. $\endgroup$
    – Abhi
    Nov 26, 2013 at 6:12

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .