The jonki

呼ばれて飛び出てじょじょじょじょーんき

OpenCVでカメラのRGB画像を90度回転する

OpenCVでカメラ画像を90度回転してみました。OpenCVの便利関数を使えばすぐですが、あえてそれに頼らない方法も書いてみました。CWが右回転、CCWが左回転です。90度であれば回転行列は不要です。1画素はRGBで3つ分のunsigned charなのでそこがちょっと注意ですね。

参考にしたページ

#include <iostream>
#include "opencv2/opencv.hpp"


// 右回転
// ref. http://stackoverflow.com/questions/21550903/rotate-pixel-array-90-degrees-in-c
void rotateCW90(unsigned char *buffer, const unsigned int width, const unsigned int height)
{
    const unsigned int sizeBuffer = width * height * 3; 
    unsigned char *tempBuffer = new unsigned char[sizeBuffer];

    for (int y = 0, destinationColumn = height - 1; y < height; ++y, --destinationColumn)
    {
        int offset = y * width;

        for (int x = 0; x < width; x++)
        {
            for (int i = 0; i < 3; i++) { // RGB
                tempBuffer[(x * height + destinationColumn) * 3 + i] = buffer[(offset + x) * 3 + i];
            }
        }
    }

    memcpy(buffer, tempBuffer, sizeBuffer);
    delete[] tempBuffer;
}

// 左回転
void rotateCCW90(unsigned char *buffer, const unsigned int width, const unsigned int height)
{
    const unsigned int sizeBuffer = width * height * 3; 
    unsigned char *tempBuffer = new unsigned char[sizeBuffer];

    for (int y = 0, destinationColumn = 0; y < height; ++y, ++destinationColumn)
    {
        int offset = y * width;

        for (int x = 0; x < width; x++)
        {
            for (int i = 0; i < 3; i++) { // RGB
                tempBuffer[((width - x - 1) * height + destinationColumn) * 3 + i] = buffer[(offset + x) * 3 + i];
            }
        }
    }

    memcpy(buffer, tempBuffer, sizeBuffer);
    delete[] tempBuffer;
}

int main()
{
    cv::VideoCapture cap(0);
    const int W = 640;
    const int H = 480;
    cv::Mat srcFrame;
    cv::Mat dstFrame = cv::Mat::zeros(W, H, CV_8UC3); //RGB (符号なしの8ビット整数(CV_8U) 3つ分)
    
    cap.set(CV_CAP_PROP_FRAME_WIDTH, W);
    cap.set(CV_CAP_PROP_FRAME_HEIGHT, H);
    
    unsigned char *pImg;
    
    while (cv::waitKey(1)!='q') {
        cap >> srcFrame;
        
        // 自前で回転
        pImg = srcFrame.data;
        rotateCCW90(pImg, W, H);
        dstFrame.data = pImg;
        
        // opencvの便利関数で回転
//        cv::transpose(srcFrame, dstFrame);
//        cv::flip(dstFrame, srcFrame, 0);
        
        imshow("rotation", dstFrame);
    }
    
    return 0;
}
結果

f:id:jonki:20140913015109p:plain