  # Implementation of photomosaics

File handling | NumPy | Python Methods and Functions

Photomosaic — it is an image, broken down into a grid of rectangles, each of which is replaced by a different image that suits the purpose (the image you ultimately want to display in this photo). In other words, if you look at the mosaic from a distance, you will see an image of the target; but if you get closer, you can see that the image is actually made up of many small images. This works because of the way the human eye works.

There are two kinds of mosaics, depending on how the matching is done. In a simpler form, each portion of the target image is averaged to one color. Each of the images in the library is also reduced to one color. Each part of the target image is then replaced with one part from the library where the colors are as similar as possible. Essentially, the target image is downsampled (downsampled) and then each of the resulting pixels is replaced with an image whose average color corresponds to that pixel.

In a more advanced form of photographic mosaic, the target image is not downsampled. and matching is performed by comparing each pixel in the rectangle with a corresponding pixel from each library image. The rectangle in the target is then replaced with the library image, which minimizes the overall difference. This is much more computationally intensive than the simple type, but the results can be much better as the pixel-by-pixel matching can preserve the resolution of the target image.

How do I create a photo mosaic?

1. Read the tile images that will replace the tiles in the original image.
2. Read the target image and break it down into an M × N grid of tiles.
3. For each tile, find the best match from the input images.
4. Create a final mosaic by positioning the selected input images on an M × N grid

Tiling images

Now let`s see how to calculate coordinates for one tile from this grid. A tile with index (i, j) has an upper left corner coordinate (i * w, i * j) and a lower right corner coordinate ((i + 1) * w, (j + 1) * h), where w and h denote the width and height of the tiles, respectively. They can be used with PIL to crop and tile this image.

Averaging color values ​​

Every pixel in an image has a color that can be represented its values ​​for red, green and blue. In this case, you are using 8-bit images, so each of these components has an 8-bit value in the range [0, 255]. For an image with a total of N pixels, the average RGB value is calculated as follows: Matching Images

For each tile in the target image, you need to find the matching image from the images in the user-specified input folder. Use RGB averages to determine if two images are the same. The closest match is the image with the nearest RGB mean.
The easiest way to do this is — calculate the distance between RGB values ​​in a pixel to find the best match among the input images. You can use the following distance calculation for 3D points from geometry: Now let`s try to code this

 ` # Import required libraries ` ` import ` ` os, random, argparse ` ` from ` ` PIL ` ` import ` ` Image ` ` import imghdr ```` import numpy as np   def getAverageRGBOld (image ): "" »   For a given PIL image, return the average color value as (r, g, b) "" "   # # of pixels in the image   npixels = image.size [ 0 ] * image.size [ 1 ] # get colors as [(cnt1, (r1, g1, b1)), ...] cols = image.getcolors (npixels)   # get [(c1 * r1, c1 * g1, c1 * g2), ...] sumRGB = [(x [ 0 ] * x [ 1 ] [ 0 ], x [ 0 ] * x [ 1 ] [ 1 ], x [ 0 ] * x [ 1 ] [ 2 ]) for x in cols]  # calculate (sum (ci * ri) / np, sum (ci * gi) / np, sum (ci * bi) / np) # zip code gives us [(c1 * r1, c2 * r2, ..), (c1 * g1, c1 * g2, ...) ...] avg = tuple ([ int ( sum (x) / npixels) for x in zip ( * sumRGB)]) r eturn avg   def getAverageRGB (image):   " "" For a given PIL image, return the average color value as (r, g, b) "" " # get the image as an array   im = np.array (image) # get the form w, h, d = im.shape # get average return tuple (np.average (im.reshape (w * h, d), axis = 0 ))   def splitImage (image, size): " "" Given Image and dims (rows, cols) return m * n image list "" " W, H = image.size [ 0 ], image.size [ 1 ] m, n = size w, h = int (W / n), int (H / m) # list of images imgs = [] # create a list of dimensions for j in range (m): for i in range (n) : # add cropped image imgs.append (image.crop ((i * w, j * h, (i + 1 ) * w, (j + 1 ) * h))) return imgs   def getImages (imageDir): "" "   given the image directory, return a list of images "" "   files = os.listdir (imageDir) images = []   for file in files: filePath = os.path.abspath ( os.path.join ( (imageDir, file ) ) try : # explicit loading, so we don`t face resource overload fp = open (filePath, "rb" ) im = Image. open (fp)   images.append (im) # force loading image data from file im.load ()  # close the file fp.close ()  except : # skip print ( "Invalid image:% s" % (filePath,)) return images    def getImageFilenames (imageDir): "" "   given the image directory, return a list of image file names "" "   files = os.listdir (imageDir) filenames = []   for file in files: filePath = os.path.abspath ( os.path.join ( (imageDir, file )) try :   imgType = imghdr.what (filePath)  if imgType: filenames.append ( filePath) except : # skip print ( " Invalid image:% s " % (filePath,))   return filenames    def getBestMatchIndex (input_avg, avgs): "" "   index to return the best matching image based on distance to RGB value "" "   # average value of the input image avg = input_avg   # get closest input RGB value based on x / y / z distance index = 0   min_index = 0 min_dist = float ( "inf" ) for val in avgs: dist = ((val [ 0 ] - avg [ 0 ]) * ( val [ 0 ] - avg [ 0 ]) + (val [ 1 ] - avg [ 1 ]) * (val [ 1 ] - avg [ 1 ]) + (val [ 2 ] - avg [ 2 ]) * (val [ 2 ] - avg [ 2 ])) if dist & lt; min_dist: mi n_dist = dist   min_index = index index + = 1   return min_index     def createImageGrid (images, dims): "" " Given the image list and grid size (m, n), create image grid.   “ »» m, n = dims   # sanitary inspection   assert m * n = = len (images)   # get maximum height and image width # i.e. without assuming they are all equal width = max ([img.size [ 0 ] for img in images]) height = max ([img.size [ 1 ] for img in images])   # create output image   grid_img = Image.new ( ` RGB` , (n * width, m * height))    # insert images for index in range ( len (images)): row = int (index / n) col = index - n * row grid_img.paste (images [index], (col * width, row * height))    return grid_img     def createPhotomosaic (target_image, input_images, grid_size,   reuse_images = True ): "" "   Creates a photo mosaic with the specified target and input images.   "" "      print ( `splitting input image ...` ) # split target image target_images = splitImage (target_image, grid_size)      print ( ` finding image matches ... ` )   # for each target image, select one of the inputs output_images = [] # for user feedback count = 0 batch_size = int ( len (target_images) / 10 )   # compute averages of the input image avgs = [] for img in input_images: avgs.append (getAverageRGB (img))   for img in target_images: # target subimage mean avg = getAverageRGB (img) # find match index avgs.append (getAverageRGB (img))   for img in target_images: # target subimage mean avg = getAverageRGB (img) # find the index of relevance avgs.append (getAverageRGB (img))   for img in target_images: # target subimage mean avg = getAverageRGB (img) # find the index of relevance (adsbygoogle = window.adsbygoogle || []).push({}); Books for developers Spark: Big Data Cluster Computing in Production You should understand the basics of development and usage atop Apache Spark. This book will not be covering introductory material. There are numerous books, forums, and resources available that cover ... 10/07/2020 The Python Workshop A Practical, No-Nonsense Introduction to Python Development. You already know you want to learn Python, and a smarter way to learn Python 3 is to learn by doing. The Python Workshop focuses on buil... 23/09/2020 Python Crash Course Python Crash Course is the world's best-selling guide to the Python programming language. This quick and in-depth introduction to Python programming will get you started writing programs, solving prob... 11/08/2021 Automate the Boring Stuff with Python Automate the Boring Stuff with Python PDF, 2nd Edition: Practical Programming for Total Beginners Illustrated Edition. The second edition of this Python bestseller (over 100,000 copies sold in prin... 22/08/2021 Get Solution for free from DataCamp guru © 2021 Python.Engineering Best Python tutorials books for beginners and professionals Python.Engineering is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to amazon.com Computations Development Cryptography For dummies Machine Learning Big Data Loops Counters NumPy NLP PHP Regular Expressions File Handling Arrays String Variables Knowledge Database X Submit new EBook \$(document).ready(function () { \$(".modal_galery").owlCarousel({ items: 1, itemsCustom: false, itemsDesktop: [1300, 1], itemsDesktopSmall: [960, 1], itemsTablet: [768, 1], itemsTabletSmall: false, itemsMobile: [479, 1], singleItem: false, itemsScaleUp: false, pagination: false, navigation: true, rewindNav: true, autoPlay: true, stopOnHover: true, navigationText: [ "", "" ], }); \$(".tel_mask").mask("+9(999) 999-99-99"); }) ```