我目前使用opencv(CV2)和Python Pillow圖像庫嘗試拍攝任意手機的圖像,並用新圖像替換屏幕。我已經到了可以拍攝圖像並識別手機屏幕並獲得角落所有座標的位置,但我很難用新圖像替換圖像中的該區域。如何使用Python替換圖像中的輪廓(矩形)和新圖像?
的代碼,我到目前爲止有:
import cv2
from PIL import Image
image = cv2.imread('mockup.png')
edged_image = cv2.Canny(image, 30, 200)
(contours, _) = cv2.findContours(edged_image.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours = sorted(contours, key = cv2.contourArea, reverse = True)[:10]
screenCnt = None
for contour in contours:
peri = cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, 0.02 * peri, True)
# if our approximated contour has four points, then
# we can assume that we have found our screen
if len(approx) == 4:
screenCnt = approx
break
cv2.drawContours(image, [screenCnt], -1, (0, 255, 0), 3)
cv2.imshow("Screen Location", image)
cv2.waitKey(0)
我還可以得到使用這行代碼的屏幕角的座標:
screenCoords = [x[0].tolist() for x in screenCnt]
// [[398, 139], [245, 258], [474, 487], [628, 358]]
但是我想不出我的生活中如何採取新的圖像,並將其擴展到我已經找到了座標空間的形狀和,可欣賞唉圖像ontop。
我的猜測是,我可以通過使用此功能,我改編自this stackoverflow question在枕頭的圖像變換做到這一點:
def find_transform_coefficients(pa, pb):
"""Return the coefficients required for a transform from start_points to end_points.
args:
start_points -> Tuple of 4 values for start coordinates
end_points --> Tuple of 4 values for end coordinates
"""
matrix = []
for p1, p2 in zip(pa, pb):
matrix.append([p1[0], p1[1], 1, 0, 0, 0, -p2[0]*p1[0], -p2[0]*p1[1]])
matrix.append([0, 0, 0, p1[0], p1[1], 1, -p2[1]*p1[0], -p2[1]*p1[1]])
A = numpy.matrix(matrix, dtype=numpy.float)
B = numpy.array(pb).reshape(8)
res = numpy.dot(numpy.linalg.inv(A.T * A) * A.T, B)
return numpy.array(res).reshape(8)
但是我在我頭上了一下,我不能獲得詳細信息。有人能給我一些幫助嗎?
編輯
好了,現在我使用的getPerspectiveTransform和warpPerspective功能,我有以下附加代碼:
screenCoords = numpy.asarray(
[numpy.asarray(x[0], dtype=numpy.float32) for x in screenCnt],
dtype=numpy.float32
)
overlay_image = cv2.imread('123.png')
overlay_height, overlay_width = image.shape[:2]
input_coordinates = numpy.asarray(
[
numpy.asarray([0, 0], dtype=numpy.float32),
numpy.asarray([overlay_width, 0], dtype=numpy.float32),
numpy.asarray([overlay_width, overlay_height], dtype=numpy.float32),
numpy.asarray([0, overlay_height], dtype=numpy.float32)
],
dtype=numpy.float32,
)
transformation_matrix = cv2.getPerspectiveTransform(
numpy.asarray(input_coordinates),
numpy.asarray(screenCoords),
)
warped_image = cv2.warpPerspective(
overlay_image,
transformation_matrix,
(background_width, background_height),
)
cv2.imshow("Overlay image", warped_image)
cv2.waitKey(0)
圖像是越來越旋轉和扭曲正常(我認爲) ,但與屏幕尺寸不一樣。它的「短」:
,如果我使用不同的圖像,這是非常高的垂直我最終的東西是太「長」:
我需要應用額外的轉換來縮放圖像?不知道這裏發生了什麼,我認爲透視變換會使圖像自動縮放到提供的座標。
我不認爲雖然這徹底解決了這個問題。我在圖像中找到的屏幕通常不是一個完美的矩形,因此旋轉圖像是不夠的,我還需要轉換透視圖以使其與我找到的輪廓相匹配。那有意義嗎? –
你可以做一個反向透視轉換 – user3404344
你能給我更多的細節嗎?我是一個完整的noob opencv,圖像處理和向量數學 –