Face Detection

Muhammad Qadeer

Data Scientist
Data Visualizer
Data Analyst
Jupyter
Python
TensorFlow
GORGES
England
import cv2
import numpy as np
import matplotlib.pyplot as plt

def get_differential_filter():
    filter_x = np.array([[1, 0, -1]])
    filter_y = np.array([[1], [0], [-1]])
    return filter_x, filter_y

def filter_image(im, filter):
    return cv2.filter2D(im, -1, filter)

def get_gradient(im_dx, im_dy):
    grad_mag = np.sqrt(im_dx**2 + im_dy**2)
    grad_angle = np.arctan2(im_dy, im_dx)
    return grad_mag, grad_angle

def build_histogram(grad_mag, grad_angle, cell_size):
    num_bins = 6
    angle_unit = np.pi / num_bins
    hist = np.zeros((grad_mag.shape[0] // cell_size, grad_mag.shape[1] // cell_size, num_bins))

    for i in range(hist.shape[0]):
        for j in range(hist.shape[1]):
            mag_cell = grad_mag[i*cell_size:(i+1)*cell_size, j*cell_size:(j+1)*cell_size]
            angle_cell = grad_angle[i*cell_size:(i+1)*cell_size, j*cell_size:(j+1)*cell_size]

            hist_cell = np.zeros(num_bins)
            for k in range(num_bins):
                hist_cell[k] = np.sum(mag_cell * (np.logical_and(angle_cell >= k*angle_unit, angle_cell < (k+1)*angle_unit)))

            hist[i, j, :] = hist_cell

    return hist

def get_block_descriptor(ori_histo, block_size):
    eps = 1e-5
    num_bins = ori_histo.shape[2]
    blocks = np.zeros((ori_histo.shape[0] - block_size + 1, ori_histo.shape[1] - block_size + 1, block_size**2 * num_bins))

    for i in range(blocks.shape[0]):
        for j in range(blocks.shape[1]):
            block = ori_histo[i:i+block_size, j:j+block_size, :]
            blocks[i, j, :] = block.flatten() / np.sqrt(np.sum(block**2) + eps)

    return blocks.flatten()

def extract_hog(im):
    if im is None:
        raise ValueError("Failed to load image. Check the file path and format.")
    
    im = im.astype('float') / 255.0
    filter_x, filter_y = get_differential_filter()
    im_dx = filter_image(im, filter_x)
    im_dy = filter_image(im, filter_y)
    grad_mag, grad_angle = get_gradient(im_dx, im_dy)
    cell_size = 8
    ori_histo = build_histogram(grad_mag, grad_angle, cell_size)
    block_size = 2
    hog = get_block_descriptor(ori_histo, block_size)
    visualize_hog(im, hog, cell_size, block_size)
    return hog

def visualize_hog(im, hog, cell_size, block_size):
    num_bins = 6
    max_len = 7
    im_h, im_w = im.shape
    num_cell_h, num_cell_w = int(im_h / cell_size), int(im_w / cell_size)
    num_blocks_h, num_blocks_w = num_cell_h - block_size + 1, num_cell_w - block_size + 1
    histo_normalized = hog.reshape((num_blocks_h, num_blocks_w, block_size**2, num_bins))
    histo_normalized_vis = np.sum(histo_normalized**2, axis=2) * max_len
    angles = np.arange(0, np.pi, np.pi/num_bins)
    mesh_x, mesh_y = np.meshgrid(np.r_[cell_size: cell_size*num_cell_w: cell_size], np.r_[cell_size: cell_size*num_cell_h: cell_size])
    mesh_u = histo_normalized_vis * np.sin(angles).reshape((1, 1, num_bins))
    mesh_v = histo_normalized_vis * -np.cos(angles).reshape((1, 1, num_bins))
    plt.imshow(im, cmap='gray', vmin=0, vmax=1)
    for i in range(num_bins):
        plt.quiver(mesh_x - 0.5 * mesh_u[:, :, i], mesh_y - 0.5 * mesh_v[:, :, i], mesh_u[:, :, i], mesh_v[:, :, i],
                   color='white', headaxislength=0, headlength=0, scale_units='xy', scale=1, width=0.002, angles='xy')
    plt.show()

def face_recognition(I_target, I_template):
    if I_target is None or I_template is None:
        raise ValueError("Failed to load images for face recognition. Check the file paths and format.")
    
    result = cv2.matchTemplate(I_target, I_template, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
    box_size = I_template.shape[:2]
    bounding_boxes = np.array([[max_loc[0], max_loc[1], max_val]])
    return bounding_boxes

def visualize_face_detection(I_target, bounding_boxes, box_size):
    if I_target is None:
        raise ValueError("Failed to load image for face detection visualization. Check the file path and format.")
    
    hh, ww, cc = I_target.shape
    fimg = I_target.copy()
    for ii in range(bounding_boxes.shape[0]):
        x1 = bounding_boxes[ii, 0]
        x2 = bounding_boxes[ii, 0] + box_size[1]
        y1 = bounding_boxes[ii, 1]
        y2 = bounding_boxes[ii, 1] + box_size[0]

        x1 = max(0, min(x1, ww-1))
        x2 = max(0, min(x2, ww-1))
        y1 = max(0, min(y1, hh-1))
        y2 = max(0, min(y2, hh-1))

        fimg = cv2.rectangle(fimg, (int(x1), int(y1)), (int(x2), int(y2)), (255, 0, 0), 1)
        cv2.putText(fimg, "%.2f" % bounding_boxes[ii, 2], (int(x1) + 1, int(y1) + 2), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2, cv2.LINE_AA)

    plt.imshow(cv2.cvtColor(fimg, cv2.COLOR_BGR2RGB))
    plt.show()
if __name__ == '__main__':
    im = cv2.imread('camraman.tif', 0)
    hog = extract_hog(im)

    I_target = cv2.imread('target.png', 0)
    I_template = cv2.imread('template.png', 0)
    bounding_boxes = face_recognition(I_target, I_template)

    I_target_c = cv2.imread('target.png')
    visualize_face_detection(I_target_c, bounding_boxes, I_template.shape[:2])

Partner With Muhammad
View Services

More Projects by Muhammad