[Image-SIG] Dev notes on PIL core
Noah.org
noahspurrier at gmail.com
Tue May 29 18:41:08 CEST 2007
I'm adding a difference_rms(im1, im2) method to ImageChops.
It's fast and works with 1-bit BW, 8-bit gray, and 24-bit color.
I plan to post patches to this group when I'm done testing.
I have gotten only a little bit familiar with the C code. My concern
at this point is the proper way to raise exceptions.
I want to raise an exception if the images are in different modes or
if the sizes do not match (ImagingError_ModeError or ImagingError_Mismatch).
My C function in Chops.c returns a double (the difference RMS value).
Most of the functions in Chops.c return Imaging objects, so
if there is an exception they can easily return an ImagingError.
I want to make my code follow the conventions already being used.
Can anyone suggest the best way to handle raising an exception
from C code that only returns a double?
The heart of the function that I have added to Chops.c looks like this:
double ImagingChopDifferenceRMS(Imaging imIn1, Imaging imIn2)
{
int x, y;
long count, n, ns;
if (!imIn1 || !imIn2 || imIn1->type != IMAGING_TYPE_UINT8 ||
(strcmp(imIn1->mode, imIn2->mode) != 0))
return -1.0; //(Imaging) ImagingError_ModeError();
if (imIn1->type != imIn2->type ||
imIn1->bands != imIn2->bands ||
imIn1->ysize != imIn2->ysize ||
imIn1->xsize != imIn2->xsize)
return -2.0; //(Imaging) ImagingError_Mismatch();
ns = 0;
count = 0;
for (y = 0; y < imIn1->ysize; ++y)
{
UINT8* in1 = (UINT8*) imIn1->image[y];
UINT8* in2 = (UINT8*) imIn2->image[y];
for (x = 0; x < imIn1->linesize; ++x)
{
++count;
n = (long) in1[x] - (long) in2[x];
ns += n*n;
}
}
return sqrt((double)ns / (double)count);
}
Yours,
Noah
P.S. I realize RMS comparisons can be done with PIL and Python alone, but
a C implementation is AT LAST 10 times faster than doing something like this
(the fastest way I could find to do it in Python alone):
h1 = Image.open("im1.jpg").histogram()
h2 = Image.open("im2.jpg").histogram()
rms = math.sqrt(reduce(operator.add, map(lambda a,b: (a-b)**2, h1, h2))/len(h1))
More information about the Image-SIG
mailing list