You can use OpenCV Contours and masking algorithms and by using Bitwise AND operation between this bounding rectangle(counter) and mask, we can crop out polygon from Image.
Here are few points to look at before taking and running this code.
Links are for images
cv2.boundingRect => It will create bounding rectangle look at image for best visualization
With and Without Bounding Rectangle
cv2.drawContours => It will update mask where ever points lie inside our counter.
Mask with and Without Contours extract
cv2.bitwise_and => For this you can refer to :
Stackoverflow Discussion over cv2.bitwise_and(img,img,mask = mask)
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as img
import matplotlib.patches as patches 
import cv2
image_file = 'photo.jpg'
def selection(s):
    plt.title(s, fontsize=16)
    plt.axis('off')
    plt.draw()
# =========   Saving Click Point using ginput method   =========
while True:
    data = []
    while len(data) < 3:
        image = img.imread(image_file)
        fig, ax=plt.subplots()
        ax.imshow(image,cmap="gray")
        selection('Free Form Selection')
        data = np.asarray(plt.ginput(0, timeout=-1))
        if len(data) < 3:
            selection('Free Form Selection')
    
    # =========   Counter-Dimension   =========        
    minXY = data.min(axis= 0)
    maxXY = data.max(axis= 0)
    delXY = maxXY - minXY
    
    # =========   Counter with Free-Form Selection   =========
    counter = plt.fill(data[:, 0], data[:, 1], '#f0f0f0', edgecolor='#000000', linewidth= 0.5)
    rect = patches.Rectangle(minXY, delXY[0], delXY[1], linewidth= 0.5, edgecolor='#000000', facecolor="none") 
    
    # =========   Add the patch to the Axes   ========= 
    ax.add_patch(rect) 
    selection('          ')
    if plt.waitforbuttonpress():
        break
    # Get rid of fill
    for c in counter:
        c.remove()
# ========= Saving Point of Polygon to CSV file =========
np.savetxt('data.csv', data, delimiter=',')
# =========   Using OpenCV We can crop polygon of Image  =========
img = cv2.imread(image_file)
pts = np.array(data, dtype='int32')             # => datatype should be int32
# =========    Crop the Bounding Rectangle  =========
rect = cv2.boundingRect(pts)
x,y,w,h = rect
croped = img[y:y+h, x:x+w].copy()
# =========   Making Mask  =========
pts = pts - pts.min(axis=0)
mask = np.zeros(croped.shape[:2], np.uint8)
cv2.drawContours(mask, [pts], -1, (255, 255, 255), -1, cv2.LINE_AA)
# =========   BitWise Operation   =========
dst = cv2.bitwise_and(croped, croped, mask=mask)
# =========   Final Result  =========
cv2.imwrite("dst.png", dst)
img = cv2.imread('dst.png')
cv2.imshow('Image', img)
cv2.waitKey(0)