warpTriangle.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #!/usr/bin/env python
  2. # Copyright (c) 2016 Satya Mallick <spmallick@learnopencv.com>
  3. # All rights reserved. No warranty, explicit or implicit, provided.
  4. import cv2
  5. import numpy as np
  6. # Warps and alpha blends triangular regions from img1 and img2 to img
  7. def warpTriangle(img1, img2, tri1, tri2) :
  8. # Find bounding rectangle for each triangle
  9. r1 = cv2.boundingRect(tri1)
  10. r2 = cv2.boundingRect(tri2)
  11. # Offset points by left top corner of the respective rectangles
  12. tri1Cropped = []
  13. tri2Cropped = []
  14. for i in xrange(0, 3):
  15. tri1Cropped.append(((tri1[0][i][0] - r1[0]),(tri1[0][i][1] - r1[1])))
  16. tri2Cropped.append(((tri2[0][i][0] - r2[0]),(tri2[0][i][1] - r2[1])))
  17. # Crop input image
  18. img1Cropped = img1[r1[1]:r1[1] + r1[3], r1[0]:r1[0] + r1[2]]
  19. # Given a pair of triangles, find the affine transform.
  20. warpMat = cv2.getAffineTransform( np.float32(tri1Cropped), np.float32(tri2Cropped) )
  21. # Apply the Affine Transform just found to the src image
  22. img2Cropped = cv2.warpAffine( img1Cropped, warpMat, (r2[2], r2[3]), None, flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_REFLECT_101 )
  23. # Get mask by filling triangle
  24. mask = np.zeros((r2[3], r2[2], 3), dtype = np.float32)
  25. cv2.fillConvexPoly(mask, np.int32(tri2Cropped), (1.0, 1.0, 1.0), 16, 0);
  26. img2Cropped = img2Cropped * mask
  27. # Copy triangular region of the rectangular patch to the output image
  28. img2[r2[1]:r2[1]+r2[3], r2[0]:r2[0]+r2[2]] = img2[r2[1]:r2[1]+r2[3], r2[0]:r2[0]+r2[2]] * ( (1.0, 1.0, 1.0) - mask )
  29. img2[r2[1]:r2[1]+r2[3], r2[0]:r2[0]+r2[2]] = img2[r2[1]:r2[1]+r2[3], r2[0]:r2[0]+r2[2]] + img2Cropped
  30. if __name__ == '__main__' :
  31. # Read input image
  32. imgIn = cv2.imread("robot.jpg")
  33. # Output image is set to white
  34. imgOut = 255 * np.ones(imgIn.shape, dtype = imgIn.dtype)
  35. # Input triangle
  36. triIn = np.float32([[[360,200], [60,250], [450,400]]])
  37. # Output triangle
  38. triOut = np.float32([[[400,200], [160,270], [400,400]]])
  39. # Warp all pixels inside input triangle to output triangle
  40. warpTriangle(imgIn, imgOut, triIn, triOut)
  41. # Draw triangle using this color
  42. color = (255, 150, 0)
  43. # Draw triangles in input and output images.
  44. cv2.polylines(imgIn, triIn.astype(int), True, color, 2, 16)
  45. cv2.polylines(imgOut, triOut.astype(int), True, color, 2, 16)
  46. cv2.imshow("Input", imgIn)
  47. cv2.imshow("Output", imgOut)
  48. cv2.waitKey(0)