views:

117

answers:

2

When I use this code to rotate the image, the destination image size remains same and hence the image gets clipped. Please provide me a way/code snippet to resize accordingly (like matlab does in imrotate) so that image does not get clipped and outlier pixels gets filled with all white instead of black. I dont image to be scaled down to fit in original size. I just want rotation, no scaling.

void imrotate(std::string imgPath,std::string angleStr,std::string outPath) {
    size_t found1,found2;
    found1=imgPath.find_last_of('/');
    found2=imgPath.size()-4;
    IplImage* src=cvLoadImage(imgPath.c_str(), -1);;
    IplImage* dst;
    dst = cvCloneImage( src );
    int angle = atoi(angleStr.c_str());
    CvMat* rot_mat = cvCreateMat(2,3,CV_32FC1);
    CvPoint2D32f center = cvPoint2D32f(
        src->width/2,
        src->height/2
    );
    double scale = 1;
    cv2DRotationMatrix( center, angle, scale, rot_mat );
    cvWarpAffine( src, dst, rot_mat);
    char angStr[4];
    sprintf(angStr,"%d",angle);
    cvSaveImage(string(outPath+imgPath.substr(found1+1,found2-found1-1)+"_"+angStr+".jpg").c_str(),dst);
    cvReleaseImage(&src);
    cvReleaseImage(&dst);
    cvReleaseMat( &rot_mat );
}

Original Image:

alt text

Rotated Image:

alt text

+1  A: 

Instead of cloning the source image as the dest you are going to have to create an image big enough to take the final rotated image, which will be a square with sides 1.5 times the biggest of the source width or height.

Edit:

The amount you need to enlarge the destination by is 1 + sin(angle of rotation), which has a maximum value at 45 degrees of 1.414... This must be rounded up to a suitable value

David Sykes
Isn't it: "… a square with sides 1.414… times …"
Didier Trosset
a suitably rounded up value of 1.414..., yes
David Sykes
+1  A: 

You need to make the source image bigger by padding before doing the rotation.

IplImage* src_b = cvCreateImage( cvSize(src->width+src->width/2,src->height+src->height/2), src->depth, src->nChannels );
IplImage* dst = cvCreateImage( cvSize(src->width+src->width/2,src->height+src->height/2), src->depth, src->nChannels );

// copy src to bigger image with white border
CvPoint offset = cvPoint(src->width/4,+src->height/4);
cvCopyMakeBorder(src, src_b, offset, IPL_BORDER_CONSTANT, cvScalarAll(255));

// find rotation matrix ....

// Rotate with white fill
cvWarpAffine( src_2, dst, rot_mat, CV_WARP_FILL_OUTLIERS, cvScalarAll(255));

Here the image is 1.5 bigger instead of 1.414 for obvious reasons.

sjchoi