Created
December 22, 2019 05:17
-
-
Save nmz787/c9464d7167ca93e89dabc6b55bfe91d9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- 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