I am trying to make a perspective transformation with opencv. I want to extract screen from my e-book and align it.
First, I found a biggest contour and put it screenCnt2 variable. After that I extracted values to 2 lists:
x1_1 = [i[0] for j in screenCnt2 for i in j]
y1_1 = [i[1] for j in screenCnt2 for i in j]
Then, I calculated max_width and max_height of my subimage inside contours:
len_yr = np.sqrt((x1_1[1] - x1_1[0]) ** 2 + (y1_1[0] - y1_1[1])**2)
len_rb = np.sqrt((x1_1[1] - x1_1[2])**2 + (y1_1[2] - y1_1[1])**2)
len_bg = np.sqrt((x1_1[2] - x1_1[3])**2 + (y1_1[2] - y1_1[3])**2)
len_gy = np.sqrt((y1_1[3] - y1_1[0])**2 + (x1_1[0] - x1_1[3])**2)
print(len_yr, len_rb, len_bg, len_gy)
max_width = max(int(len_yr), int(len_bg))
max_height = max(int(len_gy), int(len_rb))
And finally apply perspective transforming
p1 = [i for i in zip(x1_1,y1_1)]
pts1 = np.float32(p1)
pts2 = np.float32([[0,0],[max_width - 1,0],[max_width - 1, max_height - 1],[0, max_height -1 ]])
M = cv2.getPerspectiveTransform(pts1,pts2)
dst2 = cv2.warpPerspective(seg_im3, M, (max_width, max_height))
x1_2 = [i[0] for i in pts2]
y1_2 = [i[1] for i in pts2]
plt.figure(figsize=(10, 10))
plt.subplot(121),plt.imshow(angle_im2[:, :, ::-1]),plt.title('Input')
plt.scatter(x1_1, y1_1, color = colors)
for x, y, color in zip(x1_1, y1_1, colors):
plt.text(x, y, f'[{int(x)},{int(y)}]', color = color)
plt.subplot(122),plt.imshow(dst2[:, :, ::-1]),plt.title('Output')
plt.scatter(x1_2, y1_2, color = colors)
for x, y, color in zip(x1_2, y1_2, colors):
plt.text(x, y, f'[{int(x)},{int(y)}]', color = color)
plt.show()
I have no idea what I am doing wrong, because same code works fine with another image:

//EDIT
The red rectangle at first image is a biggest contour. To find it I use these 2 functions: adjust gamma to make image darker
def adjust_gamma(image, gamma=1.0):
invGamma = 1.0 / gamma
table = np.array([((i / 255.0) ** invGamma) * 255
for i in np.arange(0, 256)]).astype("uint8")
return cv2.LUT(image, table)
Then I found all contours and took the biggest:
def find_biggest_cnt(img):
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thrash = cv2.threshold(img_gray, 35 , 200, cv2.CHAIN_APPROX_NONE)
cnts = cv2.findContours(thrash,cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
cnts = imutils.grab_contours(cnts)
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:5]
for c in cnts:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
if len(approx) == 4:
screenCnt = approx
break
return screenCnt


