使用OpenCV将图像旋转90度的最简单方法?
将IplImage/cv :: Mat旋转90度的最佳方式是什么(在c/C++中)?我认为必须有比使用矩阵转换它更好的东西,但我似乎无法在API和在线中找到其他任何东西。使用OpenCV将图像旋转90度的最简单方法?
由于OpenCV3的。2,生活刚刚得到一个更容易一点,你现在可以在一个单一的代码行旋转图像:
cv::rotate(image, image, ROTATE_90_CLOCKWISE);
为方向,您可以选择以下任何一种:
ROTATE_90_CLOCKWISE
ROTATE_180
ROTATE_90_COUNTERCLOCKWISE
更新置换:
您应该使用cvTranspose()
或cv::transpose()
因为(你正确地指出),它的效率更高。同样,我建议升级到OpenCV2.0,因为大部分cvXXX
函数只是将IplImage*
结构转换为Mat
对象(无深度副本)。如果将图像存储在Mat
对象中,则Mat.t()
将返回转置。
任何旋转:
应该通过变换矩阵的总体框架确定旋转矩阵使用cvWarpAffine。我强烈建议升级到OpenCV2.0,它有几个功能,以及一个封装矩阵和图像的Mat
类。使用2.0时,您可以使用warpAffine以上。
嗯,我正在寻找一些细节,并没有找到任何示例。所以我张贴transposeImage
函数,我希望可以帮助其他人谁正在寻找一种直接的方式旋转90°,而不会丢失数据:
IplImage* transposeImage(IplImage* image) {
IplImage *rotated = cvCreateImage(cvSize(image->height,image->width),
IPL_DEPTH_8U,image->nChannels);
CvPoint2D32f center;
float center_val = (float)((image->width)-1)/2;
center.x = center_val;
center.y = center_val;
CvMat *mapMatrix = cvCreateMat(2, 3, CV_32FC1);
cv2DRotationMatrix(center, 90, 1.0, mapMatrix);
cvWarpAffine(image, rotated, mapMatrix,
CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS,
cvScalarAll(0));
cvReleaseMat(&mapMatrix);
return rotated;
}
问:为什么呢?
float center_val = (float)((image->width)-1)/2;
答案:因为它工作:)我发现的唯一中心没有翻译图像。虽然如果有人有解释我会感兴趣。
您的数学原因可能是由于整数除法。你想要做的是:float center_val =(float)image-> width/2.0f。 – 2010-07-02 22:22:24
请注意,如果您只需要以90度增量旋转,则cvTranspose + cvFlip方法稍微快一点。 – 2012-08-13 21:32:09
旋转是转置和翻转的组合。
哪在OpenCV中可以这样写(Python的下面的示例):
img = cv.LoadImage("path_to_image.jpg")
timg = cv.CreateImage((img.height,img.width), img.depth, img.channels) # transposed image
# rotate counter-clockwise
cv.Transpose(img,timg)
cv.Flip(timg,timg,flipMode=0)
cv.SaveImage("rotated_counter_clockwise.jpg", timg)
# rotate clockwise
cv.Transpose(img,timg)
cv.Flip(timg,timg,flipMode=1)
cv.SaveImage("rotated_clockwise.jpg", timg)
请参阅下面的“cv2”:http://*.com/questions/2259678/easiest-way-to-rotate-by-90-degrees-an-image-using-opencv/42359233#42359233 – 2017-02-21 05:19:12
垂直翻转(flipMode = 0)应该比水平翻转要贵一些,因为你更好地使用缓存。因此,首先进行水平翻转,然后进行转置,逆时针旋转应该稍微快一些。 – 2017-04-04 17:20:40
这是一个没有新的C++接口的例子(适用于90,180和270度,使用param = 1,2和3)。请记住在使用后返回的图像上调用cvReleaseImage
。
IplImage *rotate_image(IplImage *image, int _90_degrees_steps_anti_clockwise)
{
IplImage *rotated;
if(_90_degrees_steps_anti_clockwise != 2)
rotated = cvCreateImage(cvSize(image->height, image->width), image->depth, image->nChannels);
else
rotated = cvCloneImage(image);
if(_90_degrees_steps_anti_clockwise != 2)
cvTranspose(image, rotated);
if(_90_degrees_steps_anti_clockwise == 3)
cvFlip(rotated, NULL, 1);
else if(_90_degrees_steps_anti_clockwise == 1)
cvFlip(rotated, NULL, 0);
else if(_90_degrees_steps_anti_clockwise == 2)
cvFlip(rotated, NULL, -1);
return rotated;
}
这里是我的EmguCV(一OpenCV中的C#端口)解决方案:
public static Image<TColor, TDepth> Rotate90<TColor, TDepth>(this Image<TColor, TDepth> img)
where TColor : struct, IColor
where TDepth : new()
{
var rot = new Image<TColor, TDepth>(img.Height, img.Width);
CvInvoke.cvTranspose(img.Ptr, rot.Ptr);
rot._Flip(FLIP.HORIZONTAL);
return rot;
}
public static Image<TColor, TDepth> Rotate180<TColor, TDepth>(this Image<TColor, TDepth> img)
where TColor : struct, IColor
where TDepth : new()
{
var rot = img.CopyBlank();
rot = img.Flip(FLIP.VERTICAL);
rot._Flip(FLIP.HORIZONTAL);
return rot;
}
public static void _Rotate180<TColor, TDepth>(this Image<TColor, TDepth> img)
where TColor : struct, IColor
where TDepth : new()
{
img._Flip(FLIP.VERTICAL);
img._Flip(FLIP.HORIZONTAL);
}
public static Image<TColor, TDepth> Rotate270<TColor, TDepth>(this Image<TColor, TDepth> img)
where TColor : struct, IColor
where TDepth : new()
{
var rot = new Image<TColor, TDepth>(img.Height, img.Width);
CvInvoke.cvTranspose(img.Ptr, rot.Ptr);
rot._Flip(FLIP.VERTICAL);
return rot;
}
应该不会太难回转化为C++。
这里是我的Python cv2
实现:
import cv2
img=cv2.imread("path_to_image.jpg")
# rotate ccw
out=cv2.transpose(img)
out=cv2.flip(out,flipCode=0)
# rotate cw
out=cv2.transpose(img)
out=cv2.flip(out,flipCode=1)
cv2.imwrite("rotated.jpg", out)
您的ccw代码进行cw转换。 – Jason 2017-06-08 02:51:42
已更正。谢谢@Jason! – 2017-06-08 20:49:32
C++的答案是[这里](http://*.com/a/16278334/2436175)。 – Antonio 2016-02-17 10:00:57