Peter Jackson
Peter Jackson

Reputation: 1

EmguCV Rotation Algorithm not working

I want to rotate an image using OpenCV/EmguCV. I've found a rotation algorithm that I want to implement, but the outcome is not quite as I want it to be. Maybe someone can have a look.

My Code:

static void Main(string[] args)
    {
        Mat image = CvInvoke.Imread("C:\\Users\\Leon\\Downloads\\a.jpg", LoadImageType.Grayscale);

        int height = image.Height;
        int width = image.Width;

        //Convert to Matrix
        Matrix<Byte> matrix = new Matrix<Byte>(image.Rows, image.Cols, image.NumberOfChannels);
        image.CopyTo(matrix);

        Matrix<Byte> newMatrix = new Matrix<Byte>(image.Rows, image.Cols, image.NumberOfChannels);
        image.CopyTo(newMatrix);

        for (int i = 0; i < matrix.Rows - 1; i++)
        {
            for (int j = 0; j < matrix.Cols - 1; j++)
            {
                newMatrix.Data[i, j] = matrix.Data[(byte)(i * Math.Cos(3) - j * Math.Sin(3)), (byte)(i * Math.Sin(3) + j * Math.Cos(3))];
            }
        }

        CvInvoke.Imshow("abc", newMatrix);
        CvInvoke.WaitKey(0);

    }
}

Original Picture:

Vladimir Putin

My Outcome:

incorrectly rotated

If someone can point out what I'm doing wrong, I'd be very thankful! :)

Upvotes: 0

Views: 684

Answers (1)

MBo
MBo

Reputation: 80287

Pattern with square length 256 says that some coordinate overflow exists.

Look at the casting to byte here:

 matrix.Data[(byte)(i * Math.Cos(3) - j * Math.Sin(3)), (byte)(i * Math.Sin(3) + j * Math.Cos(3))];

Seems you need to round float values to int, then check - if it lies in range 0..width-1 or 0..height-1 for x and y.

possible pseudocode:

cs = Math.Cos(angle); //calculate them once before cycle
sn = Math.Sin(angle);
...
x = (int) (i * cs - j * sn);
y = (int) (i * sn + j * cs);
if (x>=0)&&(x<width)&&(y>=0)&&(y<height)
   {copy byte to new picture}

Aside question: what is 3 argument of Sin and Cos?

Upvotes: 1

Related Questions