Cocos2d-xでOpenCVを使ってみたかったけど.....
今回は、OpenCVをcocos2d-xで使おうと思ったけどダメだったというお話です。
前回に続き、cocos2d-xを触っていたのですが、動画再生用のノードがcocos2d-xってないみたいですね。
そこで、私の得意分野なOpenCVを使って動画ファイルからSpriteのリストを作成してアニメーションさせようと考えて実装してみました。
#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;
};
実装部分は
#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追記
解決法とコードを修正したものまとめましたので
ここを見てください。
Author And Source
この問題について(Cocos2d-xでOpenCVを使ってみたかったけど.....), 我々は、より多くの情報をここで見つけました https://qiita.com/Hare8563/items/bae7ac731535215acd54著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .