Ask Your Question

Revision history [back]

in the first you have to rotate 4 corners of image then compute rectangle of rotated points. In the following code you have to call bhRotateImage for rotate of image.

#define BH_DEG_TO_RAD   CV_PI/180
BH_RECT bhBlankRECT()
{
    BH_RECT res;
    res.left = BH_MAXINT;
    res.top = BH_MAXINT;
    res.bottom = 0;
    res.right = 0;
    return res;

}
int bhLineLength(CvPoint p1,CvPoint p2)
{
    int res ;
    if ( (p2.x == p1.x) && (p2.y == p1.y))
        res = 0;
    else  if (p2.x == p1.x)  
        res = abs(p2.y - p1.y);
    else if (p2.y == p1.y)  
        res = abs(p2.x - p1.x);
    else 
        res = cvRound( sqrt(pow((float)p2.y-p1.y,2) + pow((float)p2.x-p1.x,2)));

    return res;
}
float bhGetLineAngle(CvPoint p1, CvPoint p2)
{
    float deg =  float( atan2( (float)(p2.y - p1.y) , (float)(p2.x - p1.x)) * BH_RAD_TO_DEG );
    if (deg < 0)
        deg = 360 + deg;

    return deg;
}


CvRect bhGetImageCvRect(const IplImage* srcImage)
{
    return cvRect(0,0,srcImage->width,srcImage->height);
}
BhPoints32f bhGetRectPoints(CvRect srcRect)
{
    BhPoints32f result;
    result.push_back(cvPoint2D32f(srcRect.x,srcRect.y));
    result.push_back(cvPoint2D32f(srcRect.x + srcRect.width,srcRect.y));
    result.push_back(cvPoint2D32f(srcRect.x + srcRect.width ,srcRect.y + srcRect.height));
    result.push_back(cvPoint2D32f(srcRect.x,srcRect.y + srcRect.height));
    return result;
}
CvPoint2D32f bhRotatePoint(CvPoint2D32f srcPoint,CvPoint2D32f center,float angle)
{
    int rad = bhLineLength(cvPointFrom32f(srcPoint),cvPointFrom32f(center));
    float teta = bhGetLineAngle(cvPointFrom32f(center),cvPointFrom32f(srcPoint));

    CvPoint2D32f result;
    float newTeta = angle + teta;
    result.x =  center.x + cvRound( rad * cos(newTeta * BH_DEG_TO_RAD));
    result.y =  center.y + cvRound( rad * sin(newTeta * BH_DEG_TO_RAD));
    return result;

}



void bhRotatePoints(BhPoints32f& srcPoints,CvPoint2D32f center,float angle)
{
    for (unsigned int i =0 ; i < srcPoints.size();i++)
    {
        srcPoints[i] = bhRotatePoint(srcPoints[i],center,angle);

    }

}

CvRect bhGetPoints32fCVRect(BhPoints32f points)
{

  BH_RECT r = bhBlankRECT();
  for (unsigned int i=0; i < points.size() ;i++)
  {
      if (points[i].x < r.left)
          r.left = (int) points[i].x;

      if (points[i].x > r.right)
          r.right = (int)points[i].x;

      if (points[i].y < r.top)
          r.top = (int)points[i].y;

      if (points[i].y > r.bottom)
          r.bottom = (int)points[i].y;

  }

  return bhRect2CvRect(r);
}
CvPoint bhGetImageCenter(const IplImage* srcImage)
{
    return cvPoint(srcImage->width/2,srcImage->height/2);
}

IplImage* bhRotateImage(const IplImage* srcImage,CvPoint center,double angle,CvScalar fillval ,CvPoint& offsetPoint,int flags )
{
   CvMat* rot_mat = cvCreateMat(2,3,CV_32FC1);
   cv2DRotationMatrix(cvPointTo32f( center), angle, 1, rot_mat );
   IplImage* resultImage = NULL;

   CvRect imageRect = bhGetImageCvRect(srcImage);
   BhPoints32f rectPoints = bhGetRectPoints(imageRect);
   bhRotatePoints(rectPoints,cvPointTo32f(center),float(-angle));
   CvRect rotateRect = bhGetPoints32fCVRect(rectPoints);

   CV_MAT_ELEM(*rot_mat,float,0,2) = CV_MAT_ELEM(*rot_mat,float,0,2) - rotateRect.x;
   CV_MAT_ELEM(*rot_mat,float,1,2) = CV_MAT_ELEM(*rot_mat,float,1,2) - rotateRect.y;

   resultImage = cvCreateImage(bhGetRectSize(rotateRect),srcImage->depth,srcImage->nChannels);

   cvSetImageROI(resultImage,bhGetImageCvRect(resultImage));
   cvWarpAffine( srcImage, resultImage, rot_mat ,flags,fillval);
   cvResetImageROI(resultImage);
   offsetPoint = cvPoint(rotateRect.x,rotateRect.y);

   CvPoint preCenter = bhGetImageCenter(srcImage);
   CvPoint curCenter = bhGetImageCenter(resultImage);

   offsetPoint = cvPoint(curCenter.x - preCenter.x , curCenter.y - preCenter.y);

   cvReleaseMat(&rot_mat);
   return resultImage;
}

in the first you have to rotate 4 corners of image then compute rectangle of rotated points. In the following code you have to call bhRotateImage for rotate of image.

#define BH_DEG_TO_RAD   CV_PI/180
#define BH_RAD_TO_DEG   180/CV_PI
typedef unsigned int        UINT; 
#define BH_MAXUINT     ((UINT)~((UINT)0))
#define BH_MAXINT      ((int)(BH_MAXUINT >> 1))
typedef vector<CvPoint2D32f> BhPoints32f;
CvSize bhGetRectSize(const CvRect srcRect)
{
return cvSize(srcRect.width,srcRect.height);
}
BH_RECT bhBlankRECT()
{
    BH_RECT res;
    res.left = BH_MAXINT;
    res.top = BH_MAXINT;
    res.bottom = 0;
    res.right = 0;
    return res;

}
int bhLineLength(CvPoint p1,CvPoint p2)
{
    int res ;
    if ( (p2.x == p1.x) && (p2.y == p1.y))
        res = 0;
    else  if (p2.x == p1.x)  
        res = abs(p2.y - p1.y);
    else if (p2.y == p1.y)  
        res = abs(p2.x - p1.x);
    else 
        res = cvRound( sqrt(pow((float)p2.y-p1.y,2) + pow((float)p2.x-p1.x,2)));

    return res;
}
float bhGetLineAngle(CvPoint p1, CvPoint p2)
{
    float deg =  float( atan2( (float)(p2.y - p1.y) , (float)(p2.x - p1.x)) * BH_RAD_TO_DEG );
    if (deg < 0)
        deg = 360 + deg;

    return deg;
}


CvRect bhGetImageCvRect(const IplImage* srcImage)
{
    return cvRect(0,0,srcImage->width,srcImage->height);
}
BhPoints32f bhGetRectPoints(CvRect srcRect)
{
    BhPoints32f result;
    result.push_back(cvPoint2D32f(srcRect.x,srcRect.y));
    result.push_back(cvPoint2D32f(srcRect.x + srcRect.width,srcRect.y));
    result.push_back(cvPoint2D32f(srcRect.x + srcRect.width ,srcRect.y + srcRect.height));
    result.push_back(cvPoint2D32f(srcRect.x,srcRect.y + srcRect.height));
    return result;
}
CvPoint2D32f bhRotatePoint(CvPoint2D32f srcPoint,CvPoint2D32f center,float angle)
{
    int rad = bhLineLength(cvPointFrom32f(srcPoint),cvPointFrom32f(center));
    float teta = bhGetLineAngle(cvPointFrom32f(center),cvPointFrom32f(srcPoint));

    CvPoint2D32f result;
    float newTeta = angle + teta;
    result.x =  center.x + cvRound( rad * cos(newTeta * BH_DEG_TO_RAD));
    result.y =  center.y + cvRound( rad * sin(newTeta * BH_DEG_TO_RAD));
    return result;

}



void bhRotatePoints(BhPoints32f& srcPoints,CvPoint2D32f center,float angle)
{
    for (unsigned int i =0 ; i < srcPoints.size();i++)
    {
        srcPoints[i] = bhRotatePoint(srcPoints[i],center,angle);

    }

}

CvRect bhGetPoints32fCVRect(BhPoints32f points)
{

  BH_RECT r = bhBlankRECT();
  for (unsigned int i=0; i < points.size() ;i++)
  {
      if (points[i].x < r.left)
          r.left = (int) points[i].x;

      if (points[i].x > r.right)
          r.right = (int)points[i].x;

      if (points[i].y < r.top)
          r.top = (int)points[i].y;

      if (points[i].y > r.bottom)
          r.bottom = (int)points[i].y;

  }

  return bhRect2CvRect(r);
}
CvPoint bhGetImageCenter(const IplImage* srcImage)
{
    return cvPoint(srcImage->width/2,srcImage->height/2);
}

IplImage* bhRotateImage(const IplImage* srcImage,CvPoint center,double angle,CvScalar fillval ,CvPoint& offsetPoint,int flags )
{
   CvMat* rot_mat = cvCreateMat(2,3,CV_32FC1);
   cv2DRotationMatrix(cvPointTo32f( center), angle, 1, rot_mat );
   IplImage* resultImage = NULL;

   CvRect imageRect = bhGetImageCvRect(srcImage);
   BhPoints32f rectPoints = bhGetRectPoints(imageRect);
   bhRotatePoints(rectPoints,cvPointTo32f(center),float(-angle));
   CvRect rotateRect = bhGetPoints32fCVRect(rectPoints);

   CV_MAT_ELEM(*rot_mat,float,0,2) = CV_MAT_ELEM(*rot_mat,float,0,2) - rotateRect.x;
   CV_MAT_ELEM(*rot_mat,float,1,2) = CV_MAT_ELEM(*rot_mat,float,1,2) - rotateRect.y;

   resultImage = cvCreateImage(bhGetRectSize(rotateRect),srcImage->depth,srcImage->nChannels);

   cvSetImageROI(resultImage,bhGetImageCvRect(resultImage));
   cvWarpAffine( srcImage, resultImage, rot_mat ,flags,fillval);
   cvResetImageROI(resultImage);
   offsetPoint = cvPoint(rotateRect.x,rotateRect.y);

   CvPoint preCenter = bhGetImageCenter(srcImage);
   CvPoint curCenter = bhGetImageCenter(resultImage);

   offsetPoint = cvPoint(curCenter.x - preCenter.x , curCenter.y - preCenter.y);

   cvReleaseMat(&rot_mat);
   return resultImage;
}

in In the first you have to rotate 4 corners of image then compute rectangle of rotated points. In the following code you have to call bhRotateImage for rotate of image.

#define BH_DEG_TO_RAD   CV_PI/180
#define BH_RAD_TO_DEG   180/CV_PI
typedef unsigned int        UINT; 
#define BH_MAXUINT     ((UINT)~((UINT)0))
#define BH_MAXINT      ((int)(BH_MAXUINT >> 1))
typedef vector<CvPoint2D32f> BhPoints32f;
CvSize bhGetRectSize(const CvRect srcRect)
{
return cvSize(srcRect.width,srcRect.height);
}
BH_RECT bhBlankRECT()
{
    BH_RECT res;
    res.left = BH_MAXINT;
    res.top = BH_MAXINT;
    res.bottom = 0;
    res.right = 0;
    return res;

}
int bhLineLength(CvPoint p1,CvPoint p2)
{
    int res ;
    if ( (p2.x == p1.x) && (p2.y == p1.y))
        res = 0;
    else  if (p2.x == p1.x)  
        res = abs(p2.y - p1.y);
    else if (p2.y == p1.y)  
        res = abs(p2.x - p1.x);
    else 
        res = cvRound( sqrt(pow((float)p2.y-p1.y,2) + pow((float)p2.x-p1.x,2)));

    return res;
}
float bhGetLineAngle(CvPoint p1, CvPoint p2)
{
    float deg =  float( atan2( (float)(p2.y - p1.y) , (float)(p2.x - p1.x)) * BH_RAD_TO_DEG );
    if (deg < 0)
        deg = 360 + deg;

    return deg;
}


CvRect bhGetImageCvRect(const IplImage* srcImage)
{
    return cvRect(0,0,srcImage->width,srcImage->height);
}
BhPoints32f bhGetRectPoints(CvRect srcRect)
{
    BhPoints32f result;
    result.push_back(cvPoint2D32f(srcRect.x,srcRect.y));
    result.push_back(cvPoint2D32f(srcRect.x + srcRect.width,srcRect.y));
    result.push_back(cvPoint2D32f(srcRect.x + srcRect.width ,srcRect.y + srcRect.height));
    result.push_back(cvPoint2D32f(srcRect.x,srcRect.y + srcRect.height));
    return result;
}
CvPoint2D32f bhRotatePoint(CvPoint2D32f srcPoint,CvPoint2D32f center,float angle)
{
    int rad = bhLineLength(cvPointFrom32f(srcPoint),cvPointFrom32f(center));
    float teta = bhGetLineAngle(cvPointFrom32f(center),cvPointFrom32f(srcPoint));

    CvPoint2D32f result;
    float newTeta = angle + teta;
    result.x =  center.x + cvRound( rad * cos(newTeta * BH_DEG_TO_RAD));
    result.y =  center.y + cvRound( rad * sin(newTeta * BH_DEG_TO_RAD));
    return result;

}



void bhRotatePoints(BhPoints32f& srcPoints,CvPoint2D32f center,float angle)
{
    for (unsigned int i =0 ; i < srcPoints.size();i++)
    {
        srcPoints[i] = bhRotatePoint(srcPoints[i],center,angle);

    }

}

CvRect bhGetPoints32fCVRect(BhPoints32f points)
{

  BH_RECT r = bhBlankRECT();
  for (unsigned int i=0; i < points.size() ;i++)
  {
      if (points[i].x < r.left)
          r.left = (int) points[i].x;

      if (points[i].x > r.right)
          r.right = (int)points[i].x;

      if (points[i].y < r.top)
          r.top = (int)points[i].y;

      if (points[i].y > r.bottom)
          r.bottom = (int)points[i].y;

  }

  return bhRect2CvRect(r);
}
CvPoint bhGetImageCenter(const IplImage* srcImage)
{
    return cvPoint(srcImage->width/2,srcImage->height/2);
}

IplImage* bhRotateImage(const IplImage* srcImage,CvPoint center,double angle,CvScalar fillval ,CvPoint& offsetPoint,int flags )
{
   CvMat* rot_mat = cvCreateMat(2,3,CV_32FC1);
   cv2DRotationMatrix(cvPointTo32f( center), angle, 1, rot_mat );
   IplImage* resultImage = NULL;

   CvRect imageRect = bhGetImageCvRect(srcImage);
   BhPoints32f rectPoints = bhGetRectPoints(imageRect);
   bhRotatePoints(rectPoints,cvPointTo32f(center),float(-angle));
   CvRect rotateRect = bhGetPoints32fCVRect(rectPoints);

   CV_MAT_ELEM(*rot_mat,float,0,2) = CV_MAT_ELEM(*rot_mat,float,0,2) - rotateRect.x;
   CV_MAT_ELEM(*rot_mat,float,1,2) = CV_MAT_ELEM(*rot_mat,float,1,2) - rotateRect.y;

   resultImage = cvCreateImage(bhGetRectSize(rotateRect),srcImage->depth,srcImage->nChannels);

   cvSetImageROI(resultImage,bhGetImageCvRect(resultImage));
   cvWarpAffine( srcImage, resultImage, rot_mat ,flags,fillval);
   cvResetImageROI(resultImage);
   offsetPoint = cvPoint(rotateRect.x,rotateRect.y);

   CvPoint preCenter = bhGetImageCenter(srcImage);
   CvPoint curCenter = bhGetImageCenter(resultImage);

   offsetPoint = cvPoint(curCenter.x - preCenter.x , curCenter.y - preCenter.y);

   cvReleaseMat(&rot_mat);
   return resultImage;
}