{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n# Leaves in natural images\n\nReplication of Wallis and Bex, 2012\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import torch\nimport pandas as pd\nfrom deadleaves import LeafGeometryGenerator, LeafAppearanceSampler, ImageRenderer\nfrom deadleaves.utils import choose_compute_backend\nfrom PIL import Image\nfrom torchvision.transforms.functional import pil_to_tensor\n\ndevice = choose_compute_backend()\nreference_image = Image.open(\"../../examples/images/ulb_5136-2516.jpg\").resize(\n (731, 512), box=(0, 0, 3810, 2667)\n)\nimage_tensor = pil_to_tensor(pic=reference_image).to(device=device) / 255\n\nY, X = torch.meshgrid(\n torch.arange(731),\n torch.arange(512),\n indexing=\"xy\",\n)\n\ncombined_leaf_table = pd.DataFrame()\nfor radius in [50, 120, 200]:\n for angle in [0, 0.5 * torch.pi, torch.pi, 1.5 * torch.pi]:\n x_pos = int(radius * torch.cos(torch.Tensor([angle]))) + 256\n y_pos = int(radius * torch.sin(torch.Tensor([angle]))) + 365.5\n area = torch.Tensor([radius * 10])\n dist_from_center = torch.sqrt((X - x_pos) ** 2 + (Y - y_pos) ** 2)\n mask = (dist_from_center <= torch.sqrt(area / torch.pi)).to(device)\n\n model = LeafGeometryGenerator(\n leaf_shape=\"ellipsoid\",\n shape_param_distributions={\n \"area\": {\"uniform\": {\"low\": 100.0, \"high\": 200.0}},\n \"aspect_ratio\": {\"uniform\": {\"low\": 0.5, \"high\": 2}},\n \"orientation\": {\"uniform\": {\"low\": 0.0, \"high\": 2 * torch.pi}},\n },\n image_shape=(512, 731),\n position_mask=mask,\n )\n leaf_table, segmentation_map = model.generate_segmentation()\n combined_leaf_table = pd.concat(\n [combined_leaf_table, leaf_table], ignore_index=True\n )\n\ncombined_leaf_table.leaf_idx = combined_leaf_table.index + 1\n\ncolor_params = {\n \"R\": {\n \"constant\": {\n \"value\": {\n \"from\": [\"x_pos\", \"y_pos\"],\n \"fn\": lambda x: image_tensor[\n 0, x[\"y_pos\"].astype(int), x[\"x_pos\"].astype(int)\n ],\n }\n }\n },\n \"G\": {\n \"constant\": {\n \"value\": {\n \"from\": [\"x_pos\", \"y_pos\"],\n \"fn\": lambda x: image_tensor[\n 1, x[\"y_pos\"].astype(int), x[\"x_pos\"].astype(int)\n ],\n }\n }\n },\n \"B\": {\n \"constant\": {\n \"value\": {\n \"from\": [\"x_pos\", \"y_pos\"],\n \"fn\": lambda x: image_tensor[\n 2, x[\"y_pos\"].astype(int), x[\"x_pos\"].astype(int)\n ],\n }\n }\n },\n}\n\ncolormodel = LeafAppearanceSampler(leaf_table=combined_leaf_table)\ncolormodel.sample_color(color_param_distributions=color_params)\n\nrenderer = ImageRenderer(leaf_table=colormodel.leaf_table, image_shape=(512, 731))\nimage = renderer.render_image()\nmask = renderer.segmentation_map == 0\nimage[mask] = image_tensor.permute(1, 2, 0)[mask]\nrenderer.show(image)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.3" } }, "nbformat": 4, "nbformat_minor": 0 }