您的位置:首页 > 运维架构

利用OpenCV旋转图像的摸索(2)

2017-02-25 13:49 531 查看
http://blog.csdn.net/leaf6094189/article/details/18554549以及http://blog.csdn.net/xiaowei_cqu/article/details/7616044对图像的矩阵变换做了详细的阐述:二维图的变换,如旋转、平移、缩放等,都可以转化为一系列的矩阵操作。这个变换矩阵是是2行3列的cv::Mat。变换矩阵通常的type()是CV_64FC1型,即是说,6个元素的类型都是double。保存在cv::Mat::data为首地址的一段内存里面。由于cv::Mat是行主序排列,所以第一行的3个元素先排,第二行的3个元素后排。

根据 http://blog.csdn.net/xiaowei_cqu/article/details/7616044的说法,这个矩阵的前两列构成一个2x2的矩阵,任何的围绕图像原点(原点即图像左上角)的旋转操作和任何缩放操作都可以用这个2x2矩阵表述。而矩阵的平移则由矩阵的第三列表示。这里要注意,在坐标变换里,少不了规定坐标系。OpenCV规定X正方向是图像的右方,而Y正方向是图像下方。
下图所示的矩阵,表示先将图像绕坐标系原点(即图像左上)逆时针转动角度a,然后沿X方向和Y方向分别平移dX,dY。



接下来验证上面的话。跟利用OpenCV旋转图像的摸索(1)一样,我们利用一张274x300的莱纳图。先产生一个围绕(0,0)旋转的矩阵rotateMat。这样会让图像逆时针转动30度。,如下图:



但是转出去的部分(红线以上)就看不到了。为了让图像完整可见,还要下移图像。于是,接下来把rotateMat.data的第6个元素设置为137.

这是因为图像宽度是274,所以转出部分的高度就是274 * sin(30) = 137. 第六个元素是前面提到的dY,也就是图像下移的像素数。

代码:

int _tmain(int argc, _TCHAR* argv[])
{
cv::Mat image = cv::imread("E:\\lena.jpg");
if (image.empty())
{
std::cout<<"read image failure"<<std::endl;
return -1;
}

//cv::Point2f center = cv::Point2f(image.cols , image.rows );  // 旋转中心
cv::Point2f center = cv::Point2f(0 , 0 );
double angle = 30;  // 旋转角度
double scale = 1; // 缩放尺度

cv::Mat rotateMat;
rotateMat = cv::getRotationMatrix2D(center, angle, scale);
/*注意这段代码:*/
cv::Mat shiftImg = cv::Mat::zeros(image.rows * 2, image.cols * 2, image.type());
int iType = rotateMat.type();
//cv::Mat ROI = shiftImg(cv::Rect(image.cols / 2, image.rows/2, image.cols, image.rows));
cv::Mat ROI = shiftImg(cv::Rect(0, 0, image.cols, image.rows));
image.copyTo(ROI);
/***************/
cv::Mat rotateImg;
unsigned char * pData = rotateMat.data + sizeof(double) * 5;
double dY = 137;
memcpy(pData, &dY, sizeof(double));
cv::warpAffine(shiftImg, rotateImg, rotateMat, shiftImg.size());
double arrMat[6];
memcpy(arrMat, rotateMat.data, sizeof(double) * 6);
printf("%lf %lf %lf %lf %lf %lf", arrMat[0], arrMat[1], arrMat[2], arrMat[3], arrMat[4], arrMat[5]);
cv::imwrite("E:\\rotate.jpg", rotateImg);
cv::imwrite("E:\\shift.jpg", shiftImg);
return 0;
}
加断点观察可见,rotateMat.data的内容确实与前面分析的一致:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  opencv Mat 图像旋转