Welcome Guest ( Log In | Register )


Important

The forums will be closing permanently the weekend of March 15th. Please see the notice in the announcements forum for details.

 
Filter - Separate Rgb Arrays, howto separate RGB array and manipulate?
« Next Oldest | Next Newest » Track this topic | Email this topic | Print this topic
mancanfly
Posted: Mar 26 2003, 02:58 AM


Unregistered









Hello,

I am interested in developing a filter for Virtual Dub and would need some help from developers. Actually the filter has already been developed for images and I want to extend it to videos.

The following is written in 'filtsdk-1_05\Filtsdk\docs\crashcourse.html' (the filter SDK provided on VirtualDub website)-

"...This generally means that if you need to do any arithmetic on a pixel, such as averaging several together, you will need to either unpack the pixels into triplets to get more range or mask off bits to reduce precision. The latter generally leads to poor results, so you will want to unpack pixels."

To begin with, I would like to do a simple operation (in the same format and not through masking) as:

for(i=0;i<w;i++) //assign destination the modified RGBs.
{
for(j=0;j<h;j++)
{
dst[count++] = IpixelR[i][j];
dst[count++] = IpixelG[i][j]/2;
dst[count++] = IpixelB[i][j]/3;
}
}

and not as:

do {
w = fa->src.w;

do {
Pixel32 old_pixel, new_pixel;

old_pixel = *src++;

new_pixel = (old_pixel & 0xFF0000) + ((old_pixel & 0x00FF00)>>1) + 0x0000FF;

*dst++ = new_pixel;
} while(--w);

src = (Pixel32 *)((char *)src + fa->src.modulo);
dst = (Pixel32 *)((char *)dst + fa->dst.modulo);
} while(--h);

Can somebody suggest me the required changes in the example given in 'filtsdk-1_05\Filtsdk\docs\tutorial_maincode.html' to achieve this?

waiting for a reply.[B][/B]
 
  Top
fccHandler
Posted: Mar 26 2003, 03:27 AM


Administrator n00b


Group: Moderators
Posts: 3961
Member No.: 280
Joined: 13-September 02



I don't really understand your question, but I think what the SDK is saying is that it's better to split the pixel into its R/G/B components and do the math on the components, rather than on the pixel as a whole:

CODE
int r,g,b;

/* Unpack red, green, and blue */
r = (old_pixel >> 16) & 0xFF;
g = (old_pixel >> 8) & 0xFF;
b = old_pixel & 0xFF;

/* Do some math with r, g, and b... */
g = g / 2;
b = b / 3;

/* Clamp the results if necessary */
if (r < 0) r = 0; else if (r > 255) r = 255;
if (g < 0) g = 0; else if (g > 255) g = 255;
if (b < 0) b = 0; else if (b > 255) b = 255;

/* Pack into new pixel */
new_pixel = (r << 16) + (g << 8) + b;


Does this help you at all?

--------------------
May the FOURCC be with you...
 
     Top
mancanfly
Posted: Mar 28 2003, 02:41 AM


Unregistered









actually what i am interested in is processing a 2D array (of the form PixelR[i][j], PixelG[i][j], PixelB[i][j]) of different pixels instead of handling individual RGBs (in a scanline).

How can I store the RGB components of the frame in a 2D array? Consider the 2D array being created as follows:
_______________________________________________
//Allocation of R,G,B components of Input Image begins...
float **IpixelR, **IpixelG, **IpixelB;

IpixelR = (float **)malloc((fa->src.w)*sizeof(float *));
IpixelG = (float **)malloc((fa->src.w)*sizeof(float *));
IpixelB = (float **)malloc((fa->src.w)*sizeof(float *));

for(j=0;j<(fa->src.h);j++)
{
IpixelR[j] = (float *)malloc((fa->src.w)*sizeof(float));
IpixelG[j] = (float *)malloc((fa->src.w)*sizeof(float));
IpixelB[j] = (float *)malloc((fa->src.w)*sizeof(float));
}
_______________________________________________

And consider what you suggested in the following loop:

h = fa->src.h;

for (i=h; i>0; i--)
{
w = fa->src.w;
for (j=w; j>0; j--)
{
Pixel32 old_pixel, new_pixel;

old_pixel = *src++;

int r,g,b, l;

//Unpack red, green, and blue
//IpixelR[j][i] =
r = (old_pixel >> 16) & 0xFF;
//IpixelG[j][i] =
g = (old_pixel >> 8) & 0xFF;
//IpixelB[j][i] =
b = old_pixel & 0xFF;

//Do some math with r, g, and b...
g = g / 2;
b = b / 3;

//Clamp the results if necessary
if (r < 0) r = 0; else if (r > 255) r = 255;
if (g < 0) g = 0; else if (g > 255) g = 255;
if (b < 0) b = 0; else if (b > 255) b = 255;

//Pack into new pixel
new_pixel = (r << 16) + (g << 8) + b;

*dst++ = new_pixel;
}

src = (Pixel32 *)((char *)src + fa->src.modulo);
dst = (Pixel32 *)((char *)dst + fa->dst.modulo);
}

thanks for you earlier reply!
 
  Top
fccHandler
Posted: Mar 28 2003, 03:38 AM


Administrator n00b


Group: Moderators
Posts: 3961
Member No.: 280
Joined: 13-September 02



I still don't completely understand, but it sounds like what you want is a planar image of floats, however, VirtualDub's internal storage is packed bytes. It's still possible to convert from one to the other for your processing, but it won't be terribly efficient:

CODE
// Allocate your arrays
// ...

// Convert source to planar format
int i,j;
Pixel32 *src = fa->src.data;
for (j = 0; j < fa->src.h; j++) {
   for (i = 0; i < fa->src.w; i++) {
       Pixel32 p = *src++;
       IPixelR[i][j] = (p >> 16) & 0xFF;
       IPixelG[i][j] = (p >> 8) & 0xFF;
       IPixelB[i][j] = p & 0xFF;
   }
   src = (Pixel32 *)((char)src + fa->src.modulo);
}

// Do some stuff with the planar image
// ...

// Write to destination in packed format
int r,g,b;
Pixel32 *dst = fa->dst.data;
for (j = 0; j < fa->dst.h; j++) {
   for (i = 0; i < fa->dst.w; i++) {
       r = (int)IPixelR[i][j];
       g = (int)IPixelG[i][j];
       b = (int)IPixelB[i][j];
       if (r < 0) r = 0; else if (r > 255) r = 255;
       if (g < 0) g = 0; else if (g > 255) g = 255;
       if (b < 0) b = 0; else if (b > 255) b = 255;
       *dst++ = (Pixel32)((r << 16) + (g << 8) + b);
   }
   dst = (Pixel32 *)((char)dst + fa->dst.modulo);
}

// Deallocate your arrays
// ...


I didn't test the code but it should work (if I haven't make any typos). tongue.gif
Also, it's better to alloc/dealloc in StartProc/EndProc.



--------------------
May the FOURCC be with you...
 
     Top
mancanfly
Posted: Mar 29 2003, 07:26 PM


Unregistered









This thing is really confusing me.. Now where is the mistake?? On debugging I get error in the line where comments are in UPPERCASE (where I assign the src values to IpixelR[i][j], IpixelG[i][j], IpixelB[i][j].
________________________________________________________

int i,j, count;
//Allocation of R,G,B components of Input Image begins...
float **IpixelR, **IpixelG, **IpixelB;

IpixelR = (float **)malloc((fa->src.h)*sizeof(float *));
IpixelG = (float **)malloc((fa->src.h)*sizeof(float *));
IpixelB = (float **)malloc((fa->src.h)*sizeof(float *));

for(j=0;j<(fa->src.h);j++)
{
IpixelR[j] = (float *)malloc((fa->src.w)*sizeof(float));
IpixelG[j] = (float *)malloc((fa->src.w)*sizeof(float));
IpixelB[j] = (float *)malloc((fa->src.w)*sizeof(float));
}

// Convert source to planar format
for (j = 0; j < fa->src.h; j++)
{
for (i = 0; i < fa->src.w; i++)
{
Pixel32 p = *src++;
IpixelR[i][j] = (p >> 16) & 0xFF; //ERROR ON DEBUGGING
IpixelG[i][j] = (p >> 8) & 0xFF;
IpixelB[i][j] = p & 0xFF;
}
src = (Pixel32 *)((char)src + fa->src.modulo);
}

// Write to destination in packed format
int r,g,b;
for (j = 0; j < fa->src.h; j++)
{
for (i = 0; i < fa->src.w; i++)
{
r = (int)IpixelR[i][j];
g = (int)IpixelG[i][j];
b = (int)IpixelB[i][j];
if (r < 0) r = 0; else if (r > 255) r = 255;
if (g < 0) g = 0; else if (g > 255) g = 255;
if (b < 0) b = 0; else if (b > 255) b = 255;
*dst++ = (Pixel32)((r << 16) + (g << 8) +b);
}
dst = (Pixel32 *)((char)dst + fa->dst.modulo);
}

// Deallocate arrays
// ...
_____________________________________

The error message says that:
AVIAudioPreviewOutputStream: flushing...
First-chance exception in VirtualDub.exe: 0xC0000005: Access Violation.
 
  Top
phaeron
Posted: Mar 29 2003, 08:42 PM


Virtualdub Developer


Group: Administrator
Posts: 7773
Member No.: 61
Joined: 30-July 02



Your arrays are allocated [y][x] but you are accessing them [x][y].
 
    Top
fccHandler
Posted: Mar 29 2003, 08:58 PM


Administrator n00b


Group: Moderators
Posts: 3961
Member No.: 280
Joined: 13-September 02



ph34r.gif Doh! I didn't look closely enough at your allocation strategy, sorry. (Thanks phaeron!)

It should be:
CODE
//Allocation of R,G,B components of Input Image begins...
float **IpixelR, **IpixelG, **IpixelB;

IpixelR = (float **)malloc((fa->src.w)*sizeof(float *));
IpixelG = (float **)malloc((fa->src.w)*sizeof(float *));
IpixelB = (float **)malloc((fa->src.w)*sizeof(float *));

for(i=0;i<(fa->src.w);i++) {
   IpixelR[i] = (float *)malloc((fa->src.h)*sizeof(float));
   IpixelG[i] = (float *)malloc((fa->src.h)*sizeof(float));
   IpixelB[i] = (float *)malloc((fa->src.h)*sizeof(float));
}


Don't forget to deallocate:
CODE
//Deallocate arrays...
for(i=(fa->src.w)-1;i>=0;i--) {
   free(IpixelB[i]);
   free(IpixelG[i]);
   free(IpixelR[i]);
}
free(IpixelB);
free(IpixelG);
free(IpixelR);


smile.gif

--------------------
May the FOURCC be with you...
 
     Top
mancanfly
Posted: Mar 30 2003, 09:05 PM


Unregistered









Seems FOURCC is not with me! Can you just create a .cpp file (say, test_filter.cpp) and test the following code for me? Now the error line is the one where the src pointer is being equated to the Pixel32 variable 'p'.
I truly appreciate your patience. Though it has to be something trivial, but this step has become so critical that I simply can't proceed with my work any further without it getting completed. Actually I intend to do some matrix operations on the frame array hence obtained.
_____________________________________________
#include <stdio.h>

#include "filter.h"
#include "filters.h"
#include "f_convolute.h"
#include "ScriptInterpreter.h"
#include "ScriptValue.h"
#include "ScriptError.h"


int tutorialRunProc(const FilterActivation *fa, const FilterFunctions *ff)
{
PixDim w, h;
Pixel32 *src, *dst;

src = (Pixel32 *)fa->src.data;
dst = (Pixel32 *)fa->dst.data;

int i,j, count;
//Allocation of R,G,B components of Input Image begins...
float **IpixelR, **IpixelG, **IpixelB;

IpixelR = (float **)malloc((fa->src.w)*sizeof(float *));
IpixelG = (float **)malloc((fa->src.w)*sizeof(float *));
IpixelB = (float **)malloc((fa->src.w)*sizeof(float *));

for(j=0;j<(fa->src.w);j++)
{
IpixelR[j] = (float *)malloc((fa->src.h)*sizeof(float));
IpixelG[j] = (float *)malloc((fa->src.h)*sizeof(float));
IpixelB[j] = (float *)malloc((fa->src.h)*sizeof(float));
}

///////////
// Convert source to planar format
for (j = 0; j < fa->src.h; j++)
{
for (i = 0; i < fa->src.w; i++)
{
Pixel32 p = (Pixel32) *src++; // <-- ERROR ON DEBUGGING
IpixelR[i][j] = (p >> 16) & 0xFF;
IpixelG[i][j] = (p >> 8) & 0xFF;
IpixelB[i][j] = p & 0xFF;
}
src = (Pixel32 *)((char)src + fa->src.modulo);
}

///////////

//
// Do some stuff with the planar image
//

///////////
// Write to destination in packed format
int r,g,b;
for (j = 0; j < fa->src.h; j++)
{
for (i = 0; i < fa->src.w; i++)
{
r = (int)IpixelR[i][j];
g = (int)IpixelG[i][j]/2;
b = (int)IpixelB[i][j]/3;
if (r < 0) r = 0; else if (r > 255) r = 255;
if (g < 0) g = 0; else if (g > 255) g = 255;
if (b < 0) b = 0; else if (b > 255) b = 255;
*dst++ = (Pixel32)((r << 16) + (g << 8) + b);
}
dst = (Pixel32 *)((char)dst + fa->dst.modulo);
}

//free allocated memory
for(i=(fa->src.w)-1;i>=0;i--)
{
free(IpixelR[i]);
free(IpixelG[i]);
free(IpixelB[i]);
}
free(IpixelR);
free(IpixelG);
free(IpixelB);

return 0;
}

struct FilterDefinition filterDef_tutorial = {

NULL, NULL, NULL, // next, prev, module
"tutorial", // name
"This is a test filter.",
// desc
"test", // maker
NULL, // private_data
0, // inst_data_size

NULL, // initProc
NULL, // deinitProc
tutorialRunProc, // runProc
NULL, // paramProc
NULL, // configProc
NULL, // stringProc
NULL, // startProc
NULL, // endProc

NULL, // script_obj
NULL, // fssProc

};
_____________________________________________

 
  Top
phaeron
Posted: Mar 30 2003, 09:53 PM


Virtualdub Developer


Group: Administrator
Posts: 7773
Member No.: 61
Joined: 30-July 02



src = (Pixel32 *)((char)src + fa->src.modulo);

That should be (char *).
 
    Top
fccHandler
Posted: Mar 31 2003, 05:50 AM


Administrator n00b


Group: Moderators
Posts: 3961
Member No.: 280
Joined: 13-September 02



mad.gif That darn typo devil strikes again!

For sure, next time I will test any code before I post it. rolleyes.gif

--------------------
May the FOURCC be with you...
 
     Top
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:
9 replies since Mar 26 2003, 02:58 AM Track this topic | Email this topic | Print this topic

<< Back to VirtualDub Filters and Filter Development