This answer is more explanatory than trying to be concise and efficient. I think gnovice's solution is best in that regard. In case you are trying to understand how it works, keep reading...
Now the problem with your code is that you are mapping locations from the input image to the output image, which is why you are getting the spotty output. Consider an example where input image is all white and output initialized to black, we get the following:
What you should be doing is the opposite (from output to input). To illustrate, consider the following notation:
1 c 1 scaleC*c
+-----------+ 1 +----------------------+ 1
| | | | | |
|----o | <=== | | |
| (ii,jj) | |--------o |
+-----------+ r | (i,j) |
inputImage | |
| |
+----------------------+ scaleR*r
ouputImage
Note: I am using matrix notation (row/col), so:
i ranges on [1,scaleR*r] , and j on [1,scaleC*c]
and ii on [1,r], jj on [1,c]
The idea is that for each location (i,j)
in the output image, we want to map it to the "nearest" location in the input image coordinates. Since this is a simple mapping we use the formula that maps a given x
to y
(given all the other params):
x-minX y-minY
--------- = ---------
maxX-minX maxY-minY
in our case, x
is the i
/j
coordinate and y
is the ii
/jj
coordinate. Therefore substituting for each gives us:
jj = (j-1)*(c-1)/(scaleC*c-1) + 1
ii = (i-1)*(r-1)/(scaleR*r-1) + 1
Putting pieces together, we get the following code:
% read a sample image
inputI = imread('coins.png');
[r,c] = size(inputI);
scale = [2 2]; % you could scale each dimension differently
outputI = zeros(scale(1)*r,scale(2)*c, class(inputI));
for i=1:scale(1)*r
for j=1:scale(2)*c
% map from output image location to input image location
ii = round( (i-1)*(r-1)/(scale(1)*r-1)+1 );
jj = round( (j-1)*(c-1)/(scale(2)*c-1)+1 );
% assign value
outputI(i,j) = inputI(ii,jj);
end
end
figure(1), imshow(inputI)
figure(2), imshow(outputI)