slit scanning frame buffer

hi,

im trying to port one of my old slit-scanning processing experiments into openframeworks. its working, but very slow, slower then in processing in fact… so need to work out the correct way of doing things in openframeworks.

the break down ::
im adding each frame as an array of pixels into a frame buffer with a maximum frame limit of say 200, so it stores the last 200 frames. when a new frame comes in and i have to shift each frame in the frame buffer by one to make room for the new frame… it chokes, works but painfully slow.

i know the problem is that im using a single frameBuffer array to store all the pixels and have to shift all the values in the array everytime a new frame comes in creating a huge overhead.

anyone know the optimum / alternative way of doing this?

here is my code if it helps,

void testApp::setup(){

// camWidth = 640;
// camHeight = 480;

camWidth = 160;
camHeight = 120;

frameBufferLimit = camWidth;

vidGrabber.setVerbose( true );
vidGrabber.initGrabber( camWidth, camHeight );

outputTexture.allocate( camWidth, camHeight, GL_RGB );

outputPixels = new unsigned char[ camWidth * camHeight * 3 ];
frameBuffer = new unsigned char[ camWidth * camHeight * 3 * frameBufferLimit ];
}

//--------------------------------------------------------------
void testApp :: update()
{

ofBackground( 100, 100, 100 );

vidGrabber.grabFrame();

if( vidGrabber.isFrameNew() )
{
updateFrameBuffer();
updateOutputPixels();
}
}

void testApp :: updateFrameBuffer()
{
unsigned char * vidPixels = vidGrabber.getPixels();
int totalPixelsPerFrame;
int i;
int j;
int p1;
int p2;

totalPixelsPerFrame = camWidth * camHeight * 3;

if( frameBufferCount < frameBufferLimit ) // add frames to frameBuffer until the buffer is full.
{
for( i=0; i<totalPixelsPerFrame; i++ )
{
frameBuffer[ ( frameBufferCount * totalPixelsPerFrame ) + i ] = vidPixels[ i ];
}

++frameBufferCount;
}
else
{
for( i=frameBufferLimit-1; i>0; i-- ) // move each frame up in the frameBuffer.
{
for( j=0; j<totalPixelsPerFrame; j++ )
{
p1 = i * totalPixelsPerFrame + j;
p2 = ( i - 1 ) * totalPixelsPerFrame + j;

frameBuffer[ p1 ] = frameBuffer[ p2 ];
}
}

for( i=0; i<totalPixelsPerFrame; i++ ) // add new frame to start of buffer.
{
frameBuffer[ i ] = vidPixels[ i ];
}
}
}

void testApp :: updateOutputPixels ()
{
int totalPixels;
int x;
int y;
int i;
int p1;
int p2;

totalPixels = camWidth * camHeight * 3;

unsigned char * vidPixels = vidGrabber.getPixels();

for( y=0; y<camHeight; y++ )
{
for( x=0; x<camWidth; x++ )
{
for( i=0; i<3; i++ )
{
p1 = y * ( camWidth * 3 ) + x * 3 + i;
p2 = y * ( camWidth * 3 ) + x * 3 + i + ( totalPixels * x );

if( x < frameBufferCount )
{
outputPixels[ p1 ] = frameBuffer[ p2 ];
}
else
{
outputPixels[ p1 ] = vidPixels[ p1 ];
}
}
}
}

outputTexture.loadData( outputPixels, camWidth, camHeight, GL_RGB );
}

//--------------------------------------------------------------
void testApp::draw()
{
ofSetColor( 0xffffff );
vidGrabber.draw( 20, 20 );
outputTexture.draw( 20 + camWidth, 20 , camWidth, camHeight );
}

is it possible to store / retrieve pixel data in OfTexture or OfImage?

rather than copying everything over by one slot and always inserting at the start, you can use what’s called a ‘circular-buffer’ or a ‘ring buffer’: have an array of say 200 ofImages, and an int current_index, initialised to 0. for each incoming frame, write it into current_index, then bump up current_index by 1. to render in order, start at current_index and go upwards through the array, wrapping round to 0 when you reach the end, and stopping when you get to current_index-1.

genius!
going to try it now.

also jesus gollonet, did a slit scan some time ago, perhaps you want to have a look:

http://www.openframeworks.cc/forum/view-…-t=slitscan

yeah nice, thx guys.
got it working with the circular buffer… running great now.

thx for sharing that link arturo, wil check out the code and compare.

You could also just use a linked list or vector, and just add the new frame to the head… much simpler than shifting all the elements in an array around.

hey I just added a slightly reworked version to the thread that arturo posted. just make sure to get the last one!

best,
jesús.