The aim of the project was to measure the height in pixels of a person from a given image, as I mentioned in a previous post that the challenge we faced was on Dr Mick’s image and any image that has a noise in the background, Safiah and Aaron tried various ways to get rid of the background on Dr Mick’s image, in the end Aaron succeeded, and was able to develop a code that worked well on Dr Mick’s image, and would be very useful to use on images with background noises.
To finalise our project, we decided to put the two methods together into one code, and allow the user to choose what method suits him, in order to do that I added a user menu, so he can choose if the picture that he wishes to measure the height from has a white background or has a noise in the background, and an if else statement will run the method that the user chooses [1], the final code is provided below:
'''
Image Processing Group Project
"Determine height of a person in pixels from an image"
Group members:
Aaron Costello
Ruba Bait Bin Saleem
Safiah Sadeq
Objective:
- To calculate the Height of a person in Pixals using various image processing methods in python to achieve that goal
- Allowing the user to choose between two options listed using an If else statment
**************************************** Option 1 ****************************************
Sample image used: 1man.JPG - 2man.JPG - 3man.JPG
Script used to identify image height in pixels, using Contours to get the highest and the lowest points to calculate the height
Steps:
- Importing the necessary packages
- Accessing a pixels value to get the Blue Green and Red colour values
- Setting the upper and lower range values wanted for each colour
- Setting the mask in function B using the ranges set
- Deducting the White from the Mask B
- Using the contours function to outline the man in the white background image
- Getting the max contour area
- From it using tuples the extreme top (extTop) and extrem bottom (extBot) point are obtained
- A Blue dot is drawn at the extreme top point and a Green dot is drawn at the extreme bottom point
- From the coordination the x and y values are extracted
- The y values from the bottom and top coordinations are subtracted from each other to get the height
- The values obtained are then printed on screen and the image is shown on screen
**************************************** Option 2 ****************************************
Sample image provided: DrMick.jpg
Script used to identify image height in pixels, utilising HOG feature detector + Canny edge detection
Concept:
- Read image and convert to grayscale
- Initialize HOG descriptor and feed in image classification SVM
- Pass in accurate parameters
- Adjust sliding window values / scale to optimise detection
- draw_detections function draws border surrounding the findings of the HOG descriptor
- Inside of border taken and canny is applied to detect edges of person
- Iterate through edges, find lowest point to retrieve Y-value of feet and the height is found
The HOG Descriptor:
The Histogram of Gradients is utilised to find not only the x and y gradiants but the magnitude. This is useful in finding more
information regarding our edges and corners in the image in order to learn about the shapes contained in it. This is fed into
an SVM (getDefaultPeopleDetector) which contains algorithms used to detect features.
Parameters:
winStride - defines the step size in x and y values of the sliding window
padding - defines the amount of pixels our region is padded with PRIOR to the HOG descriptor actually being applied
scale - the image is downsized and smoothed through multiple layers, the greater the scale the less accurate detections may be yet
performance is faster due to a smaller amount of layers. Ultimately, the sliding window as defined in winStride will iterate over
the image at different layers and how many layers there are is defined here.
draw_border():
This function contains the processing done for drawing the border around out detections, Canny edge detection, and finding the
height in pixels.
Input:
img - our source image
rects - this contains our x and y coordinates, along with the width and height that was returned from HOG
thickness - the thickness of our border we will draw
We iterate over each detection, and adjust the frame size of our border (pad_w, pad_h) due to the HOG descriptor
tending to over exaggerate.
cv2.rectangle takes in:
- our image to draw on (passed into the function)
- our start and end X & Y values
- BGR value of rectangle (Green in this case)
- thickness of border, set to 1 as defined at the start of the function
This draws the border around the detected person.
Accessing the pixels defined in the border, this image is cropped leaving only our ROI using the following format
- cropped_region = original[bounding_y_vals:bounding_x_vals]
A small addition to the top, and subtraction from the bottom is made (+2 and -3), to reduce the gap between the head of the person and
the feet from the edge of the image
A threshold of min and max val of 100 and 200 is applied, before utilising Canny edge detection to disern the human shape
without ay remaining noise.
non_zero_points holds all the points in the image that are an edge, effectively where the value is not 0
Due to non_zero_points being an array of tuples (x and y coords) we access the i part of the array, holding the Y values. By
using np.max, with find the top of the head. Due to the feet being the starting point, this will give us the height of our person
in pixels
'''
#######################################################################
# import the necessary packages:
import numpy as np
import cv2
import imutils
from matplotlib import pyplot as plt
from matplotlib import image as image
import easygui
# Opening the images
f = easygui.fileopenbox()
img = cv2.imread(f)
Original = img.copy()
#######################################################################
print("---------------- Height Measurment Tool ----------------")
print(" The Type of image:")
print("1. White background image.")
print("2. Image with a noise in the background.")
print("Note: Press q to exit option 2.")
option = int(input("option choosed: "))
#######################################################################
if option == 1:
# Accessing a pixel's value:
b,g,r = img[1,1]
lowerRange = (b-25, g-25, r-25)
upperRange = (b+50, g+50, r+50)
B = cv2.inRange(img, lowerRange, upperRange)
B=255-B
B, contours,_ = cv2.findContours(B, mode = cv2.RETR_EXTERNAL, method = cv2.CHAIN_APPROX_NONE)
img = cv2.drawContours(img, contours, contourIdx = -1, color = (0,0,255), thickness = 5)
c = max(contours, key=cv2.contourArea)
extTop = tuple(c[c[:, :, 1].argmin()][0])
cv2.circle(img = img, center = extTop, radius = 5, color = (255,0,0), thickness = -1)
extBot = tuple(c[c[:, :, 1].argmax()][0])
cv2.circle(img = img, center = extBot, radius = 5, color = (0,255,0), thickness = -1)
x_Top, y_Top = extTop
x_Bot, y_Bot = extBot
height = (y_Bot-y_Top)
print("---------------- Printing Results ----------------")
print(" The top point: ", extTop)
print(" The bottom point: ", extBot)
print(" The height of the person in pixels: ", height)
# show the output image
cv2.imshow("Result", img)
cv2.waitKey(0)
#######################################################################
elif option == 2:
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
def draw_border(img, rects, thickness = 1):
for x, y, w, h in rects:
# Make the rectangle smaller due to inflated HOG results
pad_w, pad_h = int(0.15*w), int(0.02*h)
cv2.rectangle(img, (x+pad_w, y+pad_h), (x+w-pad_w, y+h-pad_h), (0, 255, 0), thickness)
#crop out contents contained within our rectangle with adjusted height values
drmick = img[y+pad_h+2:y+h-pad_h-3,x+pad_w+2:x+w-pad_w-3]
#Apply Canny Edge detection
edges = cv2.Canny(drmick,100,200)
cv2.imshow("Canny Edges",edges)
non_zero_points = np.where(edges != [0])
maxval = np.max(non_zero_points[0])
print("---------------- Printing Results ----------------")
print "Height in pixels of image = " + str(maxval)
hog = cv2.HOGDescriptor()
hog.setSVMDetector( cv2.HOGDescriptor_getDefaultPeopleDetector() )
found,w=hog.detectMultiScale(img, winStride=(4,4), padding=(8,8), scale=1.10)
draw_border(img,found)
while True:
cv2.imshow("HOG Results", img)
key = cv2.waitKey(0)
if key == ord("r"):
I = Original.copy()
elif key == ord("q"):
break
######################################################################
else:
print("Good bye!")
Reference:
[1]”Python if, if…else, if…elif…else and Nested if Statement”, Programiz.com, 2018. [Online]. Available: https://www.programiz.com/python-programming/if-elif-else. [Accessed: 25- Nov- 2018].






