Skip to content
Advertisement

OpenCV transform image shape transformation into a given contour

Does anyone know whether it’s possible to transform image A into image B contour if their shapes are random, using OpenCV or any other python libraries that work with images?

Here is what I have so far with 2 images:

I’ve been able to find draw contours of the bulb and insert a fox in it using bitwise_and method, but what it does is it crops the second image, whereas I need it to transform its shape into the bulb contour.

JavaScript

Bulb original image:

Fox original image:

Bulb contour:

Advertisement

Answer

The Concept

For this we are going to need to slice the into triangles, and warp each triangle individually. The starting points of the image should be along the outline of the original image, and the ending points should be along the outline of the destination shape.

Although below I have hard-coded the 2 sets of points, you’ll just need to figure out the optimal processing to retrieve the contours of the 2 images (each needs have the same number of points and in the same order). Also, I have programmed an interactive OpenCV program that will allow us to easily retrieve the coordinates.

The Code

JavaScript

The Output

enter image description here

The Explanation

  1. Import the necessary libraries:
JavaScript
  1. Define a function, triangles, that will take in an array of coordinates, points, and yield lists of 3 indices of the array for triangles that will cover the area of the original array of coordinates:
JavaScript
  1. Define a function, crop, that will take in an image array, img, and an array of three coordinates, pts. It will return a rectangular segment of the image just large enough to fit the triangle formed by the three point, and return the array of three coordinates transferred to the top-left corner of image:
JavaScript
  1. Define a function, warp, that will take in 2 image arrays, img1 and img2, and 2 arrays of coordinates, pts1 and pts2. It will utilize the triangles function defined before iterate through the triangles from the first array of coordinates, the crop function defined before to crop both images at coordinates corresponding to the triangle indices and use the cv2.warpAffine() method to warp the image at the current triangle of the iterations:
JavaScript
  1. Read in your images. Note that I have resized the images to better fit my screen. If you remove the resizing part, you’ll need to use the program below to re-adjust the points and get the corrected sets of points:
JavaScript
  1. Finally, define the 2 sets of points; the first set outlining the first image, and the second one outlining the second. Use the warp function defined before to warp img1 to have its keypoints overlap with the kewpoints of img2 and show the resulting image:
JavaScript

Tools

Use the program below to manually drag the point onto each image, and see the warp effect in real-time. Of course, rather than manually doing this, you can detect the contours of the two images (make sure that they have the same number of points and are in the same order):

JavaScript

enter image description here

Here is a rough demonstration of how it works (sped up x4):

enter image description here

If the real-time warping is too slow on your computer, simply press the p key to pause the warp updating, and press it again to resume it.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement