top of page

Computer Graphics Lab

CSE:3016

Faculty In charge : Prof. Rajesh Kanna

Home: Welcome
Home: Blog2
Search

MULTIMEDIA EXPERIMENTS

Writer's picture: theBloggerstheBloggers

1. Morphing two images


Python code using OpenCV:


import numpy as np

import cv2

import sys


# Read points from text file

def readPoints(path) :

# Create an array of points.

points = [];

# Read points

with open(path) as file :

for line in file :

x, y = line.split()

points.append((int(x), int(y)))


return points


# Apply affine transform calculated using srcTri and dstTri to src and

# output an image of size.

def applyAffineTransform(src, srcTri, dstTri, size) :

# Given a pair of triangles, find the affine transform.

warpMat = cv2.getAffineTransform( np.float32(srcTri), np.float32(dstTri) )

# Apply the Affine Transform just found to the src image

dst = cv2.warpAffine( src, warpMat, (size[0], size[1]), None, flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_REFLECT_101 )


return dst



# Warps and alpha blends triangular regions from img1 and img2 to img

def morphTriangle(img1, img2, img, t1, t2, t, alpha) :


# Find bounding rectangle for each triangle

r1 = cv2.boundingRect(np.float32([t1]))

r2 = cv2.boundingRect(np.float32([t2]))

r = cv2.boundingRect(np.float32([t]))



# Offset points by left top corner of the respective rectangles

t1Rect = []

t2Rect = []

tRect = []



for i in range(0, 3):

tRect.append(((t[i][0] - r[0]),(t[i][1] - r[1])))

t1Rect.append(((t1[i][0] - r1[0]),(t1[i][1] - r1[1])))

t2Rect.append(((t2[i][0] - r2[0]),(t2[i][1] - r2[1])))



# Get mask by filling triangle

mask = np.zeros((r[3], r[2], 3), dtype = np.float32)

cv2.fillConvexPoly(mask, np.int32(tRect), (1.0, 1.0, 1.0), 16, 0);


# Apply warpImage to small rectangular patches

img1Rect = img1[r1[1]:r1[1] + r1[3], r1[0]:r1[0] + r1[2]]

img2Rect = img2[r2[1]:r2[1] + r2[3], r2[0]:r2[0] + r2[2]]


size = (r[2], r[3])

warpImage1 = applyAffineTransform(img1Rect, t1Rect, tRect, size)

warpImage2 = applyAffineTransform(img2Rect, t2Rect, tRect, size)


# Alpha blend rectangular patches

imgRect = (1.0 - alpha) * warpImage1 + alpha * warpImage2


# Copy triangular region of the rectangular patch to the output image

img[r[1]:r[1]+r[3], r[0]:r[0]+r[2]] = img[r[1]:r[1]+r[3], r[0]:r[0]+r[2]] * ( 1 - mask ) + imgRect * mask



if __name__ == '__main__' :


filename1 = 'hillary_clinton.jpg'

filename2 = 'donald_trump.jpg'

alpha = 0.5

# Read images

img1 = cv2.imread(filename1);

img2 = cv2.imread(filename2);

# Convert Mat to float data type

img1 = np.float32(img1)

img2 = np.float32(img2)


# Read array of corresponding points

points1 = readPoints(filename1 + '.txt')

points2 = readPoints(filename2 + '.txt')

points = [];


# Compute weighted average point coordinates

for i in range(0, len(points1)):

x = ( 1 - alpha ) * points1[i][0] + alpha * points2[i][0]

y = ( 1 - alpha ) * points1[i][1] + alpha * points2[i][1]

points.append((x,y))



# Allocate space for final output

imgMorph = np.zeros(img1.shape, dtype = img1.dtype)


# Read triangles from tri.txt

with open("tri.txt") as file :

for line in file :

x,y,z = line.split()

x = int(x)

y = int(y)

z = int(z)

t1 = [points1[x], points1[y], points1[z]]

t2 = [points2[x], points2[y], points2[z]]

t = [ points[x], points[y], points[z] ]


# Morph one triangle at a time.

morphTriangle(img1, img2, imgMorph, t1, t2, t, alpha)



# Display Result

cv2.imshow("Morphed Face", np.uint8(imgMorph))

cv2.waitKey(0)



Source image 1: Ted Cruz


Source image 2: Hilary Clinton



Final Output after Face Morphing of Hillary Clinton and Ted Cruz


2. Warping


Python code:


import numpy as np

from PIL import Image


def quad_as_rect(quad):

if quad[0] != quad[2]: return False

if quad[1] != quad[7]: return False

if quad[4] != quad[6]: return False

if quad[3] != quad[5]: return False

return True


def quad_to_rect(quad):

assert(len(quad) == 8)

assert(quad_as_rect(quad))

return (quad[0], quad[1], quad[4], quad[3])


def rect_to_quad(rect):

assert(len(rect) == 4)

return (rect[0], rect[1], rect[0], rect[3], rect[2], rect[3], rect[2], rect[1])


def shape_to_rect(shape):

assert(len(shape) == 2)

return (0, 0, shape[0], shape[1])


def griddify(rect, w_div, h_div):

w = rect[2] - rect[0]

h = rect[3] - rect[1]

x_step = w / float(w_div)

y_step = h / float(h_div)

y = rect[1]

grid_vertex_matrix = []

for _ in range(h_div + 1):

grid_vertex_matrix.append([])

x = rect[0]

for _ in range(w_div + 1):

grid_vertex_matrix[-1].append([int(x), int(y)])

x += x_step

y += y_step

grid = np.array(grid_vertex_matrix)

return grid


def distort_grid(org_grid, max_shift):

new_grid = np.copy(org_grid)

x_min = np.min(new_grid[:, :, 0])

y_min = np.min(new_grid[:, :, 1])

x_max = np.max(new_grid[:, :, 0])

y_max = np.max(new_grid[:, :, 1])

new_grid += np.random.randint(- max_shift, max_shift + 1, new_grid.shape)

new_grid[:, :, 0] = np.maximum(x_min, new_grid[:, :, 0])

new_grid[:, :, 1] = np.maximum(y_min, new_grid[:, :, 1])

new_grid[:, :, 0] = np.minimum(x_max, new_grid[:, :, 0])

new_grid[:, :, 1] = np.minimum(y_max, new_grid[:, :, 1])

return new_grid


def grid_to_mesh(src_grid, dst_grid):

assert(src_grid.shape == dst_grid.shape)

mesh = []

for i in range(src_grid.shape[0] - 1):

for j in range(src_grid.shape[1] - 1):

src_quad = [src_grid[i , j , 0], src_grid[i , j , 1],

src_grid[i + 1, j , 0], src_grid[i + 1, j , 1],

src_grid[i + 1, j + 1, 0], src_grid[i + 1, j + 1, 1],

src_grid[i , j + 1, 0], src_grid[i , j + 1, 1]]

dst_quad = [dst_grid[i , j , 0], dst_grid[i , j , 1],

dst_grid[i + 1, j , 0], dst_grid[i + 1, j , 1],

dst_grid[i + 1, j + 1, 0], dst_grid[i + 1, j + 1, 1],

dst_grid[i , j + 1, 0], dst_grid[i , j + 1, 1]]

dst_rect = quad_to_rect(dst_quad)

mesh.append([dst_rect, src_quad])

return mesh


im = Image.open('hillary_clinton.jpg')

dst_grid = griddify(shape_to_rect(im.size), 4, 4)

src_grid = distort_grid(dst_grid, 50)

mesh = grid_to_mesh(src_grid, dst_grid)

im = im.transform(im.size, Image.MESH, mesh)

im.show()



Warping a given image



23 views0 comments

Recent Posts

See All

Comments


Home: Blog Feed

Meet theBloggers !

This Blog was created by students of Computer Graphics and Design Class (CSE3016) with sole purpose of relaying information of the different activities performed throughout the course period.

theBloggers
Ibra Nafis - 17BCE1230

Bhavya S Chauhan - 17BCE1270

Home: About

© Proudly created with Wix.com

bottom of page