|
5 | 5 | "colab": {
|
6 | 6 | "provenance": [],
|
7 | 7 | "gpuType": "T4",
|
| 8 | + "authorship_tag": "ABX9TyPD3pXRpOuigYiFeN4QIF32", |
8 | 9 | "include_colab_link": true
|
9 | 10 | },
|
10 | 11 | "kernelspec": {
|
|
27 | 28 | "<a href=\"https://colab.research.google.com/github/compphoto/Intrinsic/blob/main/recoloring.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
28 | 29 | ]
|
29 | 30 | },
|
30 |
| - { |
31 |
| - "cell_type": "markdown", |
32 |
| - "source": [ |
33 |
| - "Make sure to set the runtime to GPU: Runtime -> Change runtime type -> T4 GPU\n", |
34 |
| - "\n", |
35 |
| - "You can upload your own images, then change the relevant code cells to load it and send it through the model." |
36 |
| - ], |
37 |
| - "metadata": { |
38 |
| - "id": "-lKPW1wZEulh" |
39 |
| - } |
40 |
| - }, |
41 | 31 | {
|
42 | 32 | "cell_type": "code",
|
43 | 33 | "execution_count": null,
|
44 | 34 | "metadata": {
|
45 |
| - "id": "_cPkUxN-ikld" |
| 35 | + "id": "nnOA8b8E3Y6U" |
46 | 36 | },
|
47 | 37 | "outputs": [],
|
48 | 38 | "source": [
|
49 |
| - "# install the intrinsic decomposition repo from github\n", |
50 |
| - "!pip install https://github.com/compphoto/Intrinsic/archive/main.zip" |
| 39 | + "!git clone https://github.com/compphoto/Intrinsic\n", |
| 40 | + "!cd Intrinsic/ && pip install ." |
51 | 41 | ]
|
52 | 42 | },
|
53 | 43 | {
|
|
56 | 46 | "import torch\n",
|
57 | 47 | "\n",
|
58 | 48 | "# import some helper functions from chrislib (will be installed by the intrinsic repo)\n",
|
59 |
| - "from chrislib.general import show, view, uninvert\n", |
| 49 | + "from chrislib.general import show, view, uninvert, match_scale\n", |
60 | 50 | "from chrislib.data_util import load_image\n",
|
61 | 51 | "\n",
|
62 | 52 | "# import model loading and running the pipeline\n",
|
63 | 53 | "from intrinsic.pipeline import run_pipeline\n",
|
64 | 54 | "from intrinsic.model_util import load_models"
|
65 | 55 | ],
|
66 | 56 | "metadata": {
|
67 |
| - "id": "J0gn82ZSjomn" |
| 57 | + "id": "mS9AFGEj3jhc" |
68 | 58 | },
|
69 | 59 | "execution_count": null,
|
70 | 60 | "outputs": []
|
71 | 61 | },
|
72 | 62 | {
|
73 | 63 | "cell_type": "code",
|
74 | 64 | "source": [
|
75 |
| - "# download the pretrained weights and return the model (may take a bit to download weights)\n", |
76 | 65 | "intrinsic_model = load_models('paper_weights')"
|
77 | 66 | ],
|
78 | 67 | "metadata": {
|
79 |
| - "id": "Ap3HubpwC_KG" |
| 68 | + "id": "nw0poq363mqy" |
80 | 69 | },
|
81 | 70 | "execution_count": null,
|
82 | 71 | "outputs": []
|
83 | 72 | },
|
84 | 73 | {
|
85 | 74 | "cell_type": "code",
|
86 | 75 | "source": [
|
87 |
| - "# load an example image from the github repo\n", |
88 |
| - "torch.hub.download_url_to_file('https://raw.githubusercontent.com/compphoto/Intrinsic/main/figures/avocado.png', 'avo.png')" |
| 76 | + "# three different example scenes from the paper\n", |
| 77 | + "scene_name = 'yellow_chair'\n", |
| 78 | + "# scene_name = 'brown_chairs'\n", |
| 79 | + "# scene_name = 'spain_museum'" |
89 | 80 | ],
|
90 | 81 | "metadata": {
|
91 |
| - "id": "m_NYfDx0AhTw" |
| 82 | + "id": "l5YBpZ3a5rfS" |
92 | 83 | },
|
93 | 84 | "execution_count": null,
|
94 | 85 | "outputs": []
|
95 | 86 | },
|
96 | 87 | {
|
97 | 88 | "cell_type": "code",
|
98 | 89 | "source": [
|
99 |
| - "# load the image to run through the pipeline\n", |
100 |
| - "img = load_image('/content/avo.png')" |
| 90 | + "inp = load_image(f'Intrinsic/examples/{scene_name}/input.png')[:, :, :3]\n", |
| 91 | + "msk = load_image(f'Intrinsic/examples/{scene_name}/mask.png')[:, :, :3]\n", |
| 92 | + "tex = load_image(f'Intrinsic/examples/{scene_name}/texture.png')[:, :, :3] ** 2.2" |
101 | 93 | ],
|
102 | 94 | "metadata": {
|
103 |
| - "id": "ALb4Pjfvj-MU" |
| 95 | + "id": "zmWeGYSP77W4" |
104 | 96 | },
|
105 | 97 | "execution_count": null,
|
106 | 98 | "outputs": []
|
107 | 99 | },
|
108 | 100 | {
|
109 | 101 | "cell_type": "code",
|
110 | 102 | "source": [
|
111 |
| - "# run the image through the pipeline (use R0 resizing dicussed in the paper)\n", |
112 |
| - "result = run_pipeline(\n", |
| 103 | + "results = run_pipeline(\n", |
113 | 104 | " intrinsic_model,\n",
|
114 |
| - " img,\n", |
115 |
| - " resize_conf=0.0,\n", |
116 |
| - " maintain_size=True,\n", |
117 |
| - " linear=False,\n", |
118 |
| - " device='cuda'\n", |
119 |
| - ")" |
| 105 | + " inp,\n", |
| 106 | + " resize_conf=None,\n", |
| 107 | + " maintain_size=True\n", |
| 108 | + ")\n", |
| 109 | + "\n", |
| 110 | + "alb = results['albedo']\n", |
| 111 | + "image = results['image']\n", |
| 112 | + "inv_shd = results['inv_shading']\n", |
| 113 | + "\n", |
| 114 | + "shd = uninvert(inv_shd)[:, :, None]" |
120 | 115 | ],
|
121 | 116 | "metadata": {
|
122 |
| - "id": "QW0TiFypkOj-" |
| 117 | + "id": "pDr4Wh7M5pIE" |
123 | 118 | },
|
124 | 119 | "execution_count": null,
|
125 | 120 | "outputs": []
|
126 | 121 | },
|
127 | 122 | {
|
128 | 123 | "cell_type": "code",
|
129 | 124 | "source": [
|
130 |
| - "# convert the inverse shading to regular shading for visualization\n", |
131 |
| - "shd = uninvert(result['inv_shading'])\n", |
132 |
| - "alb = result['albedo']" |
| 125 | + "def perform_recolor(msk, alb, shd, shd_power=1.0, recolor=None):\n", |
| 126 | + " # this function will perform the illumination-aware recoloring, or apply a shading curve\n", |
| 127 | + " # msk - numpy array (HxWx1) denoting the region to perform the edit\n", |
| 128 | + " # alb - linear albedo of the image\n", |
| 129 | + " # shd - linear shading of the image\n", |
| 130 | + " # shd_power - exponent to apply to the shading (<1 for more diffuse, >1 for more specular)\n", |
| 131 | + " # recolor - a texture to apply to the edited region, no recoloring is performed if set to None\n", |
| 132 | + "\n", |
| 133 | + " if recolor is None:\n", |
| 134 | + " our_new_alb = alb\n", |
| 135 | + " else:\n", |
| 136 | + " # we match the scale of the texture to the albedo in the edited region to\n", |
| 137 | + " # ensure the appearance of the region is maintained, but this can be altered\n", |
| 138 | + " recolor = match_scale(recolor, alb, msk.astype(bool))\n", |
| 139 | + " our_new_alb = ((1.0 - msk) * alb) + (msk * recolor)\n", |
| 140 | + "\n", |
| 141 | + " # apply exponentiation to the shading of the region and composite\n", |
| 142 | + " masked_shd = msk * (shd ** shd_power)\n", |
| 143 | + " new_shd = ((1.0 - msk) * shd) + masked_shd\n", |
| 144 | + "\n", |
| 145 | + " # combine edited albedo and shading, gamma correct and clip\n", |
| 146 | + " recolored = (our_new_alb * new_shd) ** (1/2.2)\n", |
| 147 | + "\n", |
| 148 | + " return recolored.clip(0, 1)" |
133 | 149 | ],
|
134 | 150 | "metadata": {
|
135 |
| - "id": "XpYY2MNjkp2f" |
| 151 | + "id": "kip8Y1tE83Zi" |
136 | 152 | },
|
137 | 153 | "execution_count": null,
|
138 | 154 | "outputs": []
|
139 | 155 | },
|
140 | 156 | {
|
141 | 157 | "cell_type": "code",
|
142 | 158 | "source": [
|
143 |
| - "# show the result (gamma corrects the linear intrinsic components and scales to [0-1])\n", |
144 |
| - "show([img, view(shd), view(alb)], size=(20, 7))" |
| 159 | + "# NOTE: setting the shading exponent to >1 will make the shading appear more specular,\n", |
| 160 | + "# but small errors in the shading (albedo leakage) will be amplified in some cases\n", |
| 161 | + "show(perform_recolor(msk, alb, shd, 1.0, recolor=tex))" |
145 | 162 | ],
|
146 | 163 | "metadata": {
|
147 |
| - "id": "8KKbyoVLki9s" |
| 164 | + "id": "oF2ljuOv84WA" |
148 | 165 | },
|
149 | 166 | "execution_count": null,
|
150 | 167 | "outputs": []
|
|
0 commit comments