亲爱的, 使用下面的代码,我旋转了cv :: Mat对象(除了load / save / convertionColor ..之外,我没有使用任何Cv的函数,因为这是一个学术项目),并且收到了裁剪的图像
旋转功能:
float rads = angle*3.1415926/180.0;
float _cos = cos(-rads);
float _sin = sin(-rads);
float xcenter = (float)(src.cols)/2.0;
float ycenter = (float)(src.rows)/2.0;
for(int i = 0; i < src.rows; i++)
for(int j = 0; j < src.cols; j++){
int x = ycenter + ((float)(i)-ycenter)*_cos - ((float)(j)-xcenter)*_sin;
int y = xcenter + ((float)(i)-ycenter)*_sin + ((float)(j)-xcenter)*_cos;
if (x >= 0 && x < src.rows && y >= 0 && y < src.cols) {
dst.at<cv::Vec4b>(i ,j) = src.at<cv::Vec4b>(x, y);
}
else {
dst.at<cv::Vec4b>(i ,j)[3] = 0;
}
}
我想知道,每次旋转图像时如何保存完整图像。 我是否在功能中缺少某些内容? 预先感谢
答案 0 :(得分:2)
旋转后的图像通常必须比旧图像大,才能存储所有像素值。
每个点(x,y)
被翻译为
(x', y') = (x*cos(rads) - y*sin(rads), x*sin(rads) + y*cos(rads))
图像的高度为h
,宽度为w
,中心位于(0,0),四角位于
(h/2, w/2)
(h/2, -w/2)
(-h/2, w/2)
(-h/2, -w/2)
具有新高度
h' = 2*y' = 2 * (w/2*sin(rads) + h/2*cos(rads))
和新宽度
w' = 2*x' = 2 * (w/2*cos(rads) + h/2*sin(rads))
0 <= rads <= pi/4
。它是x * y <= x' * y'
,对于rads != k*pi/2
和k = 1, 2, ...
,它是x * y < x' * y'
在任何情况下,旋转后图像的面积都等于或大于旧图像的面积。
如果使用旧尺寸,则会切掉角落。
示例:
您的图片包含h=1
,w=1
和rads=pi/4
。您需要具有h'=sqrt(2)=1.41421356237
和w'=sqrt(2)=1.41421356237
的新图像来存储所有像素值。来自(1,1)的像素被转换为(0,sqrt(2))。