Skip to content

Instantly share code, notes, and snippets.

@nmz787
Created December 22, 2019 05:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nmz787/c9464d7167ca93e89dabc6b55bfe91d9 to your computer and use it in GitHub Desktop.
Save nmz787/c9464d7167ca93e89dabc6b55bfe91d9 to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
"""
Convert a dir of image files to a GDS file, all packed in together
"""
import os
import cv2
import sys
import math
from gdsCAD import *
def convert_image_to_gds(filepath, width, height, startx, starty, grid, unitCell):
binaryImage = cv2.imread(filepath, cv2.IMREAD_UNCHANGED)
for x in range(width):
for y in range(height):
if binaryImage.item(y, x) == 0:
#print("({0}, {1}) is black".format(x, y))
#cell = core.CellReference(unitCell, origin=(x+startx, starty+ height - y - 1))
cell = core.CellReference(unitCell, origin=(x+startx, starty - y))
grid.add(cell)
def pack_images(dirname, sizeOfTheCell):
files = sorted(os.listdir(dirname))
images = []
iamge_names = []
num_pixels = 0
maxx = maxy = 0
for i, file in enumerate(files):
filepath = os.path.join(dirname, file)
print(filepath)
binaryImage = cv2.imread(filepath, cv2.IMREAD_UNCHANGED)
width = binaryImage.shape[1]
height = binaryImage.shape[0]
maxx = max(width, maxx)
maxy = max(width, maxy)
images.append(((height, width), filepath))
del binaryImage
num_pixels += width*height
if not i%1000:
print(i)
image_widths = width
print('number of total pixels: {}'.format(num_pixels))
edge_len = math.ceil(math.sqrt(num_pixels))
print('edge len could be {}'.format(edge_len))
theorhetical_num_images_wide = math.ceil(edge_len/width)
max_pixels_ml150 = (150*1000)/.6 # 150mm and 600nm pixel size
target_width = (theorhetical_num_images_wide+1)*width
target_height = max(target_width, maxx)
print('output height, width: {} {}'.format(target_height, target_width))
packing_info = []
maxx=maxy=0
x=0
y=0
for i, img in enumerate(images):
h, w = img[0]
packing_info.append({'x':x,'y':max_pixels_ml150 - y,'w':w,'h':h,'rid':img})
if y > target_height:
if x > max_pixels_ml150:
print('cannot move over in X anymore. on image {} of {}'.format(i, len(images)))
break
x += image_widths
y=0
else:
y += h
print('finished packing, starting to paste image together')
top = core.Cell("TOP")
grid = core.Cell("GRID")
unitCell = core.Cell("CELL")
square = shapes.Rectangle((0.0, 0.0), (1.0, 1.0), layer=(int)(0))
unitCell.add(square)
with open('image_lookup_table.tsv', 'w') as f:
f.write('X1 X2 Y1 Y2 NAME\n')
for i, rect in enumerate(packing_info):
x = rect['x']
y = rect['y']
w = rect['w']
h = rect['h']
f.write('{}\t{}\t{}\t{}\t{}\n'.format(sizeOfTheCell * x,
sizeOfTheCell * (x+w-1),
sizeOfTheCell * y,
sizeOfTheCell * (y+h-1), rect['rid'][1]))
print('w {} h {} x {} y {} shape {} filename {}'.format(w, h, x, y, rect['rid'][0], rect['rid'][1]))
convert_image_to_gds(rect['rid'][1], w, h, x, y, grid, unitCell)
del rect['rid']
scaledGrid = core.CellReference(
grid, origin=(0, 0), magnification=sizeOfTheCell)
top.add(scaledGrid)
# Add the top-cell to a layout and save
layout = core.Layout("LAYOUT")
layout.add(top)
layout.save("image.gds")
if __name__ == "__main__":
args = sys.argv
if len(args) == 3:
dirName = args[1]
sizeOfTheCell = args[2]
pack_images(dirName, float(sizeOfTheCell))
else:
print(
"usage: python image_gds_packer.py <fileName> <sizeOfTheCell[um]>")
quit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment