C/C++ to Python help
As some of you know I'm working on face detection, and I need some code help.
I don't know any C or C++ and need to know whats going on here:
bgrdata = bi->GetImg();
graydata = new unsigned char[w*h];
for (i=0; i<w*h; i++)
{
graydata[i] = (unsigned char) ((.11*bgrdata[3*i] + .59*bgrdata[3*i+1] + .3*bgrdata[3*i+2]));
}
I'm not asking for any one to write the code for me, I just need to know what exactly this does and maybe what graydata would look like after it has been run through the for statement.
My goal is to port this to python so I can use a dll I found online for face detection.
I'll try my best to explain this. I have a pretty good understanding of C++ so here goes.
bgrdata is equal too the class bi's child named getImg(); so basically whenever you call bgrdata it will call getImg();
graydata = new unsigned char[w*h];
that means graydata is equal to a character with the array number of w times h. (sorry, i don't quite understand what unsigned means)
the for statements says for the time i < w*h then execute this.
graydata[i] = (unsigned char) ((.11bgrdata[3i] + .59bgrdata[3i+1] + .3bgrdata[3i+2]));
graydata[i] is accessing the array "i" of graydata. The (unsigned char) casts everything as an unsigned char regardless of what it is. This is so it will work with graydata[i]. The rest of it is mathematical calculations. Anything between the [] is an array of the variable. So bgrdata[3i] is 3i. Say i = 5. bgrdata[3*5] = bgrdata[15]-1; -1 because every array in C++ starts at 0 and not one. I hoped i helped, i like what your doing. If i can help in any other way pm me.
"Unsigned" as a keyword means that there are no bits dedicated to the sign of a number, they can't be negative, in other words. However, with that recovered bit, they can be larger.
http://en.wikipedia.org/wiki/Signedness
Also some good links on there about how things can be represented as negative (2's complement etc).
imask8erhack wrote: I'll try my best to explain this. I have a pretty good understanding of C++ so here goes.
bgrdata is equal too the class bi's child named getImg(); so basically whenever you call bgrdata it will call getImg();
Apparently not, because that's wrong. Firstly, bi is not a class; bi is a variable that stores a pointer to an object of currently unknown class type for us. There is also no… child. What it does is dereference the pointer so that you get the object and then call the function GetImg() from it and subsequently assigns the returned value to bgrdata. That code is the equivalent of this:
markupbgrdata = (*bi).GetImg();
GetImg() will not be called every single time you call bgrdata because all bgrdata contains after it is whatever value GetImg() returned to it. So unless bgrdata is a typedef of the type GetImg() is and it returns a pointer to itself, I highly doubt that that'd happen. Plus that it's a class' function which works slightly differently anyhow, so no, it will not be called.
markupgraydata = new unsigned char[w*h];
Now, this just means that graydata will be an array of unsigned char type on the heap of size w*h. They are presumably using unsigned for purposes of not having any accidental mishaps with calculations performed on those variables.
The rest of the code is really very self explanatory. So techb, you might want to think twice about that PM anyhow.
Okay, I'm starting to get a hang of python's ctypes.
unsigned char is a string right? Or at least will be.
If it is going to be a string how come there are mathematical operators on it
eg markupgraydata[i] = (unsigned char) ((.11*bgrdata[3*i] + .59*bgrdata[3*i+1] + .3*bgrdata[3*i+2]))
I know the contents of bgrdata are and its not strings.
here is the complete sample code i want to port to python, so you know the datatypes and classes i;m working with
#include "windows.h"
#include "loadbmp.h" // from http://gpwiki.org/index.php/LoadBMPCpp
#include "fdlib.h"
void main(int argc, char *argv[])
{
int i, n, x[256], y[256], size[256], w, h, threshold;
BMPImg *bi;
unsigned char *bgrdata, *graydata;
if (argc==1)
{
printf("usage: fdtest bmpfilename [threshold]\n");
exit(0);
}
bi = new BMPImg();
printf("\nloading %s\n", argv[1]);
bi->Load(argv[1]);
w = bi->GetWidth();
h = bi->GetHeight();
printf("image is %dx%d pixels\n", w, h);
bgrdata = bi->GetImg();
graydata = new unsigned char[w*h];
for (i=0; i<w*h; i++)
{
graydata[i] = (unsigned char) ((.11*bgrdata[3*i] + .59*bgrdata[3*i+1] + .3*bgrdata[3*i+2]));
//if (i<10) printf("%d ", graydata[i]);
}
threshold = argc>2 ? atoi(argv[2]) : 0;
printf("detecting with threshold = %d\n", threshold);
fdlib_detectfaces(graydata, w, h, threshold);
n = fdlib_getndetections();
if (n==1)
printf("%d face found\n", n);
else
printf("%d faces found\n", n);
for (i=0; i<n; i++)
{
fdlib_getdetection(i, x+i, y+i, size+i);
printf("x:%d y:%d size:%d\n", x[i], y[i], size[i]);
}
delete[] graydata;
delete bi;
}
Oh and is there a way, or option to notify me via email when a reply is made on a post? I can't seem to find one.
techb wrote: Okay, I'm starting to get a hang of python's ctypes. unsigned char is a string right? Or at least will be. If it is going to be a string how come there are mathematical operators on it String is a high level concept and not a base type, individual parts are not strings, learn how it works. But, yes, you could say that it will be a string… if you want it to be one, or want to call it that. There are mathematical operators on it because a char is basically just like an int, except smaller. So if you don't need the size of an int, might as well use chars. But really, stop thinking of string as one entity or a base type or somesuch, it's not good for you.
techb wrote: Oh and is there a way, or option to notify me via email when a reply is made on a post? I can't seem to find one. You mean, here on hbh or…?
Turns out the only thing wrong with my ctypes array was i was passing the actual array to the fdlib_detectfaces() function, instead of a pointer.
fd.fdlib_detectfaces(byref(graydata), w, h, threshold)
and I used the wrong function to call the dll in my case this is the proper way:
fd = cdll.LoadLibrary('fdlib.dll')
#instead of
fd = windll.LoadLibrary('fdlib.dll')
"…ctypes pushed 4 bytes of argument onto the stack which weren't popped off by the caller."
"If you were using windll when you should have been using cdll then ctypes will have been expecting the library to clean up the stack, and the library will have been expecting the caller to do the cleanup…"
More details on the array conversion and substituting the graydata for PIL. im.convert("L") to be specific. http://www.daniweb.com/forums/thread265466.html
Cited: