30

画像を 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 度の回転に使用できる同様の最適化はありますか?

4

11 に答える 11

46

Java API についてはよくわかりません。このコードは C++ で開発されています。ロジックは同じである必要があります。トランスポーズ + フリップを使用して画像を 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);
        }
    }
}
于 2013-04-29T12:11:09.110 に答える
9

これは、90 の倍数の最も効率的な手段を使用して、任意の角度で画像を回転させます。

    void
    rotate_cw(const cv::Mat& image, cv::Mat& dest, int degrees)
    {
        switch (degrees % 360) {
            case 0:
                dest = image.clone();
                break;
            case 90:
                cv::flip(image.t(), dest, 1);
                break;
            case 180:
                cv::flip(image, dest, -1);
                break;
            case 270:
                cv::flip(image.t(), dest, 0);
                break;
            default:
                cv::Mat r = cv::getRotationMatrix2D({image.cols/2.0F, image.rows/2.0F}, degrees, 1.0);
                int len = std::max(image.cols, image.rows);
                cv::warpAffine(image, dest, r, cv::Size(len, len));
                break; //image size will change
        }
    }

しかし、opencv 3.0 では、これは単にcv::rotateコマンドを介して行われます:

cv::rotate(image, dest, e.g. cv::ROTATE_90_COUNTERCLOCKWISE);
于 2015-02-11T03:12:12.130 に答える
6

Android API を使用したソリューションを次に示します。ここでは、さまざまな向きに取り付けることができるカメラからの画像を回転させるために使用しています。

if (mCameraOrientation == 270) {
    // Rotate clockwise 270 degrees
    Core.flip(src.t(), dst, 0);
} else if (mCameraOrientation == 180) {
    // Rotate clockwise 180 degrees
    Core.flip(src, dst, -1);
} else if (mCameraOrientation == 90) {
    // Rotate clockwise 90 degrees
    Core.flip(src.t(), dst, 1);
} else if (mCameraOrientation == 0) {
    // No rotation
    dst = src;
}
于 2014-12-16T18:51:04.453 に答える
3

これが私のPython翻訳です(そしてすべてのポスターに感謝します):

import cv2
def rot90(img, rotflag):
    """ rotFlag 1=CW, 2=CCW, 3=180"""
    if rotflag == 1:
        img = cv2.transpose(img)  
        img = cv2.flip(img, 1)  # transpose+flip(1)=CW
    elif rotflag == 2:
        img = cv2.transpose(img)  
        img = cv2.flip(img, 0)  # transpose+flip(0)=CCW
    elif rotflag ==3:
        img = cv2.flip(img, -1)  # transpose+flip(-1)=180
    elif rotflag != 0:  # if not 0,1,2,3
        raise Exception("Unknown rotation flag({})".format(rotflag))
    return img
于 2016-09-26T09:54:41.140 に答える
0

パイソンでは:

# import the necessary packages
import numpy as np
import cv2

# initialize the camera and grab a reference to the raw camera capture
vs = cv2.VideoCapture(0)
(ret, image_original) = vs.read()
image_rotated_90 = np.rot90(image_original)
image_rotated_180 = np.rot90(image_rotated_90)

# show the frame and press any key to quit the image frame
cv2.imshow("Frame", image_rotated_180)
cv2.waitKey(0)
于 2017-11-06T21:31:14.920 に答える