旋转函数RotateDIB会使画布变大,旋转越多就越大,但我用旋转只是想纠正原来被旋转过的正方形,希望画布变小,要怎么做?

ljooo 2008-07-23 04:15:26
比如我把一个正方形顺时钟选择了25度,画布变大了。我想逆时针旋转25恢复原来的正方形,让画布跟原来一样大,但实际是每次旋转画布都会变大,我怎么修改原来的算法,使它变小呢?

这是原来的代码:

// 将旋转角度从度转换到弧度
fRotateAngle = (float) RADIAN(iRotateAngle);

// 计算旋转角度的正弦
fSina = (float) sin((double)fRotateAngle);

// 计算旋转角度的余弦
fCosa = (float) cos((double)fRotateAngle);

// 计算原图的四个角的坐标(以图像中心为坐标系原点)
fSrcX1 = (float) (- (lWidth - 1) / 2);
fSrcY1 = (float) ( (lHeight - 1) / 2);
fSrcX2 = (float) ( (lWidth - 1) / 2);
fSrcY2 = (float) ( (lHeight - 1) / 2);
fSrcX3 = (float) (- (lWidth - 1) / 2);
fSrcY3 = (float) (- (lHeight - 1) / 2);
fSrcX4 = (float) ( (lWidth - 1) / 2);
fSrcY4 = (float) (- (lHeight - 1) / 2);

// 计算新图四个角的坐标(以图像中心为坐标系原点)
fDstX1 = fCosa * fSrcX1 + fSina * fSrcY1;
fDstY1 = -fSina * fSrcX1 + fCosa * fSrcY1;
fDstX2 = fCosa * fSrcX2 + fSina * fSrcY2;
fDstY2 = -fSina * fSrcX2 + fCosa * fSrcY2;
fDstX3 = fCosa * fSrcX3 + fSina * fSrcY3;
fDstY3 = -fSina * fSrcX3 + fCosa * fSrcY3;
fDstX4 = fCosa * fSrcX4 + fSina * fSrcY4;
fDstY4 = -fSina * fSrcX4 + fCosa * fSrcY4;

即从 fDstX1,fDstY1 和角度iRotateAngle(跟原来方向相反了),反过来求 fSrcX1,fSrcY1。
我不熟悉三角函数,希望有人帮帮忙,谢谢。
...全文
146 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
ljooo 2008-07-28
  • 打赏
  • 举报
回复
我没用OPENCV。我最后还是先旋转,然后判断有像素的范围,再裁剪。
scq2099yt 2008-07-24
  • 打赏
  • 举报
回复
up
ljooo 2008-07-24
  • 打赏
  • 举报
回复

另外一个贴人家的公式 Img->width原来的宽度求后来的宽度width_tmp。
int width_tmp = int (fabs((sin(angleRad) * Img->width)) +
fabs((cos(angleRad) * Img->height)));

int height_tmp = int (fabs((sin(angleRad) * Img->height)) +
fabs((cos(angleRad) * Img->width)));

那从后来的宽度width_tmp求原来的宽度Img->width, 即它的反函数是什么呢?
ljooo 2008-07-24
  • 打赏
  • 举报
回复
我在1楼发的做法是错误的。
是做图像识别用的,不知道有什么算法可以识别旋转的数字,因此想先矫正角度再识别。正如你说的,正常是先旋转再裁剪,不过不要通常的边缘检测算法了,只需要从上下左右四个方向逼近,直到有黑色像素。我想理论上旋转和裁剪可以同时做的。

算了一个多小时(数学太差了),得到下面这个公式。
// 计算旋转后的图像实际宽度
lNewWidth=fabs((lHeight*fSina-lWidth*fCosa)/(fSina*fSina-fCosa*fCosa));
// 计算旋转后的图像实际高度
lNewHeight=fabs((lWidth*fSina-lHeight*fCosa)/(fSina*fSina-fCosa*fCosa));

//不需要下面这些变量了。
// 源图四个角的坐标(以图像中心为坐标系原点)
//float fSrcX1,fSrcY1,fSrcX2,fSrcY2,fSrcX3,fSrcY3,fSrcX4,fSrcY4;
//// 旋转后四个角的坐标(以图像中心为坐标系原点)
//float fDstX1,fDstY1,fDstX2,fDstY2,fDstX3,fDstY3,fDstX4,fDstY4;
好像在小角度(20度以内)下是正确的,角度大点就错了。45度因为分母为0,(因为是纠正操作,原图在之前旋转了45度,一定lHeight=lWidth,所以分子也为0 ),会出错。
我想这肯定可以推出一个公式,而且不会很复杂,只是我不知道怎样得出。
菜牛 2008-07-24
  • 打赏
  • 举报
回复
矩形旋转后,只要不是旋转90度的倍数,其外包矩形肯定变大了,一般旋转算法肯定要取这个外包矩形作为新的大小,否则就丢数据了。对于你的情况,要么做边缘检测重新设置位图大小,要么后处理由用户选择新的位图大小。当然如果矩形大小是固定的,旋转角度也是固定的,那么简单点直接裁剪掉就可以了。
qidongpan 2008-07-24
  • 打赏
  • 举报
回复
旋转后再缩小,用OPENCV可保证缩小后图片的质量。
ljooo 2008-07-23
  • 打赏
  • 举报
回复
误导人了。不是改上面的代码,是改这里:
// 计算旋转后的图像实际宽度
//原来的代码
//lNewWidth = (LONG) ( max( fabs(fDstX4 - fDstX1), fabs(fDstX3 - fDstX2) ) + 0.5);
//修改后的
lNewWidth = (LONG) ( ( fabs(fDstX4 - fDstX1)+fabs(fDstX3 - fDstX2) )/2 + 0.5);


// 计算旋转后的图像高度
//lNewHeight = (LONG) ( max( fabs(fDstY4 - fDstY1), fabs(fDstY3 - fDstY2) ) + 0.5);
lNewHeight = (LONG) ( ( fabs(fDstY4 - fDstY1)+fabs(fDstY3 - fDstY2) )/2 + 0.5);

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧