Click here to Skip to main content
15,905,508 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
hi,
i have this code for image rotation

C++
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;

void main()
{
	int theta=90;
	int r0,c0;
	int r1,c1;
	int rows,cols;
	rows=500;
	cols=700;
	int ary[500][700];
	int tary[500][700];
	float rads=(theta*3.1419265)/180;
	r0=rows/2;
	c0=cols/2;
	
	for (int r=0;r<rows;r++)
	{
		for(int l=0;l<cols;l++)
		{
				
			r1=(int)(r0+((r-r0)*cos(rads))-((l-c0)*sin(rads)));
			c1=(int)(c0+((r-r0)*sin(rads))-((l-c0)*cos(rads)));
			
			tary[r1][c1]=ary[r][l];
			
		}
	}
}


it seem to work with small arrays
but when i try it with big arrays it is fail

can any one tell me why??
Posted

You are allocating your arrays on stack

C#
int ary[500][700];
int tary[500][700];


These are 350000x4=1400000 bytes each assuming that your ints are 32-bit.
This type of storage is way too large to allocate on stack.

Move them outside your function body:

C#
int ary[500][700];
int tary[500][700];

void main()
{
}


This will tell the compiler/linker to allocate them statically. It will work.
 
Share this answer
 
In addition to the issues mentioned in Solutions 1 (allocating on stack) and 2 (impossible rotation of landscape format resulting in another landscape format image), the constant PI you have used is wrong: it is 3.1415926, not 3.1419265 (although you may not be able to notice a difference in the resulting images ;)

Additionally, you should be doing calculations based on floats wherever possible, or you'll accumulate rounding errors. This may result in odd artefacts if you rotate by arbitrary angles (see below).

Your code appears to be aimed at rotating an image by arbitrary angles. If that is your goal, you'll have to reverse the logic: rather than taking the original pixels and rotating them into the new position (which may be outside the frame of the new image), you should iterate over the pixels of the target image and figure out which pixel of the original image - if any - would be rotated into this position. In many cases you'll find that a given pixel has no origin in the original image, thus you need to assign some background color to those pixels. E. g. in your example, this is true for all pixels in columns 0 to 99 and 600 to 699. In case of an arbitrary angle rotation, it takes a bit more computation.

Reversing the logic thankfully isn't so hard in case of a rotation: you'll just have to negate the rotation angle. Of course, you have to calculate the rotation correctly (one of the signs in your calculation is off).

C++
int width = 700; // using 'constant' rather than literals within the code
int height = 500;
int background = 0; // this is the background color - use a suitable value here

float rads = theta*3.1415926/180.0; // fixed constant PI
float cs = cos(-rads); // precalculate these values
float ss = sin(-rads);
float xcenter = (float)(width)/2.0;   // use float here!
float ycenter = (float)(height)/2.0;
for (int r = 0; r < height; ++r) {
   for (int c = 0; c < width; ++c) {
      // now find the pixel of the original image that is rotated to (r,c)
      // rotation formula assumes that origin = top-left and y points down
      int rorig = ycenter + ((float)(r)-ycenter)*cs - ((float)(c)-xcenter)*ss;
      int corig = xcenter + ((float)(r)-ycenter)*ss + ((float)(c)-xcenter)*cs;
      // now get the pixel value if you can
      int pixel = background; // in case there is no original pixel
      if (rorig >= 0 && rorig < height && corig >= 0 && corig < width) {
         pixel = ary[rorig][corig];
      }
      tary[r][c] = pixel;
   }
}
 
Share this answer
 
There are two problems with your code. One is that you try to allocate the arrays from the stack, which might cause trouble if your stack is not large enough for such huge amounts of data.

The second problem is that your target array has the same dimensions as your source array. When you rotate an image of 700x500, the result will be an image of size 500x700. Already in the first iteration of your loop you are trying to map pixel (0,0) to (100,600) (equiv. to tary [600,100] which is outside the boundaries of this array. So either you must rotate the dimensions of your target array as well, or do some bounds checking.

By the way, I would take the sin and cos computations outside the loop, as they are constant and not every compiler might be smart enough to detect this.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900