<jupyter_start><jupyter_text>Finding Contours  Import resources and display image<jupyter_code>import numpy as np
import matplotlib.pyplot as plt
import cv2

%matplotlib inline

# Read in the image
image = cv2.imread('images/thumbs_up_down.jpg')

# Change color to RGB (from BGR)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

plt.imshow(image)<jupyter_output><empty_output><jupyter_text>Produce a binary image for finding contours<jupyter_code># Convert to grayscale
gray = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY)

# Create a binary thresholded image
retval, binary = cv2.threshold(gray, 230, 255, cv2.THRESH_BINARY_INV)
#retval, binary = cv2.threshold(gray, 230, 255, cv2.THRESH_BINARY)

plt.imshow(binary, cmap='gray')<jupyter_output><empty_output><jupyter_text>Find and draw the contours<jupyter_code># Find contours from thresholded, binary image
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# Draw all contours on a copy of the original image
contours_image = np.copy(image)
contours_image = cv2.drawContours(contours_image, contours, -1, (0,255,0), 3)

plt.imshow(contours_image)
print(contours[1])
#print(contours.lenght)<jupyter_output>[[[172  60]]

 [[169  63]]

 [[169  65]]

 [[168  66]]

 [[168  67]]

 [[167  68]]

 [[167  69]]

 [[166  70]]

 [[166  71]]

 [[165  72]]

 [[165  73]]

 [[164  74]]

 [[164  75]]

 [[163  76]]

 [[163  77]]

 [[162  78]]

 [[162  79]]

 [[160  81]]

 [[160  82]]

 [[159  83]]

 [[159  84]]

 [[157  86]]

 [[157  87]]

 [[156  88]]

 [[156  89]]

 [[153  92]]

 [[153  93]]

 [[143 103]]

 [[142 103]]

 [[134 111]]

 [[134 112]]

 [[132 114]]

 [[132 115]]

 [[128 119]]

 [[128 120]]

 [[115 133]]

 [[115 134]]

 [[112 137]]

 [[112 138]]

 [[111 139]]

 [[111 140]]

 [[110 141]]

 [[108 141]]

 [[107 142]]

 [[105 142]]

 [[104 143]]

 [[ 96 143]]

 [[ 95 142]]

 [[ 78 142]]

 [[ 77 141]]

 [[ 76 141]]

 [[ 75 142]]

 [[ 74 141]]

 [[ 69 141]]

 [[ 68 140]]

 [[ 64 140]]

 [[ 63 139]]

 [[ 57 139]]

 [[ 56 138]]

 [[ 51 138]]

 [[ 50 137]]

 [[ 43 137]]

 [[ 42 136]]

 [[ 38 136]]

 [[ 37 135]]

 [[ 30 135]]

 [[ 29 134]]

 [[ 25 134]]

 [[ 24 133]]

 [[ 19 133]]

 [[ 18 132]]

 [[ 13[...]<jupyter_text>Contour FeaturesEvery contour has a number of features that you can calculate, including the area of the contour, it's orientation (the direction that most of the contour is pointing in), it's perimeter, and many other properties outlined in [OpenCV documentation, here](http://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_contours/py_contour_properties/py_contour_properties.html).In the next cell, you'll be asked to identify the orientations of both the left and right hand contours. The orientation should give you an idea of which hand has its thumb up and which one has its thumb down!  OrientationThe orientation of an object is the angle at which an object is directed. To find the angle of a contour, you should first find an ellipse that fits the contour and then extract the `angle` from that shape. ```python Fit an ellipse to a contour and extract the angle from that ellipse(x,y), (MA,ma), angle = cv2.fitEllipse(selected_contour)```**Orientation values**These orientation values are in degrees measured from the x-axis. A value of zero means a flat line, and a value of 90 means that a contour is pointing straight up!So, the orientation angles that you calculated for each contour should be able to tell us something about the general position of the hand. The hand with it's thumb up, should have a higher (closer to 90 degrees) orientation than the hand with it's thumb down. TODO: Find the orientation of each contour<jupyter_code>## TODO: Complete this function so that 
## it returns the orientations of a list of contours
## The list should be in the same order as the contours
## i.e. the first angle should be the orientation of the first contour
def orientations(contours):
    """
    Orientation 
    :param contours: a list of contours
    :return: angles, the orientations of the contours
    """
    
    # Create an empty list to store the angles in
    # Tip: Use angles.append(value) to add values to this list
    angles = []
    for selected_contour in contours:
        (x,y), (MA,ma), angle = cv2.fitEllipse(selected_contour)
        angles.append(angle)
    
    return angles


# ---------------------------------------------------------- #
# Print out the orientation values
angles = orientations(contours)
print('Angles of each contour (in degrees): ' + str(angles))<jupyter_output>Angles of each contour (in degrees): [61.08085632324219, 82.78831481933594]<jupyter_text>Bounding RectangleIn the next cell, you'll be asked to find the bounding rectangle around the *left* hand contour, which has its thumb up, then use that bounding rectangle to crop the image and better focus on that one hand!```python Find the bounding rectangle of a selected contourx,y,w,h = cv2.boundingRect(selected_contour) Draw the bounding rectangle as a purple boxbox_image = cv2.rectangle(contours_image, (x,y), (x+w,y+h), (200,0,200),2)```And to crop the image, select the correct width and height of the image to include.```python Crop using the dimensions of the bounding rectangle (x, y, w, h)cropped_image = image[y: y + h, x: x + w] ``` TODO: Crop the image around a contour<jupyter_code>## TODO: Complete this function so that
## it returns a new, cropped version of the original image
def left_hand_crop(image, selected_contour):
    """
    Left hand crop 
    :param image: the original image
    :param selectec_contour: the contour that will be used for cropping
    :return: cropped_image, the cropped image around the left hand
    """
    
    ## TODO: Detect the bounding rectangle of the left hand contour
    x,y,w,h = cv2.boundingRect(selected_contour)
    ## TODO: Crop the image using the dimensions of the bounding rectangle
    # Make a copy of the image to crop
    cropped_image = np.copy(image)
    cropped_image = cropped_image[y: y + h, x: x + w]
    
    return cropped_image


## TODO: Select the left hand contour from the list
## Replace this value
selected_contour = contours[1]


# ---------------------------------------------------------- #
# If you've selected a contour
if(selected_contour is not None):
    # Call the crop function with that contour passed in as a parameter
    cropped_image = left_hand_crop(image, selected_contour)
    plt.imshow(cropped_image)<jupyter_output><empty_output>
StarcoderdataJupyterStructuredCleanDedup