Source code for gdsfactory.read.from_np

"""Read component from a numpy.ndarray."""

from __future__ import annotations

from typing import Any

import numpy as np
import numpy.typing as npt

import gdsfactory as gf
from gdsfactory.boolean import boolean
from gdsfactory.component import Component
from gdsfactory.typings import PathType


def compute_area_signed(pr: npt.NDArray[np.floating[Any]]) -> float:
    """Return the signed area enclosed by a ring using the linear time.

    algorithm at http://www.cgafaq.info/wiki/Polygon_Area. A value >= 0
    indicates a counter-clockwise oriented ring.

    """
    xs, ys = map(list, zip(*pr))
    xs.append(xs[1])
    ys.append(ys[1])
    return sum(xs[i] * (ys[i + 1] - ys[i - 1]) for i in range(1, len(pr))) / 2.0  # type: ignore[no-any-return]


[docs] def from_np( ndarray: npt.NDArray[np.floating[Any]], nm_per_pixel: int = 20, layer: tuple[int, int] = (1, 0), threshold: float = 0.99, invert: bool = True, ) -> Component: """Returns Component from a np.ndarray. Extracts contours skimage.measure.find_contours using `threshold`. Args: ndarray: 2D ndarray representing the device layout. nm_per_pixel: scale_factor. layer: layer tuple to output gds. threshold: value along which to find contours in the array. invert: invert the mask. """ from skimage import measure c = Component() d = Component() ndarray = np.pad(ndarray, 2) contours = measure.find_contours(ndarray, threshold) # type: ignore[no-untyped-call] assert len(contours) > 0, ( f"no contours found for threshold = {threshold}, maybe you can reduce the" " threshold" ) for contour in contours: area = compute_area_signed(contour) points = contour * 1e-3 * nm_per_pixel if area < 0: c.add_polygon(points, layer=layer) else: d.add_polygon(points, layer=layer) return boolean(c, d, operation="not", layer=layer) if invert else d
@gf.cell def from_image(image_path: PathType, **kwargs: Any) -> Component: """Returns Component from a png image. Args: image_path: png file path. kwargs: for from_np. Keyword Args: nm_per_pixel: scale_factor. layer: layer tuple to output gds. threshold: value along which to find contours in the array. """ import matplotlib.pyplot as plt # Load the image using matplotlib img = plt.imread(image_path) if len(img.shape) == 3: img = 0.2989 * img[:, :, 0] + 0.5870 * img[:, :, 1] + 0.1140 * img[:, :, 2] # Convert image to numpy array (in fact, plt.imread already returns a numpy array) img_array = np.array(img) return from_np(img_array, **kwargs) if __name__ == "__main__": from gdsfactory.config import PATH # import gdsfactory as gf # c1 = gf.components.straight() # c1 = gf.components.bend_circular() # c1 = gf.components.ring_single() # img = c1.to_np() # c2 = from_np(img) # c2.show() c = from_image( PATH.module / "samples" / "images" / "logo.png", nm_per_pixel=500, invert=True ) c.show()