Ich benutze derzeit die Bildbibliothek opencv (CV2) und Python Pillow, um ein Bild von beliebigen Telefonen zu erstellen und den Bildschirm durch ein neues Bild zu ersetzen. Ich bin an den Punkt gekommen, wo ich ein Bild machen und den Bildschirm des Telefons identifizieren kann und alle Koordinaten für die Ecke bekommen kann, aber es fällt mir sehr schwer, diesen Bereich im Bild durch ein neues zu ersetzen.Wie ersetzt man eine Kontur (Rechteck) in einem Bild mit einem neuen Bild mit Python?
Der Code habe ich bisher:
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)
Das ist mir ein Bild geben, das wie folgt aussieht:
ich auch die Koordinaten der Bildschirmecken mit dieser Zeile Code bekommen:
screenCoords = [x[0].tolist() for x in screenCnt]
// [[398, 139], [245, 258], [474, 487], [628, 358]]
jedoch habe ich nicht für das Leben von mir herausfinden, wie ein neues Bild zu nehmen und es in die Form des Raumkoordinatenmaßstabs ich gefunden habe und overl ay das Bild ontop.
Meine Vermutung ist, dass ich das tun kann, ein Bild umwandeln in Kissen mit dieser Funktion, die ich von this stackoverflow question angepasst:
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)
Jedoch habe ich in über meinem Kopf bin ein bisschen, und ich kann nicht Informiere dich über die Details. Könnte mir jemand helfen?
EDIT
Ok jetzt, dass ich die getPerspectiveTransform und warpPerspective Funktionen verwenden, habe ich die folgenden zusätzlichen Code bekam:
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)
Das Bild wird gedreht zu werden und verzerrt richtig (glaube ich) , aber es ist nicht die gleiche Größe wie der Bildschirm. Seine „kürzer“:
und wenn ich ein anderes Bild verwenden, das sehr groß vertikal ist ich am Ende mit etwas, das zu „lang“ ist:
Muß ich eine zusätzliche Transformation anwenden, um das Bild zu skalieren? Ich bin mir nicht sicher, was hier vor sich geht, ich dachte, die perspektivische Transformation würde das Bild automatisch auf die angegebenen Koordinaten skalieren lassen.
Ich denke nicht, das vollständig das Problem löst. Der Bildschirm, den ich im Bild finde, ist normalerweise kein perfektes Rechteck, deshalb ist das Drehen des Bildes nicht ausreichend, ich muss auch die Perspektive so transformieren, dass sie der Kontur entspricht, die ich gefunden habe. Ist das sinnvoll? –
Sie könnten eine umgekehrte perspektivische Transformation tun – user3404344
Könnten Sie mir etwas mehr Details geben? Ich bin ein kompletter Anfänger zu opencv, Bildverarbeitung und Vektor Mathe –