ofVideoPlayer to ofxCvColorImage

Hi, so basically what I’m trying to do is to get frames (with if statements to check the new frames and get pixel data from them) from a desired video with ofVideoPlayer, and then convert it to ofxCvColorImage and updating it with every new frame. But I just couldn’t make it happen.

What I actually need is to add blur(ofxCv has some great ones) to a video.

share more details or code so others can understand better

yes sorry for the lack of detail, the code follows as;

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup() {
    
    cvVideo.allocate(2880, 720);
    ofSetFrameRate(30);
    

    ofVideo.load("beribak/ubahn.mp4");
    ofVideo.setLoopState(OF_LOOP_NORMAL);
    ofVideo.setVolume(0.3);
    
    
    }

//--------------------------------------------------------------
void ofApp::update() {
    
    ofBackground(20, 20, 20);
    
    ofVideo.play();

    if (ofVideo.isFrameNew()){
        cvVideo.setFromPixels(ofVideo.getPixels());
    }
}

//--------------------------------------------------------------
void ofApp::draw() {
    
    
if (ofVideo.isFrameNew()){
    cvVideo.setFromPixels(ofVideo.getPixels());
    cvVideo.draw(0, 0);
  }
}

//--------------------------------------------------------------
void ofApp::exit() {
}

header;

    ofVideoPlayer ofVideo;
    ofxCvColorImage cvVideo;

the logic is to get every new frame from the ofVideo via setFromPixels(), and then update the cvVideo accordingly. Then I think I will be able to add ofxcv’s blur to a video. I’m very rookie at coding, so any help is welcome.

try calling ofVideo.play once in setup
and in update ofVideo.update, before getPixels. not sure if it will work

Hey @Fiktug , yes definitely try dimitre’s suggestion. Also, I’d try rearranging a bit:

void ofApp::setup() {
    ofBackground(20, 20, 20);
    cvVideo.allocate(2880, 720);
    ofSetFrameRate(30);
    ofVideo.load("beribak/ubahn.mp4");
    ofVideo.setLoopState(OF_LOOP_NORMAL);
    ofVideo.setVolume(0.3);
    ofVideo.play(); // start the player
    }
//--------------------------------------------------------------
void ofApp::update() {
    // update the player before checking for new frames
    ofVideo.update();
    if (ofVideo.isFrameNew()){
        cvVideo.setFromPixels(ofVideo.getPixels());
    }
}
//--------------------------------------------------------------
void ofApp::draw() {
    cvVideo.draw(0, 0);
}

Have a look at the /computer_vision/opencvExample , which is similar for how a video player is used to set an ofxCvColorImage for some further openCV stuff.

If the openCV blur is too slow, try using a shader to blur the ofTexture of the video player.

Thank you to both of you! Code works! May I request more detail on blur shaders? My Macbook air 17 having a hard time processing all those frames.

2 Likes

Hey @Fiktug , I adapted a blur shader from Adam Ferriss, which you can find on his GitHub page. And then the /examples/shaders/ folder has lots of shader examples that go along with the ofBook chapter on them.

Shader are super helpful and they’re really a fun part of oF! The gpu is really fast at processing images.

Smaller images will blur faster on the cpu. So you could also try bluring a smaller image from the video player, and then draw the image to whatever size you like by passing 4 floats (x, y, w, h) to ofxCvImage::draw(). Drawing the video player into an ofFbo might be a quick way to resize it, as opposed to resizing the pixels on the cpu.

in psudeo-code:

// in ofApp.h
    ofFbo fbo;
    ofVideoPlayer player;
    ofxCvColorImage cvImage;

// in ofApp::setup()
    fbo.allocate(600, 450);  // pick a size that runs fast enough,
    cvImage.allocate(600, 450); // and has the right aspect ratio

// in ofApp::update()
    if(player.isFrameNew()){
        fbo.begin();
        ofClear(ofColor(0));
        player.draw(0.f, 0.f, fbo.getWidth(), fbo.getHeight());
        fbo.end();
    }
    // the video player image is now in the fbo and is 600 x 450
    // this should work (?)
    fbo.readToPixels(cvImage.getPixels());
    // blur the cvImage on the cpu

// in ofApp::draw()
    // draw it a bit bigger on the screen
    cvImage.draw(0, 0, 1200, 900);
1 Like