Cocos2d-x에서 OpenCV를 사용하고 싶었지만 ...

16362 단어 cocos2d-xOpenCV
이번에는 OpenCV를 cocos2d-x로 사용하려고 생각했지만 좋지 않았다는 이야기입니다.
전회에 이어 cocos2d-x를 만지고 있었습니다만, 동영상 재생용의 노드가 cocos2d-x가 아닌 것 같네요.

그래서 저의 특기 분야인 OpenCV를 사용하여 동영상 파일에서 Sprite의 리스트를 작성해 애니메이션 시키려고 생각해 구현해 보았습니다.

VideoNode.h
#import <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <2d/CCAnimation.h>


class VideoNode
{
public:
    static VideoNode* create();
    void initWithFile(const std::string &fileName);
    void play(bool repeat);
    cocos2d::Sprite* getSprite(){
        return this->sprite;
    }
private:
    void splitMovie(const std::string fileName, std::vector<cv::Mat> &mVec);
    void cvMat2ccImage(cv::Mat &src, cocos2d::Image &dst);
    cocos2d::Sprite* sprite;
    cocos2d::Animate *action;
};

실장 부분은

VideoNode.cpp

#include "VideoNode.h"


VideoNode* VideoNode::create()
{
    VideoNode* node = new (std::nothrow)VideoNode();

    return node;
}

void VideoNode::initWithFile(const std::string &fileName)
{
    //MP4のfileNameから画像バッファを取得

    std::vector<cv::Mat> images;
    splitMovie(fileName, images);

//    //アニメーションクラスの作成
    auto animation = cocos2d::Animation::create();
//    
//    //ループでアニメーションクラスにaddSpriteFrameしていく
//    
    for (int i=0; i < images.size(); i++) {
        //newで動的にImage分のメモリを確保
        cocos2d::Image *img = new cocos2d::Image();
        cv::Mat m = images[i];
        //確保したimgのアドレスの中身を渡す。
        cvMat2ccImage(m, *img);

        cocos2d::Texture2D *tex = new cocos2d::Texture2D();
        tex->initWithImage(img);
        auto rect = new cocos2d::Rect();
        rect->setRect(0, 0, img->getWidth(), img->getHeight());
        cocos2d::SpriteFrame *frame = cocos2d::SpriteFrame::createWithTexture(tex, *rect);
        if(i==0){
            cocos2d::Sprite *sprite = cocos2d::Sprite::createWithSpriteFrame(frame);
            sprite->setName("animSprite");
            this->sprite = sprite;
        }
        animation->addSpriteFrame(frame);
   }
    action = cocos2d::Animate::create(animation);

}

void VideoNode::play(bool repeat)
{
    auto anime = cocos2d::RepeatForever::create(action);
    this->sprite->runAction(anime);
}

//cvMatからcocos2d::Imageに変換するメソッド
void VideoNode::cvMat2ccImage(cv::Mat &src, cocos2d::Image &dst)
{
    unsigned char *srcData;
    int width = src.cols;
    int height = src.rows;


    srcData = (unsigned char *)src.data;
    unsigned long size = 3 * width * height;
    dst.initWithRawData(srcData, size, width, height, 24);
}

//映像からcv::Matのデータ群を取得するメソッド
void VideoNode::splitMovie(const std::string fileName, std::vector<cv::Mat> &mVec)
{
    CvCapture *capture = cvCreateFileCapture(fileName.c_str());
    if(!capture)
    {
        std::cerr << "cvCreateFileCapure filed" << std::endl;
    }

    int rows = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
    int cols = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);


    IplImage *frame =NULL;
    cv::Mat m(rows, cols, CV_8UC3);

    while ((frame=cvQueryFrame(capture))!=NULL) {
        m = cv::cvarrToMat(frame);
        mVec.push_back(m);
    }
}

같은 느낌으로 구현해 보았습니다. 이것으로 갈 수 있다! 나는 생각했다.



왜, 아무것도 표시되지 않습니다! ?

콘솔을 보면 뭔가 warning이 나온다.

jpeg error: Wrong JPEG library version: library is 62, caller expects 90
size=0

라든지,

libpng warning: Application built with libpng-1.6.16 but running with 1.5.12

어쨌든 ....

아무래도 조사해 보면 OpenCV에서는 빌드시에 libpng 1.5.12 사용하고, cocos2d-x는 libpng 1.6.16 사용하고 있는 것이 원인인 것 같다.

하지만 iOS 용으로 OpenCV 빌드를 다시하면 갈 수 있을까? 라고 생각했지만 libpng와 libjpeg 어떻게 지정하면 좋은지 모르고 결국 할 수 없어.

되었습니다.

누군가 좋은 해결책이 있으면 꼭 알려주세요.

2015.6.14 추가
해결책과 코드를 수정한 것 정리했으므로
여기 을 참조하십시오.

좋은 웹페이지 즐겨찾기