Hello,

I think there is an errore in the frame selection inside
PIL_decode_parts().

                    for frame in ImageSequence.Iterator(image):
                        # Assume the pixel with the largest value is the
                        # background.
                        bg = max(frame.histogram())
                        if bg < bgpix:
                            image = frame
                            bgpix = bg


outside this loop image (in my opinion) will be always the last frame of
original image.

A part from this the algorithm could be better. From my test
using stddev and sum2 yield better result.

>From a (very) raw test you may use the attached code snippet.
Of course all of these are very simple test and can be wrong bug you
test failed for a pattern common few days ago (see the attached image)


-- 
Luigi Pugnetti

Symbolic S.p.A.
V.le Mentana, 29
I-43100 Parma
Italy

Tel: +39 0521 708811
Fax: +39 0521 776190

from __future__ import division

import sys
import os
import os.path
import tempfile
import math
import time
import md5

try:
    import cStringIO as StringIO
except ImportError:
    import StringIO


from PIL import Image, ImageSequence, ImageStat, ImageOps, ImageFilter


def analyze_image(image_name):
    image = Image.open(image_name)
    image.load()
    format = image.format
    print image.format, image.size, image.mode
    print image.info
    chosen_image = image.copy()
    #if "duration" in image.info:
    if 1:
        # Big assumption?  I don't know.  If the image's info dict
        # has a duration key assume it's a multi-frame image.  This
        # should save some needless construction of pixel
        # histograms for single-frame images.
        index = -1
        bgpix = 1e17           # ridiculously large number of pixels
        choosen_bg = -1
        min_sum = 1e17
        choosen_sum = -1
        min_sum2 = 1e17
        choosen_sum2_stddev = 0
        choosen_sum2 = -1
        min_mean = 1e17
        choosen_mean = -1
        max_stddev = 0
        choosen_stddev = 0
        min_rms = 1e17
        choosen_rms = -1
        try:
            print "index bg sum sum2 mean median rms stddev"
            for frame in ImageSequence.Iterator(image):
                index += 1
                frame.save("%s.frame.%03d.%s"%(os.path.basename(image_name), index, format))
                bg = max(frame.histogram())
                fs = ImageStat.Stat(frame)
                print index, bg, fs.sum, fs.sum2, fs.mean, fs.median, fs.rms, fs.stddev
                if bg < bgpix:
                    choosen_image = frame.copy()
                    bgpix = bg
                    #bg_im = frame.copy()
                    choosen_bg = index
                if fs.sum[0] < min_sum:
                    choosen_sum = index
                    #sum_im = frame.copy()
                    min_sum = fs.sum[0]
                if fs.sum2[0] < min_sum2:
                    choosen_sum2 = index
                    min_sum2 = fs.sum2[0]
                    sum2_img = frame.copy()
                    choosen_sum2_stddev = fs.stddev[0]
                if fs.mean[0] < min_mean:
                    choosen_mean = index
                    min_mean = fs.mean[0]
                if fs.stddev[0] > max_stddev:
                    choosen_stddev = index
                    max_stddev = fs.stddev[0]
                    stddev_img = frame.copy()
                if fs.rms[0] < min_rms:
                    choosen_rms = index
                    min_rms = fs.rms[0]

            # I've empirically determined:
            #   * ValueError => GIF image isn't multi-frame.
            #   * IOError => Decoding error
        except IOError:
            print "Invalid image"
            pass
        except ValueError:
            pass

    print "choice from: bg=%d, sum=%d, sum2=%d, mean=%d, rms=%d, stddev=%d"%(choosen_bg, choosen_sum, choosen_sum2, choosen_mean, choosen_rms, choosen_stddev)
    if choosen_stddev != choosen_sum2:
        diff_per = abs(choosen_sum2_stddev - max_stddev) / max_stddev
        if diff_per < 0.02:
            print "choosen %d (%f) (sum2)"%(choosen_sum2, diff_per)
            choosen_image = sum2_img
        else:
            print "choosen %d (%f) (stddev)"%(choosen_stddev, diff_per)
            choosen_image = stddev_img
    else:
        print "equal, choosen", choosen_stddev
        choosen_image = stddev_img
    image = choosen_image.convert("RGB")
    pnmfile = "%s.final.ppm"%(os.path.basename(image_name), )
    image.save(pnmfile)

##    print "\n\n+++++++++++++++++ocrad 0.16\n\n"
##    ocr_command = r'c:\tmp\ocrad.exe -c iso-8859-15 -s 2  "%s"' % (pnmfile,)
##    print ocr_command, "\n"
##    ocr_in, ocr_out, ocr_err = os.popen3(ocr_command)
##    ctext = ocr_out.read().lower()
##    ocr_in.close()
##    ocr_out.close()
##    ocr_err.close()
##    print ctext


if __name__ == "__main__":
    analyze_image(sys.argv[1])

    

Attachment: feedback.gif.gz
Description: GNU Zip compressed data

_______________________________________________
[email protected]
http://mail.python.org/mailman/listinfo/spambayes
Check the FAQ before asking: http://spambayes.sf.net/faq.html

Reply via email to