#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    4
    Rep Power
    0

    Image processing using python, PIL,numpy and scipy


    Hi I am trying to do image processing with python.
    what i actually want to do is i have image with human and i need to indetify humna faces or detect circle (basically human face).
    what i have done so far us
    • i have done edge detection for image using sobel edge detection.
    • than i have converted image into binary image which saves binary image ad prints out array of the image which is 0 or 255 (Black and White)
    • now what i m confused about after this what can i do to detect circle in image and print out how many human present in image.
    • i am using still images so i am giving the input for the image


    i am using Python, PIL, numpy and scipy. i do not want to use opencv. i want to detect human face and count how many people are in image and than print out the number of people in image.

    i would be so greatful if someone can help me out and tell me what can i do for this problem?

    Thanks in advanced.

    THIS IS THE CODE FOR EDGE DETECTION
    import numpy
    import scipy
    from scipy import ndimage

    im = scipy.misc.imread('test5.jpg')
    im = im.astype('int32')
    dx = ndimage.sobel(im, 0) # horizontal derivative
    dy = ndimage.sobel(im, 1) # vertical derivative
    mag = numpy.hypot(dx, dy) # magnitude
    mag *= 255.0 / numpy.max(mag) # normalize (Q&D)
    scipy.misc.imsave('sobel.jpg', mag)

    THIS IS THE CODE FOR BINARY CONVERSION OF IMAGE. THIS IS NOT MY CODE I FOUND THIS ONLINE WHEN I WAS SEARCHING HOW TO CONVERT IMAGE INTO BINARY IMAGE
    ## luminance conversion formula from

    def luminosity(rgb, rcoeff=0.2126, gcoeff=0.7152, bcoeff=0.0722):
    return rcoeff*rgb[0]+gcoeff*rgb[1]+bcoeff*rgb[2]

    ## take a PIL rgb image and produce a factory that yields
    ## ((x, y), (r, g, b)), where (x, y) are the coordinates
    ## of a pixel, (x, y), and its RGB values.
    def gen_pix_factory(im):
    num_cols, num_rows = im.size
    r, c = 0, 0
    while r != num_rows:
    c = c % num_cols
    yield ((c, r), im.getpixel((c, r)))
    if c == num_cols - 1: r += 1
    c += 1

    ## take a PIL RBG image and a luminosity conversion formula,
    ## and return a new gray level PIL image in which
    ## each pixel is obtained by applying the luminosity formula
    ## to the corresponding pixel in the RGB image.
    def rgb_to_gray_level(rgb_img, conversion=luminosity):
    gl_img = Image.new('L', rgb_img.size)
    gen_pix = gen_pix_factory(im)
    lum_pix = ((gp[0], conversion(gp[1])) for gp in gen_pix)
    for lp in lum_pix:
    gl_img.putpixel(lp[0], int(lp[1]))
    return gl_img

    ## take a gray level image an a gray level threshold
    ## and replace a pixel's gray level with 0 (black) if
    ## its gray level value is <= than the threshold and
    ## with 255 (white) if it is > than the threshold.
    def binarize(gl_img, thresh=70):
    gen_pix = gen_pix_factory(gl_img)
    for pix in gen_pix:
    if pix[1] <= thresh:
    gl_img.putpixel(pix[0], 0)
    else:
    gl_img.putpixel(pix[0], 255)

    im = Image.open("Test.jpg")
    gpix=gen_pix_factory(im)
    [pix for pix in [gpix.next() for i in xrange(0, 286)] if pix[1] != (255, 255, 255)]

    im2 = rgb_to_gray_level(im, conversion=luminosity) ## this will take a couple of seconds.
    im2.save("picture.jpg")
    binarize(im2)
    im2.save("hello.jpg")
    A =np.array(im2)
    print A
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,841
    Rep Power
    480

    Might work...


    If you allowed additional input to your function, say it were the approximate radius of a head in the photo (in pixels) you could do a Hough transform on the edge-detected black and white image and then count the maxima in the resulting array.

    More specifically,

    Code:
    centers  is  a 2D  array  with each  index
    corresponding  to  a  distance  along  the
    axis, x or y.  Fill it with zeros.
    
    for each pixel in the binary image:
        if the pixel is an edge:
            increment  all  centers  to  which
            circles   of   approximately  that
            radius could belong.
    
    count  the maxima  in  the centers  array,
    which is admittedly somewhat fuzzy.
    
    Given this edge detected matrix, let us
    figure out what happens to centers for the
    pixel '-' .
    
    Following matrix is the binary image,
    which I might also have labeled BWIMAGE .
    
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    2
    0 0 0 0 0 0 0 - 1 1 0 0 0 0 0 0 0
    0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0    4
    0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    6
    0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0
    0 0 0 * 0 0 0 0 0 0 0 0 0 1 0 0 0    .
    0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0    .
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    .
    0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0
    0 0 0 0 0 1 0 0 0 0 0 * 0 0 0 0 0
    0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0   16
    
    0   2   4   6  ...             16
    
    We need a coordinate system---which I marked.
    
    Our x and y axes are the same because I
    chose a square matrix.  Suppose we use
    this grid (follows) for the axes.
    You will have to choose an appropriate
    step size and bounds.  My grid is oversize
    which allows for heads clipped by the
    photo viewport.
    
    The target head radius is 5.
    
    _[0-9]+ denotes negative number.
    
    XCENTER_GRID holds _5 _3 _1 1 3 5 7 9 11 13 15 17 19 21
    YCENTER_GRID is the same.
    
    Consider the dash at (7, 3).
    Increment all the points in the centers
    array satisfying
    6 > sqrt((x-xc)**2 + (y-yc)**2) > 4
    
    0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 1 1 0 1 1 0 0 0 0 0
    0 0 0 0 1 0 0 0 1 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 1 0 0 0 1 0 0 0 0 0
    0 0 0 0 1 1 0 1 1 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0
    
    Now add in 2 more edges to see how the
    algorithm progresses.  These are the *
    characters at (3,8) and (11,12)
    
    centers becomes
    
    0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 1 1 0 1 1 0 0 0 0 0
    0 0 0 0 1 0 0 0 1 0 0 0 0 0
    0 0 0 1 1 1 0 0 0 0 0 0 0 0
    0 0 1 0 1 0 1 0 1 0 0 0 0 0
    0 0 1 0 1 1 1 2 2 1 0 0 0 0
    0 0 1 0 0 0 2 0 0 0 1 0 0 0
    0 0 1 0 0 0 2 0 0 0 1 0 0 0
    0 0 0 1 1 1 1 0 0 0 1 0 0 0
    0 0 0 0 0 0 1 0 0 0 1 0 0 0
    0 0 0 0 0 0 0 1 1 1 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0
    
    Considering the entire binary image:
    0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 2 4 3 3 4 2 0 0 0 0
    0 0 0 2 3 2 2 2 2 3 2 0 0 0
    0 0 2 3 2 2 3 3 2 2 3 2 0 0
    0 0 4 2 2 2 5 5 2 2 2 4 0 0
    0 0 3 2 3 5 8 8 5 3 2 3 0 0
    0 0 3 2 3 5 8 8 5 3 2 3 0 0
    0 0 4 2 2 2 5 5 2 2 2 4 0 0
    0 0 2 3 2 2 3 3 2 2 3 2 0 0
    0 0 0 2 3 2 2 2 2 3 2 0 0 0
    0 0 0 0 2 4 3 3 4 2 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0
    
    Still  following?   centers  has a  single
    maximum   and   if   you   backtrack   the
    coordinates  through to  the  binary image
    the maximum is in the right place.
    Last edited by b49P23TIvg; February 21st, 2013 at 02:13 PM. Reason: Sentence fragment removed.
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    4
    Rep Power
    0
    hey i am sorry i do not understand what are you trying to say. i am not that expert in python. i have very basic knowledge about others as well. can you be more specific about it ? and one more thing you know the matrix you are showing how do i display that as because when i print array for image its not printing the matrix you have done here. Thanks
  6. #4
  7. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,841
    Rep Power
    480
    I wrote the examples using executable Iverson notation with a little bit of editing, only this time I didn't show the j code. There is a similarity between numpy array operations and j array operations. j displays arrays with maximum simplicity. Do you see extra commas or brackets??? The columns align although it's not obvious with binary data.

    What about the algorithm don't you understand? I showed the Hough space center array after 3 various processing steps, I showed the inequality satisfied
    6 > sqrt((x-xc)**2 + (y-yc)**2) > 4
    corresponding to
    approximate radius of a head
    I suppose I didn't say "5".

    That
    Code:
    for each pixel in the binary image:
        if the pixel is an edge:
            increment  all  centers  to  which
            circles   of   approximately  that
            radius could belong.
    represents 4 nested loops is, I agree, non-obvious.
    [code]Code tags[/code] are essential for python code and Makefiles!
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    4
    Rep Power
    0
    I am sorry i have no idea what you talking about. and i did figure out when to display full matrix using numpy. even than i would not able able to create code using what are you explaining. as this requires me having very high level of numpy knowledge as well. can you give me example code?
    instead of equation. entirely up to you. sorry if i am bothering you.

    Originally Posted by b49P23TIvg
    I wrote the examples using executable Iverson notation with a little bit of editing, only this time I didn't show the j code. There is a similarity between numpy array operations and j array operations. j displays arrays with maximum simplicity. Do you see extra commas or brackets??? The columns align although it's not obvious with binary data.

    What about the algorithm don't you understand? I showed the Hough space center array after 3 various processing steps, I showed the inequality satisfied
    6 > sqrt((x-xc)**2 + (y-yc)**2) > 4
    corresponding to
    approximate radius of a head
    I suppose I didn't say "5".

    That
    Code:
    for each pixel in the binary image:
        if the pixel is an edge:
            increment  all  centers  to  which
            circles   of   approximately  that
            radius could belong.
    represents 4 nested loops is, I agree, non-obvious.
  10. #6
  11. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,841
    Rep Power
    480
    I learned about the Hough transform here http://rosettacode.org/wiki/Hough_transform

    If it's algebra that's confusing---what the heck are you doing trying to detect faces without knowing some math?
    can you give me example code?
    instead of equation
    In which case start here (link).
    [code]Code tags[/code] are essential for python code and Makefiles!
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    4
    Rep Power
    0
    its not the equation thats confusing whats hard for me it to convert equation into code. i do understand the maths by the way.
  14. #8
  15. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,841
    Rep Power
    480
    6>sqrt((x-xc)**2+(y-yc)**2)>4

    is a python expression that computes numerically to 0 or 1.

    sqrt = lambda a:a**(0.5)
    from math import sqrt
    from numpy import sqrt

    It's reasonable that you should learn about numpy before using it, likewise with python.
    [code]Code tags[/code] are essential for python code and Makefiles!
  16. #9
  17. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,841
    Rep Power
    480
    Data consists of circles with various radii,
    noise, and a line. See attached image.

    This Hough space is accumulates Cartesian coordinates that could be centers of circles within a range of radii.

    1) Circle 1 makes a bright spot in Hough space.

    2) Bright spot (yellow matrix element) of #2 comes from nearby objects that form 3 "lucky" segments. It's an artifact. The cutoff peak height determines whether you'd count it as a face.

    3) 3 is a little too big but could be weighted more strongly since part of it is out of the viewport.

    4) Ultra-enhanced by lucky coincidental features, and it's close to the target radius.

    6) Too small, making a blob rather than a sharp peak.

    7) (lower right) sketches the two circles that could have centers along the diagonal line
    Code:
    #untested, assumes square matrices.
    def hough(BWIMAGE, RMIN, RMAX, AXIS):
        BW = numpy.array(BWIMAGE)# or asarray?
        H = numpy.zeros((len(AXIS),len(AXIS)))
        for (R, ROW,) in enumerate(BW):
            Y = R/float(len(BW))
            for (C, CELL,) in enumerate(Y):
                if CELL:
                    X = CELL/float(len(ROW))
                    for (i,Cx,) in enumerate(AXIS):
                        DXDX = (X - Cx)**2
                        for (j, Cy) in enumerate(AXIS):
                            H[i,j] += RMIN < numpy.sqrt(DXDX+(Y-Cy)**2) < RMAX
        return H
    inputs RMIN,RMAX bracket the radii range you'd seek. Faces are sort of oval, that's an advantage. Using equality test on a grid with floating point arithmetic is unsmart. BWIMAGE is the pixel array.
    AXIS is a list of the trial centers, from 0 to 1. I used 60 values from -0.1 to 1.1 to allow for faces with centers off screen. Output is the Hough matrix.

    >>> numpy.arange(9.0)/8 #AXIS
    array([ 0. , 0.125, 0.25 , 0.375, 0.5 , 0.625, 0.75 , 0.875, 1. ])
    Attached Images
    Last edited by b49P23TIvg; February 22nd, 2013 at 01:05 AM. Reason: insert attachment
    [code]Code tags[/code] are essential for python code and Makefiles!

IMN logo majestic logo threadwatch logo seochat tools logo