• Jona

    No luck so far with implementing any of the optical flow examples. But I took a look at geometry shaders that seem to create the optical flow arrows: https://github.com/moostrik/ofxFlowTools/blob/master/src/core/visualization/shaders/ftVelocityFieldShader.h
    And I created a simple motion detection patch that works with a shader and could be a start . The patch works with ofelia 3.0 (@cuinjune thanks for the update) and the patches made for ofelia 2.x need to be edited a bit for working with ofelia 3.x : The set from the ofelia object is now __set and pdCanvas / pdClock is now ofCancas / ofClock:
    ofeliaMotionDetection.zip

    posted in technical issues read more
  • Jona

    Here is an example that looks easier to implement (it uses only one shader):
    http://cs.brown.edu/courses/csci1290/2011/results/final/psastras/

    posted in technical issues read more
  • Jona

    Perhaps my question is a bit too general, but I wonder how to implement optical flow with Ofelia.
    I do not know a lot about optical flow, but I looked at some Open Frameworks code and video examples.
    If I understand it right it seems possible to implement it with shaders (without openCV).
    Here is an example that uses a chain of 4 shaders for calculating optical flow. It could be portable to Ofelia:
    https://github.com/princemio/ofxMIOFlowGLSL
    And here is another Open Frameworks addon that creates fluid simulation with optical flow. The results are really great, but for now it seems too complex for me to understand and implement it:

    Does anyone have any suggestions or different Open Frameworks example code for programming optical flow with Ofelia?

    posted in technical issues read more
  • Jona

    Hello :)
    I made three versions of a slitscan patch: A horizontal, a vertical, and a wide vertical Slitscan.
    For me it runs well if the frame buffer size is ~ <= 200.
    Only if the loop starts again there is a short delay (which seems to have to do with the ofVideoPlayer - because of that I rendered a video with 30 seconds of the loop for using it with Ofelia)...
    I still wonder if and how I can optimize the patch.
    Next thing to discover would be optical flow ;)

    Here are the patches: ofelia_slitscan_and_muybridge.zip

    With the Muybridge patch I had the idea tho show the whole sequence of the riding horse sequence at once and in motion:

    posted in patch~ read more
  • Jona

    @Cuinjune thanks for the library. I think it was really a good decision to change the Ofelia concept from version 1 to 2.
    First I was a bit afraid of the scripting, because I was so used to the Pure Data patching style.
    But I think it is much more flexible with the scripting now...

    posted in patch~ read more
  • Jona

    I made a video delay with ofelia. It has 8 delayed frames (the distance between those frames is 1-36), and a frame buffer that stores the recent 300 frames. The frames are blended with a shader.
    At the moment it first needs to fill the buffer before the video is drawn to the screen.
    The frame buffer could be useful for other time based video effects like slit scan too.
    ofeliaVideoDelay.zip
    Here is a test, it can surely be optimized, but that is basically what I had in mind:


    I was inspired by Norman McLarens "Pas de Deux" that makes use of the effect in a perfect way (and it was made without computers).
    The effect has some similarity with my test around minute 9...

    posted in patch~ read more
  • Jona

    i am not sure if it is the best solution, but it works now (with setFromPixels) :) it is a variable framebuffer and the example buffers the last 300 frames from a video.

    frameTable300.pd

    ;
    if type(window) ~= "userdata" then;
    window = ofWindow();
    end;
    ;
    local canvas = pdCanvas(this);
    local clock = pdClock(this, "setup");
    local videoPlayer = ofVideoPlayer();
    local outputList = {};
    local frames = {};
    local images = {};
    local N = 300;
    for i = 1, N do;
    images[i] = ofImage();
    end;
    ;
    function ofelia.new();
    ofWindow.addListener("setup", this);
    ofWindow.addListener("update", this);
    ofWindow.addListener("draw", this);
    ofWindow.addListener("exit", this);
    window:setPosition(50, 100);
    window:setSize(800 + 40, 600 + 40);
    if type(window) ~= "userdata" then;
    window = ofWindow();
    end;
    ;
    window:create();
    if ofWindow.exists then;
    clock:delay(0);
    end;
    end;
    ;
    function ofelia.free();
    window:destroy();
    ofWindow.removeListener("setup", this);
    ofWindow.removeListener("update", this);
    ofWindow.removeListener("draw", this);
    ofWindow.removeListener("exit", this);
    end;
    ;
    function ofelia.setup();
    ofSetWindowTitle("Video Player");
    ofBackground(0, 0, 0, 255);
    end;
    ;
    function ofelia.moviefile(path);
    videoPlayer:load(path);
    videoPlayer:setLoopState(OF_LOOP_NORMAL);
    videoPlayer:setPaused(true);
    end;
    ;
    function ofelia.setSpeed(f);
    videoPlayer:setSpeed(f / 100);
    end;
    ;
    function ofelia.play();
    videoPlayer:play();
    end;
    ;
    function ofelia.stop();
    videoPlayer:setFrame(0);
    videoPlayer:setPaused(true);
    end;
    ;
    function ofelia.setPaused(f);
    if f == 1 then pause = true;
    else pause = false;
    end;
    videoPlayer:setPaused(pause);
    end;
    ;
    function ofelia.setFrame(f);
    videoPlayer:setFrame(f);
    end;
    ;
    function ofelia.setPosition(f);
    videoPlayer:setPosition(f);
    end;
    ;
    function ofelia.setVolume(f);
    videoPlayer:setVolume(f / 100);
    end;
    ;
    local number = 0;
    function ofelia.update();
    videoPlayer:update();
    if videoPlayer:isFrameNew() then;
    number = (number + 1) % N;
    print(number + 1);
    images[number + 1]:setFromPixels(videoPlayer:getPixels());
    table.insert(frames, 1, images[number + 1]);
    if #frames > N then;
    table.remove(frames);
    end;
    end;
    outputList[1] = videoPlayer:getPosition();
    outputList[2] = videoPlayer:getCurrentFrame();
    outputList[3] = videoPlayer:getTotalNumFrames();
    return outputList;
    end;
    ;
    function ofelia.draw();
    videoPlayer:draw(420, 20, 400, 600);
    if #frames == N then;
    frames[ofelia.frame]:draw(20, 20, 400, 600);
    end;
    end;
    ;
    function ofelia.exit();
    videoPlayer:close();
    for i = 1, N do;
    images[i]:clear();
    end;
    end;
    ;
    
    

    posted in technical issues read more
  • Jona

    @Cuinjune perhaps I found a way to copy textures to a table:
    https://forum.openframeworks.cc/t/simply-save-oftexture-from-videograbber/31251

    "the only way to copy a texture into another is using an fbo just create an fbo, draw the video into it and get the internal texture with getTexture

    you could also use ofImage::setFromPixels(cam.getPixels()) which would be slightly slower but avoids creating an fbo (or many if you want to save several frames"

    I think the second method fits better to my case, because I want to save several textures.
    But I have problems with the "setFromPixels()" method:
    attempt to call a nil value (method 'setFromPixels')

    Is it possible that it is a getter function like ofColor::getHsb() that does not work with Ofelia yet?

    posted in technical issues read more
  • Jona

    @Cuinjune I tried to create a video frame table ("circular video buffer").
    It is possible to read (draw) video from the table but somehow only the current frame is stored at every position of the table.
    Here is an example patch. "frames" is the frame table. "N" is the table size. At the left is the texture from the table, at the right the original video. Do you know what I do wrong?
    I also tried ofPixels instead of ofTexture with the same result.
    And I tried to store several images (jpg´s) instead of video to the frame buffer, which does probably work because each image has its own source.

    framearray.pd

    ;
    if type(window) ~= "userdata" then;
    window = ofWindow();
    end;
    ;
    local canvas = pdCanvas(this);
    local clock = pdClock(this, "setup");
    local videoPlayer = ofVideoPlayer();
    local outputList = {};
    local frames = {};
    local N = 150;
    ;
    function ofelia.bang();
    ofWindow.addListener("setup", this);
    ofWindow.addListener("update", this);
    ofWindow.addListener("draw", this);
    ofWindow.addListener("exit", this);
    window:setPosition(50, 100);
    window:setSize(800 + 40, 600 + 40);
    if type(window) ~= "userdata" then;
    window = ofWindow();
    end;
    ;
    window:create();
    if ofWindow.exists then;
    clock:delay(0);
    end;
    end;
    ;
    function ofelia.free();
    window:destroy();
    ofWindow.removeListener("setup", this);
    ofWindow.removeListener("update", this);
    ofWindow.removeListener("draw", this);
    ofWindow.removeListener("exit", this);
    end;
    ;
    function ofelia.setup();
    ofSetWindowTitle("Video Player");
    ofBackground(0, 0, 0, 255);
    end;
    ;
    function ofelia.moviefile(path);
    videoPlayer:load(path);
    videoPlayer:setLoopState(OF_LOOP_NORMAL);
    videoPlayer:setPaused(true);
    end;
    ;
    function ofelia.setSpeed(f);
    videoPlayer:setSpeed(f / 100);
    end;
    ;
    function ofelia.play();
    videoPlayer:play();
    end;
    ;
    function ofelia.stop();
    videoPlayer:setFrame(0);
    videoPlayer:setPaused(true);
    end;
    ;
    function ofelia.setPaused(f);
    if f == 1 then pause = true;
    else pause = false;
    end;
    videoPlayer:setPaused(pause);
    end;
    ;
    function ofelia.setFrame(f);
    videoPlayer:setFrame(f);
    end;
    ;
    function ofelia.setPosition(f);
    videoPlayer:setPosition(f);
    end;
    ;
    function ofelia.setVolume(f);
    videoPlayer:setVolume(f / 100);
    end;
    ;
    function ofelia.update();
    videoPlayer:update();
    if videoPlayer:isFrameNew() then;
    table.insert(frames, 1, videoPlayer:getTexture());
    if #frames > N then;
    table.remove(frames, N + 1);
    end;
    end;
    end;
    ;
    function ofelia.draw();
    videoPlayer:draw(420, 20, 400, 600);
    if #frames == N then;
    frames[ofelia.frame]:draw(20, 20, 400, 600);
    end;
    outputList[1] = videoPlayer:getPosition();
    outputList[2] = videoPlayer:getCurrentFrame();
    outputList[3] = videoPlayer:getTotalNumFrames();
    return outputList;
    end;
    ;
    function ofelia.exit();
    videoPlayer:close();
    end;
    ;
    

    posted in technical issues read more
  • Jona

    @Cuinjune thanks for the clarification. Sometimes I am not sure if I find an unsupported function or if I just use a supported function the wrong way. But I will report when I get stuck and do not find a solution by myself (or with the help from a search engine).

    posted in technical issues read more

Internal error.

Oops! Looks like something went wrong!