利用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,也就是图像下移的像素数。
代码:
根据 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旋转图像的摸索(1)
- 利用opencv函数对图像旋转后,按旋转偏移新计算新的图像外接四边形绘制
- OpenCV利用矩阵实现图像旋转
- 利用OpenCV实现旋转文本图像矫正的原理及OpenCV代码
- OpenCV利用矩阵实现图像旋转
- opencv 利用仿射变换函数对图像进行任意角度旋转
- 在Python下利用OpenCV来旋转图像的教程
- Android Jni 利用OpenCV 实现图像任意角度旋转
- 利用OpenCV给图像添加标注
- OpenCV学习笔记(18):在OpenCV中利用鼠标绘制矩形和截取图像的矩形区域
- 利用OpenCV生成关于某点的颜色径向均匀渐变图像
- OpenCV2:图像的几何变换,平移、镜像、缩放、旋转(2)
- 将图像扭正确。利用OpenCV检测图像中的长方形画布或纸张并提取图像内容
- opencv系列之一 利用透视变换实现图像的俯视图(正视图)
- opencv实现图像任意角度旋转的算法解析及代码实现
- 利用均值漂移实现图像分割的原理和OpenCV代码
- 利用人体肤色从图像中分割出人体区域的OpenCV代码
- 【OpenCV】图像几何变换:旋转,缩放,斜切
- OpenCV实现图像的旋转
- 利用opencv函数计算图像的梯度幅度和梯度方向