我需要将图像旋转 90、180 或 270 度。在 OpenCV4Android 中我可以使用:
Imgproc.getRotationMatrix2D(new Point(center, center), degrees, 1);
Imgproc.warpAffine(src, dst, rotationMatrix, dst.size());
但是,这是我的图像处理算法中的一个巨大瓶颈。当然,简单旋转 90 度的倍数比 warpAffine
的最一般情况简单得多,并且可以更有效地完成。例如,对于 180 度,我可以使用:
Core.flip(src, dst, -1);
其中 -1 表示绕水平轴和垂直轴翻转。是否有类似的优化可以用于 90 度或 270 度旋转?
最佳答案
我不太了解Java API,这段代码是用c++开发的。 逻辑应该是一样的,使用 transpose + flip 来旋转图像 90n(n属于N = -int的最小值,.....,-3,-2,-1,0,1,2,3,...,int的最大值)
/*
*@brief rotate image by multiple of 90 degrees
*
*@param source : input image
*@param dst : output image
*@param angle : factor of 90, even it is not factor of 90, the angle
* will be mapped to the range of [-360, 360].
* {angle = 90n; n = {-4, -3, -2, -1, 0, 1, 2, 3, 4} }
* if angle bigger than 360 or smaller than -360, the angle will
* be map to -360 ~ 360.
* mapping rule is : angle = ((angle / 90) % 4) * 90;
*
* ex : 89 will map to 0, 98 to 90, 179 to 90, 270 to 3, 360 to 0.
*
*/
void rotate_image_90n(cv::Mat &src, cv::Mat &dst, int angle)
{
if(src.data != dst.data){
src.copyTo(dst);
}
angle = ((angle / 90) % 4) * 90;
//0 : flip vertical; 1 flip horizontal
bool const flip_horizontal_or_vertical = angle > 0 ? 1 : 0;
int const number = std::abs(angle / 90);
for(int i = 0; i != number; ++i){
cv::transpose(dst, dst);
cv::flip(dst, dst, flip_horizontal_or_vertical);
}
}
编辑:提高性能,感谢TimZaman的评论和1''的实现
void rotate_90n(cv::Mat const &src, cv::Mat &dst, int angle)
{
CV_Assert(angle % 90 == 0 && angle <= 360 && angle >= -360);
if(angle == 270 || angle == -90){
// Rotate clockwise 270 degrees
cv::transpose(src, dst);
cv::flip(dst, dst, 0);
}else if(angle == 180 || angle == -180){
// Rotate clockwise 180 degrees
cv::flip(src, dst, -1);
}else if(angle == 90 || angle == -270){
// Rotate clockwise 90 degrees
cv::transpose(src, dst);
cv::flip(dst, dst, 1);
}else if(angle == 360 || angle == 0 || angle == -360){
if(src.data != dst.data){
src.copyTo(dst);
}
}
}
关于java - 将图像旋转 90、180 或 270 度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16265673/