Image rotation algorithm and its implementation

Source: Internet
Author: User
Tags abs cos fread sin

Image rotation refers to the process of creating a new image by rotating a certain angle at a certain point. Of course this point is usually the center of the image. Since it is rotated by the center, there is a natural attribute: the position of the point away from the center is unchanged before and after the rotation.

According to this property, we can get the coordinates of the point after rotation and the corresponding relation of the original coordinates. Since the coordinates of the original image are the origin of the upper left corner, we first convert the coordinates to the center of the image as the Origin point. Assuming that the original image width is W, h, (X0,Y0) is a point within the original coordinates, the point after the transformation coordinates (X1,Y1). So it's not hard to get:

x1 = X0-W/2; Y1 =-y0 + h/2;

In the new coordinate system, the false point (x0,y0) distance from the origin is r, the line between the point and the origin is B, the angle of the x-axis is a, the rotation is a, and the point after rotation is (x1,y1), as shown.

Then there are the following conclusions:

X0=rcosb;y0=rsinb

X1 = RCOs (b-a) = Rcosbcosa+rsinbsina=x0cosa+y0sina;

Y1=rsin (b-a) =rsinbcosa-rcosbsina=-x0sina+y0cosa;

After the converted coordinates are obtained, we only need to convert these coordinates back to the original coordinate system. One more thing to note here is that the length and width of the rotated image change, so the length and width of the new image are calculated.

The following are the source programs:

1 #include "stdafx.h"
2 #include <stdio.h>
3 #include <string>
4 #include <math.h>
5 #include <windows.h>
6 using namespace Std;
7
8 #define PI 3.1415926535
9//Angle to Radian conversion
#define RADIAN (angle) ((angle) *pi/180.0)
11
void Rotation (const string& srcfile,const string& desfile,int angle)
13 {
Bitmapfileheader Bmfheader;
Bitmapinfoheader Bmiheader;
16
FILE *pfile;
if (PFile = fopen (Srcfile.c_str (), "rb") = = = NULL)
19 {
printf ("Open BMP File Error.");
Exit (-1);
22}
23//Read file and bitmap header information
Fseek (Pfile,0,seek_set);
Fread (&bmfheader,sizeof (Bitmapfileheader), 1,pfile);
Fread (&bmiheader,sizeof (Bitmapinfoheader), 1,pfile);
27//Not supported bitmaps less than 16 bits first
Bitcount int = Bmiheader.bibitcount;
if (Bitcount < 16)
30 {
To exit (-1);
32}
SRCW int = bmiheader.biwidth;
SrcH int = bmiheader.biheight;
35//The number of bytes removed from each line of the original image
linesize int = Bitcount * SRCW/8;
37//Offset, Windows system requires four-byte alignment per scan line
alignbytes int = ((Bmiheader.biwidth * bitcount +) & ~31)/8L
39-bmiheader.biwidth * BITCOUNT/8L;
40//Original image cache
srcbufsize int = linesize * SrcH;
byte* srcbuf = new Byte[srcbufsize];
I,j int;
44//Read data in file
(i = 0; i < SrcH; i++)
46 {
Fread (&srcbuf[linesize * i],linesize,1,pfile);
Fseek (pfile,alignbytes,seek_cur);
49}
50//With the center of the image as the origin of the upper left corner, the upper right corner, the lower left and lower right corner of the coordinates, used to calculate the rotated image width and height
Wuyi Point plt,prt,plb,prb;
Plt.x =-srcw/2;plt.y = SRCH/2;
Prt.x = Srcw/2;prt.y = SRCH/2;
plb.x =-srcw/2;plb.y =-SRCH/2;
prb.x = SRCW/2; PRB.Y =-SRCH/2;
56//coordinates after rotation
PLTN,PRTN,PLBN,PRBN Point;
Sina double = sin (RADIAN (angle));
Cosa double = cos (RADIAN (angle));
pltn.x = Plt.x*cosa + Plt.y*sina;
PLTN.Y =-plt.x*sina + plt.y*cosa;
prtn.x = Prt.x*cosa + Prt.y*sina;
PRTN.Y =-prt.x*sina + prt.y*cosa;
plbn.x = Plb.x*cosa + Plb.y*sina;
PLBN.Y =-plb.x*sina + plb.y*cosa;
prbn.x = Prb.x*cosa + Prb.y*sina;
PRBN.Y =-prb.x*sina + prb.y*cosa;
68//Image width and height after rotation
deswidth int = max (ABS (prbn.x-pltn.x), ABS (prtn.x-plbn.x));
desheight int = max (ABS (PRBN.Y-PLTN.Y), ABS (PRTN.Y-PLBN.Y));
71//Allocate cache of rotated images
desbufsize int = ((Deswidth * bitcount +)/+) * 4 * desheight;
*desbuf BYTE = new Byte[desbufsize];
74//Preset all pixels to white
memset (desbuf,255,desbufsize);
76//New image per line of bytes, with offset
deslinesize int = ((Deswidth * bitcount + 31)/32) * 4;
78//The coordinates of the corresponding original image are calculated by the coordinates of the new image.
(i = 0; i < desheight; i++)
80 {
Bayi for (j = 0; J < Deswidth; J + +)
82 {
83//Convert to an image-centric coordinate system with inverse rotation
A. int tX = (J-DESWIDTH/2) *cos (RADIAN (360-angle)) + (-i + DESHEIGHT/2) *sin (RADIAN (360-angle));
(J-DESWIDTH/2) *sin (RADIAN (360-angle)) + (-i + DESHEIGHT/2) *cos (RADIAN (360-angle));
86//If this coordinate is not in the original image, no value is assigned
if (tx > SRCW/2 | | tx <-SRCW/2 | | ty > SRCH/2 | | ty <-SRCH/2)
88 {
Continue;
90}
91//re-convert to the original coordinate system
TXN int = TX + srcw/2; int TYN = ABS (TY-SRCH/2);
93//Value Copy
94 memcpy (&desbuf[i * deslinesize + J * Bitcount/8],&srcbuf[tyn * linesize + TXN * bitcount/8],3);
95}
96}
97
98//Create target file
hfile hfile = _lcreat (Desfile.c_str (), 0);
100//File header information
101 Bitmapfileheader Nbmfheader;
102 Nbmfheader.bftype = 0x4d42;
103 nbmfheader.bfsize = sizeof (Bitmapfileheader) + sizeof (Bitmapinfoheader)
104 + deswidth * desheight * BITCOUNT/8;
nbmfheader.bfreserved1 = 0;
106 Nbmfheader.bfreserved2 = 0;
107 nbmfheader.bfoffbits = sizeof (Bitmapfileheader) + sizeof (bitmapinfoheader);
108//bitmap Header Information
109 Bitmapinfoheader BMI;
Bmi.bisize=sizeof (Bitmapinfoheader);
111 Bmi.biwidth=deswidth;
Bmi.biheight=desheight;
113 Bmi.biplanes=1;
Bmi.bibitcount=bitcount;
Bmi.bicompression=bi_rgb;
bmi.bisizeimage=0;
117 bmi.bixpelspermeter=0;
118 bmi.biypelspermeter=0;
119 Bmi.biclrused=0;
bmi.biclrimportant=0;
121
122//write file header information
123 _lwrite (hfile, (LPCSTR) &nbmfheader,sizeof (Bitmapfileheader));
124//write bitmap header information
_lwrite (hfile, (LPCSTR) &bmi,sizeof (Bitmapinfoheader));
126//Write image data
127 _lwrite (hfile, (LPCSTR) desbuf,desbufsize);
_lclose (hfile);
129}
130
131 int main (int argc, char* argv[])
132 {
133 FILE *pfile;
134 if ((PFile = fopen ("E://t.bmp", "RB")) = = NULL)
135 {
136 printf ("Open BMP File Error.");
137 return-1;
138}
139 String Srcfile ("E://t.bmp");
Desfile string ("E://rotation.bmp");
141 Rotation (srcfile,desfile,150);
142 System ("pause");
143 return 0;
144}
Algorithm analysis and code implementation of OPENCV to realize arbitrary angle rotation of image

Vivid_song

Algorithm parsing

Program implementation

#include "CXCORE.h"
#include "Cv.h"
#include "highgui.h"
using namespace CV;
iplimage*m_img;
Double Max (double a,double b)
{
Return (a > B)? A:B;
}
void Imgrotate (bool direction)
{
int oldwidth = m_img->width;
int oldheight = m_img->height;


The coordinates of the four corners of the source figure (in the image center as the coordinate system origin)
Float fSrcX1, fSrcY1, fSrcX2, fSrcY2, FSrcX3, FSrcY3, fSrcX4, fSrcY4;
fSrcX1 = (float) (-(OldWidth)/2);
fSrcY1 = (float) ((oldheight)/2);//Second Quadrant
fSrcX2 = (float) ((oldwidth)/2);
fSrcY2 = (float) ((oldheight)/2);//First Quadrant
FSrcX3 = (float) (-(OldWidth)/2);
FSrcY3 = (float) (-(OldHeight)/2);//Fourth Quadrant
FSrcX4 = (float) ((oldwidth)/2);
FSrcY4 = (float) (-(OldHeight)/2);//Third Quadrant


Coordinates of Four Corners after rotation (in the image center as the coordinate system origin)
Float fDstX1, fDstY1, fDstX2, fDstY2, FDstX3, FDstY3, fDstX4, fDstY4;
float theta = 0.5*cv_pi*direction;
fDstX1 = cos (theta) * fSrcX1 + sin (theta) * FSRCY1;
fDstY1 =-sin (theta) * fSrcX1 + cos (theta) * FSRCY1;
fDstX2 = cos (theta) * fSrcX2 + sin (theta) * FSRCY2;
fDstY2 =-sin (theta) * fSrcX2 + cos (theta) * FSRCY2;
fDstX3 = cos (theta) * fSrcX3 + sin (theta) * FSRCY3;
fDstY3 =-sin (theta) * fSrcX3 + cos (theta) * FSRCY3;
fDstX4 = cos (theta) * fSrcX4 + sin (theta) * FSRCY4;
FDstY4 =-sin (theta) * fSrcX4 + cos (theta) * FSRCY4;
New width and height
int newwidth = (max (fabs (FDSTX4-FDSTX1), Fabs (FDSTX3-FDSTX2)));
int newheight = (max (fabs (fdsty4-fdsty1), Fabs (Fdsty3-fdsty2)));


IPLIMAGE*DST = Cvcreateimage (Cvsize (Newwidth, Newheight), m_img->depth, m_img->nchannels);
See rotation principle, determinant in the third row 12th column
float dx = -0.5*newwidth*cos (theta)-0.5*newheight*sin (theta) + 0.5*oldwidth;
float dy = 0.5*newwidth*sin (theta)-0.5*newheight*cos (theta) + 0.5*oldheight;
Read every point of a new picture
for (int height = 0; height<newheight; height++)
{
Uchar*ptrnow = (uchar*) (Dst->imagedata + height*dst->widthstep);//point to the No. 0 column of the first row of the picture
for (int width = 0; width<newwidth; width++)
{
int x = float (width) *cos (theta) + float (height) *sin (theta) + dx;
int y = float (-width) *sin (theta) + float (height) *cos (theta) + dy;//points corresponding to the original image
Uchar*ptrold = (uchar*) (M_img->imagedata + y*m_img->widthstep);//point to row No. 0 of the original image
if ((x<0) | | | (x >= oldwidth) | | (y<0) | | (y >= oldheight)) Determine if an area is not an image
{
if (m_img->nchannels = = 3)//Determine the image is a few channels of image
{
Ptrnow[3 * Width + 1] = 0;
Ptrnow[3 * Width + 2] = 0;
Ptrnow[3 * Width + 3] = 0;
}
else if (m_img->nchannels = = 1)
{
Ptrnow[width] = 0;
}
}
Else
{
if (m_img->nchannels = = 3)
{
Ptrnow[3 * Width + 1] = ptrold[3 * x + 1];
Ptrnow[3 * Width + 2] = ptrold[3 * x + 2];
Ptrnow[3 * Width + 3] = ptrold[3 * x + 3];
}
else if (m_img->nchannels = = 1)
{
Ptrnow[width] = ptrold[x];
}
}
}
}
Cvzero (M_IMG);
m_img = Cvcreateimage (Cvsize (Newwidth, Newheight), dst->depth, dst->nchannels);
Cvcopy (DST, m_img);
Cvreleaseimage (&AMP;DST);
}


int main (int argc, char*argv[])
{
m_img = Cvloadimage ("d:\\-led internship \ \ Car Picture \\result.jpg");
Imgrotate (TRUE);
Cvnamedwindow ("Show_image", 0);
Cvshowimage ("Show_image", m_img);
Cvwaitkey (0);
return 0;
}

Image rotation algorithm and its implementation

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.