Ejemplo n.º 1
0
def FindTemplate(pyramid, template, threshold):
    #Get dimensions of the template
    tempWidth, tempHeight = template.size
    #Resize template to the suggested size in order to speed up NCC computations
    template = template.resize(
        (suggestedTemplateWidth,
         (tempHeight * suggestedTemplateWidth / tempWidth)), Image.BICUBIC)

    #Call NCC and get Cross Correlation Coefficients for every image in the pyramid
    crossCorrCoefficients = []
    for image in pyramid:
        value = ncc.normxcorr2D(image, template)
        crossCorrCoefficients.append(value)

    #Once you have the NCC stuff use that to find faces by checking every pixel
    k = 0

    #Loop over Cross Correlation Coefficients List of every image in the pyramid
    for correlationArray in crossCorrCoefficients:

        #access elements of pixel correlation matrix
        for i in range(len(correlationArray)):
            for j in range(len(correlationArray[0])):
                #if correlation at the specific pixel is above threshold then draw a rectangle around the face
                if correlationArray[i][j] > threshold:
                    draw = ImageDraw.Draw(pyramid[0])

                    #Draw rectangle around a detected face
                    draw.line(((j - tempWidth / 2) / (0.75**k),
                               (i - tempHeight / 2) / (0.75**k),
                               (j + tempWidth / 2) / (0.75**k),
                               (i - tempHeight / 2) / (0.75**k)),
                              fill="red",
                              width=2)
                    draw.line(((j - tempWidth / 2) / (0.75**k),
                               (i - tempHeight / 2) / (0.75**k),
                               (j - tempWidth / 2) / (0.75**k),
                               (i + tempHeight / 2) / (0.75**k)),
                              fill="red",
                              width=2)
                    draw.line(((j - tempWidth / 2) / (0.75**k),
                               (i + tempHeight / 2) / (0.75**k),
                               (j + tempWidth / 2) / (0.75**k),
                               (i + tempHeight / 2) / (0.75**k)),
                              fill="red",
                              width=2)
                    draw.line(((j + tempWidth / 2) / (0.75**k),
                               (i + tempHeight / 2) / (0.75**k),
                               (j + tempWidth / 2) / (0.75**k),
                               (i - tempHeight / 2) / (0.75**k)),
                              fill="red",
                              width=2)

                    #convert rectangle to color red
                    pyramid[0] = pyramid[0].convert('RGB')
                    del draw
        k = k + 1
    #show the original image
    pyramid[0].show()
    return 0
Ejemplo n.º 2
0
def FindTemplate(pyramid, template, threshold):
	# Maintain a variable so we know by how much to scale the coordinates back.
	scaleBack = 1

	matches = []

	# This markerImage will be the image where we draw the rectangles of matches we find.
	markerImage = pyramid[0]
	# Convert it to RGB so we can add coloured rectangles.
	markerImage = markerImage.convert('RGB')

	# Loop over every image in the pyramid to find matches.
	for image in pyramid:
		# Get the normalized cross correlation of the template with the image.
		grey_image = image.convert('L')
		#crossXC = ncc.normxcorr2D(image, template)
		crossXC = ncc.normxcorr2D(grey_image, template)

		# We loop through this 2D returned array to check for values larger than our threshold.
		for y in range(len(crossXC)):
			for x in range(len(crossXC[y])):
				if crossXC[y][x] > threshold:
					matches.append((x*scaleBack,y*scaleBack,scaleBack))
	
		scaleBack *= 1/scale
	return matches
Ejemplo n.º 3
0
def FindTemplate(image, template, threshold):
    
    template = Image.open(template)
    
    #apply a gussian filter on template based on the imgae size to get a better result
    template1 = scipy.ndimage.filters.gaussian_filter(template, sigma =3)

    #change the template size to given size in the question for original image 
    #and sclaed version of it based on i
    temp_size = (15,int((15*50)/37))
    template1 = template.resize(temp_size, Image.BICUBIC)
    
    # apply normalized autocorrelation of template on the image to find matched places
    template_finder = ncc.normxcorr2D(image, template1)
    template_finder = np.transpose(template_finder)
    template_finder = template_finder.reshape((image.size[0], image.size[1]))
    image = image.convert('RGB')

    #If the array's elements are less than
    #threshold they're going to be 0 and else 1
    for x in range(0,template_finder.shape[0]):
        for y in range(0,template_finder.shape[1]):
            
            if(template_finder[x][y] >= threshold):
                template_finder[x][y] = 1
            
            if(template_finder[x][y] < threshold):
                template_finder[x][y] = 0
                
    #find the location of elements which are not 0, and draw a rectangle around it based on the template size         
    for x in range(0,template_finder.shape[0]):
        for y in range(0,template_finder.shape[1]):
            
            if(template_finder[x][y] == 1):
                x1 = x-int(temp_size[0])
                x2 = x+int(temp_size[0])
    

                y1 = y-int(temp_size[1])
                y2 = y+int(temp_size[1])

                draw = ImageDraw.Draw(image)
                draw.line((x1,y1,x2,y1),fill="red",width=2)
                del draw

                draw = ImageDraw.Draw(image)
                draw.line((x1,y1,x1,y2),fill="red",width=2)
                del draw

                draw = ImageDraw.Draw(image)
                draw.line((x1,y2,x2,y2),fill="red",width=2)
                del draw

                draw = ImageDraw.Draw(image)
                draw.line((x2,y2,x2,y1),fill="red",width=2)
                del draw

    image.save('111.jpg' )
  
    return image.convert('RGB')
def FindTemplate(pyramid, template, threshold):

    newTemplateWidth = templateWidth;
    newTemplateHeight = templateWidth/template.width*template.height;

    if template.width > templateWidth:
        template = template.resize((int(newTemplateWidth),int(newTemplateHeight)), Image.BICUBIC)

    outputImage = pyramid[0];   # Get the original image, this is the one you draw rectangles on
    outputImage = outputImage.convert('RGB')

    for index, im in enumerate(pyramid):
        nccImage = ncc.normxcorr2D(im, template)       # Get the normalized correlation of the template onto the im
        rectWidth = newTemplateWidth * (0.75 ** index)  # Update template rectangle size
        rectHeight = newTemplateHeight * (0.75 ** index) # Update template rectangle size
        for row in range(nccImage.shape[0]):
            for col in range(nccImage.shape[1]):
                if(nccImage[row][col] > threshold):
                    scaledBackCol = col*(1.333**index)
                    scaledBackRow = row*(1.333**index)
                    draw = ImageDraw.Draw(outputImage)
                    draw.rectangle([scaledBackCol-rectWidth/2, scaledBackRow-rectHeight/2, scaledBackCol+rectWidth/2, scaledBackRow+rectHeight/2], fill=None, outline="red")
                    del draw

    outputImage.show()
Ejemplo n.º 5
0
def FindTemplate(pyramid, template, threshold):
    matches = []

    for img in pyramid:
        matches.append(ncc.normxcorr2D(img, template))

    thresholdMatches = []

    #For the matched images in pyramid, diregard the ones
    #With small correlations
    for match in matches:
        thresholdMatches.append(np.where(match >= threshold, 1, 0))

    return thresholdMatches
Ejemplo n.º 6
0
def FindTemplate(pyramid, template, threshold):
    # create a new template with width = 15
    width = 15
    r = template.size[0] / width
    height = template.size[1] / r
    newTemplate = template.resize((width,height),Image.BICUBIC)

    pixelPositions = []
    for img in pyramid:
        result = ncc.normxcorr2D(img, newTemplate)
        # correlation is bigger than the threshold
        pixelBiggerThreshold = np.where (result > threshold)
        
        # pixelBiggerThreshold contains two elements, for each x and y
        # [0] holds y indices, [1] holds x indices
        c = zip(pixelBiggerThreshold[0],pixelBiggerThreshold[1])
        
        # pixelPositions contains all matching points for each image
        pixelPositions.append(c)
    
    # make image support RBG color, then we can draw the red retangele on the image
    image = pyramid[0].convert('RGB')
    
    for index in range(len(pixelPositions)):
        points = pixelPositions[index]
        # changes in x, width and y, height
        changeInX = newTemplate.size[0] 
        changeInY = newTemplate.size[1] 
        
        # draw red rectangle around the centred of each point
        for point in points:
            # rescale the poins by the right power of 0.75
            xP = point[1] // 0.75 ** index 
            yP = point[0] // 0.75 ** index
            
            # calculate 4 points around the centre
            x2 = xP + changeInX
            x1 = xP - changeInX
            y1 = yP - changeInY
            y2 = yP + changeInY
            
            # draw all 4 lines
            draw = ImageDraw.Draw(image)
       	    draw.line((x1,y1,x2,y1),fill="red",width=2)
       	    draw.line((x1,y2,x2,y2),fill="red",width=2)
       	    draw.line((x1,y1,x1,y2),fill="red",width=2)
       	    draw.line((x2,y1,x2,y2),fill="red",width=2)
            del draw
    
    image.show()
Ejemplo n.º 7
0
>>> def FindTemplate(pyramid, template, threshold):
	# initialize values
	tracker = []

	# NCC is expensive, so reduce to a more preferable width
	prefered_width = 15

	# resize the template with bicubic interpolation to prefered_width
	# since not all image are perfect suqare, we need to calcuate how much
	# to resize its Y and still retain the image's aspect ratio
	scaledown = template.size[0]/prefered_width
	template = template.resize((prefered_width, template.size[1]//scaledown), Image.BICUBIC)

	# loop through each image in pyramid, compute the NCC
	for im in pyramid:

		# the array of cross-correlation coefficients, in the range -1.0 to 1.0.
		# check whether the threshold is reached
		thresholdLevel = np.where(ncc.normxcorr2D(im, template) > threshold)
		thresholdLevelat0 = thresholdLevel[0]
		thresholdLevelat1 = thresholdLevel[1]

		# append the thresholdLvl to the tracker
		tracker.append(zip(thresholdLevelat1, thresholdLevelat0))

	# If img must support colour. If necessary, you can achieve this with img = img.convert('RGB').
	img = pyramid[0].convert('RGB')

	# For each pixel at which the normalized correlation result is above
	# the threshold, draw lines (forming a rectangle) to mark the boundary of the template
	# at that location. All lines should be shown overlayed on the original image.
	numofitem = len(tracker)
	for pos in range(numofitem):
		multiplier = 0.75 ** pos
		multiplier2X = 2 * multiplier
		# for each item in the array
		for thres in tracker[pos]:
			
			# rectangle
			x1 = (thres[0]//multiplier) - (template.size[0]//multiplier2X)
			y1 = (thres[1]//multiplier) - (template.size[1]//multiplier2X)
			x2 = (thres[0]//multiplier) + (template.size[0]//multiplier2X)
			y2 = (thres[1]//multiplier) + (template.size[1]//multiplier2X)

			# draw read line, calculated rectangle
			draw = ImageDraw.Draw(img)
			draw.rectangle((x1,y1,x2,y2),outline="red")
			del draw

	return img
Ejemplo n.º 8
0
def FindTemplate(pyramid, template, threshold):
    desiredWidth = 15
    originalHeight = template.size[1]
    originalWidth = template.size[0]
    ratio = originalWidth / desiredWidth
    #Resize the template where width = desiredWidth and height is also reduced to fit the original ratio
    template = template.resize((desiredWidth, originalHeight / ratio),
                               Image.BICUBIC)

    #Find all the coordinates in the image that have correlation values with the template > threshold
    coordList = []
    originalImage = pyramid[0].convert('RGB')
    for image in pyramid:
        coord = np.where(ncc.normxcorr2D(image, template) > threshold)
        x_coord = coord[0]
        y_coord = coord[1]
        coords = zip(y_coord, x_coord)
        coordList.append(coords)

    for imagePos in range(len(coordList)):
        #Take the power of 0.75 to image position in the pyramidso we adjust according to the size of the picture in our pyramid
        scale = 0.75**imagePos
        for pixel in coordList[imagePos]:
            #Adjust the pixel according to the size of the image in the pyramid
            center_x = pixel[0] / scale
            center_y = pixel[1] / scale
            #Add or subtract a certain offset to the center coordinate so that we get four different coordinates to make a box
            offset = 15
            left_x = center_x - offset
            right_x = center_x + offset
            up_y = center_y + offset
            bottom_y = center_y - offset

            #Draw the lines to specify the pixels on the original image with correlation values > threshold
            draw = ImageDraw.Draw(originalImage)

            #Draw the horizontal lines
            draw.line((left_x, up_y, right_x, up_y), fill="red", width=2)
            draw.line((left_x, bottom_y, right_x, bottom_y),
                      fill="red",
                      width=2)
            #Draw the vertical lines
            draw.line((left_x, up_y, left_x, bottom_y), fill="red", width=2)
            draw.line((right_x, up_y, right_x, bottom_y), fill="red", width=2)
            del draw

    return originalImage
Ejemplo n.º 9
0
def FindTemplate(pyramid, template, threshold):
    "Find and mark all locations in the pyramid at which the NCC of the template with the image is above the threshold."
    assert (len(pyramid) >
            0), "The pyramid must have at least one image element."

    template_width = 15
    template = Image.open(template)
    tx, ty = template.size
    t = template.resize((template_width, ty * template_width / tx),
                        Image.BICUBIC)

    im = pyramid[0].copy().convert('RGB')
    draw = ImageDraw.Draw(im)

    for i, image in enumerate(pyramid):
        arr_nmcorrl = ncc.normxcorr2D(image, t)

        upscale = (1 /
                   scale)**i  # scale to be multiple regards to original image
        height, width = arr_nmcorrl.shape

        # To find every pixel that is above the threshold, and output the peaks scaled to the original image
        peaks = []
        for x in range(width):
            for y in range(height):
                if (arr_nmcorrl[y][x] > threshold):
                    peaks.append([x * upscale, y * upscale])

        for p in peaks:
            x_left = max(p[0] - t.size[0] * upscale, 0)
            y_top = max(p[1] - t.size[1] * upscale, 0)
            x_right = min(p[0] + t.size[0] * upscale, im.size[0] - 1)
            y_bottom = min(p[1] + t.size[1] * upscale, im.size[1] - 1)
            # draw a red ractangle box for matchings
            drawRedLine(draw, x_left, y_top, x_right, y_top)  #top
            drawRedLine(draw, x_left, y_top, x_left, y_bottom)  #left
            drawRedLine(draw, x_left, y_bottom, x_right, y_bottom)  #bottom
            drawRedLine(draw, x_right, y_top, x_right, y_bottom)  #right

    del draw
    im.show()
    return im


# q5

# q6
Ejemplo n.º 10
0
def FindTemplate(pyramid, template, threshold):
    #resize the template to fix width 15px,and scale the height accordingly
    template_size = 15
    template = Image.open(template)
    template = template.resize(
        (int(template_size),
         int(template.size[1] * template_size / template.size[0])),
        Image.BICUBIC)
    image = pyramid[0].convert('RGB')
    scale = 1

    for im in pyramid:
        ncc_result = ncc.normxcorr2D(im, template)
        #get all the locations that are aboved threshold
        above_threshold = np.where(ncc_result >= threshold)
        x = above_threshold[1]
        y = above_threshold[0]
        #adjust template by the right scale factor
        backToScale = 1 / scale
        xoffset = template.size[0] * backToScale / 2
        yoffset = template.size[1] * backToScale / 2
        arraySize = len(x)
        for i in range(arraySize):
            #adjust x and by by the right scale factor
            xscaled = x[i] * backToScale
            yscaled = y[i] * backToScale
            #get the position for top-left,top-right,bottom-left,bottom-right
            x1 = xscaled - xoffset
            y1 = yscaled - yoffset

            x2 = xscaled + xoffset
            y2 = yscaled - yoffset

            x3 = xscaled + xoffset
            y3 = yscaled + yoffset

            x4 = xscaled - xoffset
            y4 = yscaled + yoffset
            #draw line based on the positions
            draw = ImageDraw.Draw(image)
            draw.line((x1, y1, x2, y2), fill="red", width=2)
            draw.line((x2, y2, x3, y3), fill="red", width=2)
            draw.line((x3, y3, x4, y4), fill="red", width=2)
            draw.line((x4, y4, x1, y1), fill="red", width=2)
        scale = scale * 0.75
    return image
Ejemplo n.º 11
0
def FindTemplate(pyramid, template, THRESHOLD):
    """
    Finds the correlation between pyramid and template
    [I]:
    ----------
    pyramid     A list of resized images
    template    The given template used to match the images on the pyramid
    THRESHOLD   Is the constant we use to discard small correlations
    [O]:
    ----------
    None
    """
    match = []
    for image in pyramid:
        match.append(ncc.normxcorr2D(image, template))
    thresholded_match_list = []
    for m in match:
        thresholded_match_list.append(np.where(m >= THRESHOLD, 1, 0))
    return thresholded_match_list
Ejemplo n.º 12
0
def FindTemplate(pyramid, template, threshold):
    '''
    Finds and marks all locations in pyramid at which the normalized 
    cross correlation of the template with the image is above the threshold.

    Returns a PIL image of the largest image in the pyramid marked with red 
    rectangle's corresponding to the locations of template matches
    '''

    goalWidth = 15
    # resize template
    ratio = template.size[0] / goalWidth
    template = template.resize((goalWidth, template.size[1] // ratio), Image.BICUBIC)

    pointLists = []
    for image in pyramid:
        nccResult = ncc.normxcorr2D(image, template)
        aboveThreshold = np.where(nccResult > threshold)
        pointLists.append(zip(aboveThreshold[1], aboveThreshold[0]))

    convert = pyramid[0].convert('RGB')

    for i in range(len(pointLists)):
        pointList = pointLists[i]
        scaleFactor = 0.75 ** i

        for pt in pointList:

            ptx = pt[0] // scaleFactor
            pty = pt[1] // scaleFactor

            adjustx = template.size[0] // (2 * scaleFactor)
            adjusty = template.size[1] // (2 * scaleFactor)

            x1 = ptx - adjustx
            y1 = pty - adjusty
            x2 = ptx + adjustx
            y2 = pty + adjusty
            draw = ImageDraw.Draw(convert)
            draw.rectangle([x1,y1,x2,y2], outline="red")
            del draw

    return convert
Ejemplo n.º 13
0
Archivo: a3.py Proyecto: faddison/cs425
def FindTemplate(pyramid, template, threshold):
    array = ncc.normxcorr2D(image, template);
    matches = list();
    
    for x in range(len(array)):
        for y in range(len(array)):
            if (array[x][y] > threshold):
                matches.append((x,y));
    
    draw = ImageDraw.Draw(pyramid);
    for p in matches:
        draw.point(p,fill="red");
    del draw;
    
    pyramid.show();
    #print array;
    
    # go through the array and find all locations above 'threshold'
    # for all locations draw them on the original image
    return;
Ejemplo n.º 14
0
def FindTemplate(pyramid, template, threshold):

    finalWidth= 15
    downsampleScale=template.size[0]/finalWidth 
    finalHeight=template.size[1]/downsampleScale
    template = template.resize((finalWidth, finalHeight), Image.BICUBIC)
    #print template.size 
    
    img = pyramid[0].convert('RGB')
    
    print 'the length of the pyramid'
    print len(pyramid) 
    for image in pyramid:
	NCC=ncc.normxcorr2D(image, template)
	print 'NCC value'
	print NCC
        aboveThresh=np.where(NCC > threshold)
        print 'the points above threshold'
        print aboveThresh
        xlist=aboveThresh[1]
        ylist=aboveThresh[0]
        print xlist
        print ylist
        ptx1=template.size[0]/2
        pty1=template.size[1]/2
        print len(xlist)
        for i in range(len(xlist)):
			x1=xlist[i]-ptx1
			y1=ylist[i]-pty1
			x2=xlist[i]+ptx1
			y2=ylist[i]+pty1
			print x1,x2,y1,y2
			draw=ImageDraw.Draw(img)
			draw.rectangle((x1,y1,x2,y2),outline="red")
			#del draw
	img.save('result.png','PNG')
	
	return img
def GetMatchedTemplateCoordinates(pyramid, template, threshold):
    x, y = template.size
    xyratio = float(y) / float(x)
    normtemplate = template.resize(
        (TEMPLATE_WIDTH, int(float(TEMPLATE_WIDTH) * (xyratio))),
        Image.BICUBIC)
    # an array of normalized correlations for each image in the pyramid
    correlatedarray = []
    # an array of tuples (x,y,index) where index is the index in the pyramid
    # this is in order to kow how much to scale the template later
    matchingvalues = []
    for i in range(0, len(pyramid)):
        # get correlation result from template and an image in the pryamid
        correlatedarray.append(ncc.normxcorr2D(pyramid[i], normtemplate))
        for x in range(0, correlatedarray[i].shape[0]):
            for y in range(0, correlatedarray[i].shape[1]):
                denormal = correlatedarray[i][x][y]
                # if we have value above the threshold, we add that coorinate to the array for later
                if correlatedarray[i][x][y] > float(threshold):
                    scalefactor = 1.0 / pow(.75, i)
                    matchingvalues.append((int(float(x) * scalefactor),
                                           int(float(y) * scalefactor), i))
    return matchingvalues
Ejemplo n.º 16
0
def FindTemplate(pyramid, template, threshhold):
    # maintain a variable so we know by how much to scale the coordinates back.
    scaleBack = 1

    # this marker will be the image where we draw the rectangles of matches we find.
    marker = pyramid[0]
    marker = marker.convert('RGB')

    # loop over every image in the pyramid to find matches.
    for image in pyramid:
        # Get the normalized cross correlation of the template with the image.
        crossXC = ncc.normxcorr2D(image, template)

        # loop through this 2D returned array to check for values larger than our threshold.
        for y in range(len(crossXC)):
            for x in range(len(crossXC[y])):
                if crossXC[y][x] > threshhold:

                    # find scaled coordinate values
                    draw = ImageDraw.Draw(marker)
                    x1 = x*scaleBack + template.size[0]
                    x2 = x*scaleBack - template.size[0]
                    y1 = y*scaleBack - template.size[1]
                    y2 = y*scaleBack + template.size[1]
                    
                    # draw a red rectangle around 
                    draw.line((x1,y1,x2,y1),fill="red",width=2)
                    draw.line((x1,y2,x2,y2),fill="red",width=2)
                    draw.line((x1,y1,x1,y2),fill="red",width=2)
                    draw.line((x2,y1,x2,y2),fill="red",width=2)
                    
                    del draw
        # scaleback is determined the inverse of 0.75, our original scale value - (0.75)^(-1) = 1.33333333
        scaleBack *= 1.33333

    return marker
Ejemplo n.º 17
0
def FindTemplate(pyramid, template, threshold):

    #reduce template to 15 pixels/define a constant for template width
    size_template = 15.0
    template = Image.open("/Users/leticianakajima/PycharmProjects/a2/" +
                          template + ".jpg")
    width, height = template.size
    scaling_factor = size_template / min(width, height)
    new_height = scaling_factor * height
    new_width = scaling_factor * width

    new_template = template.resize((int(new_width), int(new_height)),
                                   PIL.Image.BICUBIC)
    matches_array = []
    #ncc-ing the template and all the pyramid images
    for x in pyramid:
        matches = np.where(ncc.normxcorr2D(x, new_template) > threshold)
        x = matches[1]
        y = matches[0]
        #adding the matches to this array
        matches_array.append(zip(x, y))
    #passing it into a helping draw function
    img = HelperDrawer(pyramid[0], matches_array)
    img.save('faces_recon.png', 'PNG')
Ejemplo n.º 18
0
def FindTemplate(pyramid, template, threshhold):
    # maintain a variable so we know by how much to scale the coordinates back.
    scaleBack = 1

    # this marker will be the image where we draw the rectangles of matches we find.
    marker = pyramid[0]
    marker = marker.convert('RGB')

    # loop over every image in the pyramid to find matches.
    for image in pyramid:
        # Get the normalized cross correlation of the template with the image.
        crossXC = ncc.normxcorr2D(image, template)

        # loop through this 2D returned array to check for values larger than our threshold.
        for y in range(len(crossXC)):
            for x in range(len(crossXC[y])):
                if crossXC[y][x] > threshhold:

                    # find scaled coordinate values
                    draw = ImageDraw.Draw(marker)
                    x1 = x * scaleBack + template.size[0]
                    x2 = x * scaleBack - template.size[0]
                    y1 = y * scaleBack - template.size[1]
                    y2 = y * scaleBack + template.size[1]

                    # draw a red rectangle around
                    draw.line((x1, y1, x2, y1), fill="red", width=2)
                    draw.line((x1, y2, x2, y2), fill="red", width=2)
                    draw.line((x1, y1, x1, y2), fill="red", width=2)
                    draw.line((x2, y1, x2, y2), fill="red", width=2)

                    del draw
        # scaleback is determined the inverse of 0.75, our original scale value - (0.75)^(-1) = 1.33333333
        scaleBack *= 1.33333

    return marker
Ejemplo n.º 19
0
def FindTemplate(pyramid, template, threshold):

    # Set the TEMPLATE_WIDTH constant (=15 as given in specifications)
    TEMPLATE_WIDTH = 15

    # Set the output image to be the first image of the pyramid (which has the size as the original image without any scaling)
    image = pyramid[0]

    # Convert the image from grayscale to color in order to see the face detection rectangle in colors (="red" rectangle as required)
    image = image.convert('RGB')

    # initialize the draw object on the given image
    draw = ImageDraw.Draw(image)

    # Open the image, here the template, so that can be accessed and used while performing the Normalized Cross-Correlation
    with Image.open(template) as template:

        # Set x to be the temlate's width and y to be the template's height
        x, y = template.size

        # Set the template width to TEMPLATE_WIDTH (= 15, as asked)
        x = TEMPLATE_WIDTH

        # Set the template height to a value that keeps the original ratio between width and height
        y = (float(TEMPLATE_WIDTH) / template.width) * template.height

        # Resize Template to width = TEMPLATE_WIDTH (= 15, as asked), and keep the ratio for the height
        template = template.resize((int(x), int(y)), Image.BICUBIC)

        # Scan through every photo in the pyramid using the template
        for photo_index in range(0, len(pyramid)):

            # Perform the Normalized Cross-Correcation on the given image using the given template
            output = ncc.normxcorr2D(pyramid[photo_index], template)

            # Save the Matrix where the normalized correlation result is above the threshold
            comparison = np.where(output > threshold)

            # Save the row of the Matrix where the normalized correlation result is above the threshold
            row = comparison[1]

            # Save the column of the Matrix where the normalized correlation result is above the threshold
            column = comparison[0]

            # Loop through every element in the row (or column, since they are equal in length)
            for i, j in enumerate(row):

                # Rescale the width of the red rectangle after each iteration using the given ratio (template.width * 1/0.75^i)
                rescaled_x = x * 1 / (0.75**photo_index)

                # Rescale the height of the red rectangle after each iteration using the given ratio (template.height * 1/0.75^i)
                rescaled_y = y * 1 / (0.75**photo_index)

                # Save the row element of the current iteration in M_x (name symbolizes Matrix x axis)
                M_x = j

                # Save the column element of the current iteration in M_x (name symbolizes Matrix y axis)
                M_y = column[i]

                # THE FACE DETECTION RECTANGLE BOX
                # Bottom line
                x1 = M_x * 1 / (
                    0.75**photo_index
                ) - rescaled_x / 2  # Rescale the image point x to match x size of the output image
                y1 = M_y * 1 / (
                    0.75**photo_index
                ) + rescaled_y / 2  # Rescale the image point y to match y size of the output image
                x2 = M_x * 1 / (
                    0.75**photo_index
                ) + rescaled_x / 2  # Rescale the image point x to match x size of the output image
                y2 = M_y * 1 / (
                    0.75**photo_index
                ) + rescaled_y / 2  # Rescale the image point y to match y size of the output image
                draw.line(
                    (x1, y1, x2, y2), fill="red", width=2
                )  # Draw the bottom line of the rectangle with width = 2 (colored in red)

                # Right line
                x1 = M_x * 1 / (0.75**photo_index) + rescaled_x / 2
                y1 = M_y * 1 / (0.75**photo_index) + rescaled_y / 2
                x2 = M_x * 1 / (0.75**photo_index) + rescaled_x / 2
                y2 = M_y * 1 / (0.75**photo_index) - rescaled_y / 2
                draw.line(
                    (x1, y1, x2, y2), fill="red", width=2
                )  # Draw the right line of the rectangle with width = 2 (colored in red)

                # Top line
                x1 = M_x * 1 / (0.75**photo_index) - rescaled_x / 2
                y1 = M_y * 1 / (0.75**photo_index) - rescaled_y / 2
                x2 = M_x * 1 / (0.75**photo_index) + rescaled_x / 2
                y2 = M_y * 1 / (0.75**photo_index) - rescaled_y / 2
                draw.line(
                    (x1, y1, x2, y2), fill="red", width=2
                )  # Draw the top line of the rectangle with width = 2 (colored in red)

                # Left Line
                x1 = M_x * 1 / (0.75**photo_index) - rescaled_x / 2
                y1 = M_y * 1 / (0.75**photo_index) + rescaled_y / 2
                x2 = M_x * 1 / (0.75**photo_index) - rescaled_x / 2
                y2 = M_y * 1 / (0.75**photo_index) - rescaled_y / 2
                draw.line(
                    (x1, y1, x2, y2), fill="red", width=2
                )  # Draw the bottom line of the rectangle with width = 2 (colored in red).
                # After drawing this last line (left line), these four lines (bottom, right, top, and left) create a red rectangle

    # Remove the binding of the draw from the local namespace
    del draw

    # Return the final image which contains red rectangles on the detected faces
    return image
Ejemplo n.º 20
0
from PIL import Image, ImageDraw
import numpy as np
import math
from scipy import signal
import ncc

scale = 0.75
threshold = 0.55
pyramid = a2.MakePyramid("./faces/judybats.jpg", 20)
template = "./faces/template.jpg"
template_width = 15
t = Image.open(template).resize((template_width, template_width),
                                Image.BICUBIC)

for i, image in enumerate(pyramid):
    arr_nmcorrl = ncc.normxcorr2D(image, t)
    upscale = (1 / scale)**i  # scale to be multiple regards to original image
    #height, width = arr_nmcorrl.shape
    width, height = arr_nmcorrl.shape[::-1]
    print width, height
    #print range(width), range(height)
    # To find every pixel that is above the threshold, and output the peaks scale to the original image
    peaks = []
    for x in range(width):
        for y in range(height):
            if (arr_nmcorrl[y][x] > threshold):
                peaks.append([x * upscale, y * upscale])
    print peaks

import a2
threshold = 0.571