First we find the smooth contour and then we straighten it into a quadrilateral using approxPolyDP
:
import cv2
import numpy as np
img = cv2.imread(r'c:\TEMP\so57564249.jpg')
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# threshold and shrink mask
_, thresh = cv2.threshold(img_gray, 10, 255, cv2.THRESH_BINARY)
thresh = cv2.erode(thresh, np.ones((10,10), np.uint8), iterations=1)
# find countour
contours,_ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
# straighten contour to quadrilateral
epsilon = 0.001*cv2.arcLength(cnt,True)
while True:
epsilon += epsilon
approx = cv2.approxPolyDP(cnt,epsilon,True)
if len(approx) <= 4:
break
# output
thresh[:,:] = 0
thresh = cv2.fillPoly(thresh, [approx], 255)
img = cv2.bitwise_and(img, img, mask=thresh)
cv2.polylines(img, [approx], True, (0,255,0), 2)

The choice of a kernel size of 10 for removing the blurred margin of the image is more or less arbitrary. You may want to adjust it. To visualize its effect you can add
cv2.polylines(img, [cnt], True, (0,0,255))
after the last line to draw the smooth contour of the initially tresholded image.