私は現在、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)
私もこのコード行を使用して、画面の隅の座標を取得することができます:私は新しいイメージを取り、私が見つけた座標空間の形状とoverlにそれを拡張する方法を私の人生のために把握することはできませんしかし
screenCoords = [x[0].tolist() for x in screenCnt]
// [[398, 139], [245, 258], [474, 487], [628, 358]]
画像のオンタップ。
私の推測では、私はイメージが私が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)
私は私の頭の上で少しだし、私はできませんしかし、細部を正しく理解してください。誰かが私に助けてくれますか?
EDIT
OK]をクリックして、今、私が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
詳細を教えてください。私はopencv、画像処理、ベクトル数学の完全なnoobです –