Spaces:
Sleeping
Sleeping
Commit
·
5c2046f
1
Parent(s):
1155ae6
HarmonyView update
Browse files- .idea/workspace.xml +30 -2
- app.py +21 -32
.idea/workspace.xml
CHANGED
|
@@ -6,6 +6,7 @@
|
|
| 6 |
<component name="ChangeListManager">
|
| 7 |
<list default="true" id="a993d736-6297-4164-9c29-6b2ab1055a96" name="변경" comment="HarmonyView update">
|
| 8 |
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
|
|
|
| 9 |
</list>
|
| 10 |
<option name="SHOW_DIALOG" value="false" />
|
| 11 |
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
@@ -32,7 +33,7 @@
|
|
| 32 |
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
| 33 |
"RunOnceActivity.ShowReadmeOnStart": "true",
|
| 34 |
"git-widget-placeholder": "main",
|
| 35 |
-
"last_opened_file_path": "/home/byeongjun/
|
| 36 |
}
|
| 37 |
}]]></component>
|
| 38 |
<component name="RecentsManager">
|
|
@@ -57,6 +58,9 @@
|
|
| 57 |
<updated>1703058146297</updated>
|
| 58 |
<workItem from="1703058147338" duration="769000" />
|
| 59 |
<workItem from="1703224127800" duration="3023000" />
|
|
|
|
|
|
|
|
|
|
| 60 |
</task>
|
| 61 |
<task id="LOCAL-00001" summary="error resolve">
|
| 62 |
<option name="closed" value="true" />
|
|
@@ -138,7 +142,31 @@
|
|
| 138 |
<option name="project" value="LOCAL" />
|
| 139 |
<updated>1703132120481</updated>
|
| 140 |
</task>
|
| 141 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 142 |
<servers />
|
| 143 |
</component>
|
| 144 |
<component name="Vcs.Log.Tabs.Properties">
|
|
|
|
| 6 |
<component name="ChangeListManager">
|
| 7 |
<list default="true" id="a993d736-6297-4164-9c29-6b2ab1055a96" name="변경" comment="HarmonyView update">
|
| 8 |
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
| 9 |
+
<change beforePath="$PROJECT_DIR$/app.py" beforeDir="false" afterPath="$PROJECT_DIR$/app.py" afterDir="false" />
|
| 10 |
</list>
|
| 11 |
<option name="SHOW_DIALOG" value="false" />
|
| 12 |
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
|
|
| 33 |
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
| 34 |
"RunOnceActivity.ShowReadmeOnStart": "true",
|
| 35 |
"git-widget-placeholder": "main",
|
| 36 |
+
"last_opened_file_path": "/home/byeongjun/HarmonyView"
|
| 37 |
}
|
| 38 |
}]]></component>
|
| 39 |
<component name="RecentsManager">
|
|
|
|
| 58 |
<updated>1703058146297</updated>
|
| 59 |
<workItem from="1703058147338" duration="769000" />
|
| 60 |
<workItem from="1703224127800" duration="3023000" />
|
| 61 |
+
<workItem from="1703644898438" duration="448000" />
|
| 62 |
+
<workItem from="1703677779702" duration="730000" />
|
| 63 |
+
<workItem from="1703731914758" duration="8515000" />
|
| 64 |
</task>
|
| 65 |
<task id="LOCAL-00001" summary="error resolve">
|
| 66 |
<option name="closed" value="true" />
|
|
|
|
| 142 |
<option name="project" value="LOCAL" />
|
| 143 |
<updated>1703132120481</updated>
|
| 144 |
</task>
|
| 145 |
+
<task id="LOCAL-00011" summary="HarmonyView update">
|
| 146 |
+
<option name="closed" value="true" />
|
| 147 |
+
<created>1703645193143</created>
|
| 148 |
+
<option name="number" value="00011" />
|
| 149 |
+
<option name="presentableId" value="LOCAL-00011" />
|
| 150 |
+
<option name="project" value="LOCAL" />
|
| 151 |
+
<updated>1703645193143</updated>
|
| 152 |
+
</task>
|
| 153 |
+
<task id="LOCAL-00012" summary="HarmonyView update">
|
| 154 |
+
<option name="closed" value="true" />
|
| 155 |
+
<created>1703645337792</created>
|
| 156 |
+
<option name="number" value="00012" />
|
| 157 |
+
<option name="presentableId" value="LOCAL-00012" />
|
| 158 |
+
<option name="project" value="LOCAL" />
|
| 159 |
+
<updated>1703645337792</updated>
|
| 160 |
+
</task>
|
| 161 |
+
<task id="LOCAL-00013" summary="HarmonyView update">
|
| 162 |
+
<option name="closed" value="true" />
|
| 163 |
+
<created>1703677831151</created>
|
| 164 |
+
<option name="number" value="00013" />
|
| 165 |
+
<option name="presentableId" value="LOCAL-00013" />
|
| 166 |
+
<option name="project" value="LOCAL" />
|
| 167 |
+
<updated>1703677831151</updated>
|
| 168 |
+
</task>
|
| 169 |
+
<option name="localTasksCounter" value="14" />
|
| 170 |
<servers />
|
| 171 |
</component>
|
| 172 |
<component name="Vcs.Log.Tabs.Properties">
|
app.py
CHANGED
|
@@ -24,14 +24,14 @@ Given a single-view image, HarmonyView is able to generate multiview-consistent
|
|
| 24 |
|
| 25 |
Procedure: </br>
|
| 26 |
**Step 1**. Upload an image or select an example. ==> The foreground is masked out by SAM and we crop it as inputs. </br>
|
| 27 |
-
**Step 2**. Select "Elevation angle "and click "Run generation". ==> Generate multiview images. The **Elevation angle** is the elevation of the input image. (This costs about
|
| 28 |
You may adjust the **Crop size** and **Elevation angle** to get a better result! <br>
|
| 29 |
To reconstruct a NeRF or a 3D mesh from the generated images, please refer to our [github repository](https://github.com/byeongjun-park/HarmonyView). <br>
|
| 30 |
We have heavily borrowed codes from [Syncdreamer](https://huggingface.co/spaces/liuyuan-pal/SyncDreamer), which is an our strong baseline.
|
| 31 |
'''
|
| 32 |
_USER_GUIDE0 = "Step1: Please upload an image in the block above (or choose an example shown in the left)."
|
| 33 |
# _USER_GUIDE1 = "Step1: Please select a **Crop size** and click **Crop it**."
|
| 34 |
-
_USER_GUIDE2 = "Step2: Please choose a **Elevation angle** and click **Run Generate**. The **Elevation angle** is the elevation of the input image. This costs about
|
| 35 |
_USER_GUIDE3 = "Generated multiview images are shown below! (You may adjust the **Crop size** and **Elevation angle** to get a better result!)"
|
| 36 |
|
| 37 |
others = '''**Step 1**. Select "Crop size" and click "Crop it". ==> The foreground object is centered and resized. </br>'''
|
|
@@ -65,7 +65,8 @@ class BackgroundRemoval:
|
|
| 65 |
image = self.interface([image])[0]
|
| 66 |
return image
|
| 67 |
|
| 68 |
-
def resize_inputs(
|
|
|
|
| 69 |
if image_input is None: return None
|
| 70 |
alpha_np = np.asarray(image_input)[:, :, 3]
|
| 71 |
coords = np.stack(np.nonzero(alpha_np), 1)[:, (1, 0)]
|
|
@@ -194,8 +195,7 @@ def run_demo():
|
|
| 194 |
with gr.Row():
|
| 195 |
with gr.Column(scale=1):
|
| 196 |
gr.Markdown('# ' + _TITLE)
|
| 197 |
-
|
| 198 |
-
# gr.DuplicateButton(value='Duplicate Space for private use', elem_id='duplicate-button')
|
| 199 |
gr.Markdown(_DESCRIPTION)
|
| 200 |
|
| 201 |
with gr.Row(variant='panel'):
|
|
@@ -211,50 +211,39 @@ def run_demo():
|
|
| 211 |
|
| 212 |
with gr.Column(scale=0.8):
|
| 213 |
image_block.render()
|
| 214 |
-
guide_text = gr.Markdown(_USER_GUIDE0, visible=True)
|
|
|
|
| 215 |
fig0 = gr.Image(value=Image.open('assets/crop_size.jpg'), type='pil', image_mode='RGB', height=256, show_label=False, tool=None, interactive=False)
|
| 216 |
|
| 217 |
|
| 218 |
with gr.Column(scale=0.8):
|
| 219 |
sam_block = gr.Image(type='pil', image_mode='RGBA', label="SAM output", height=256, interactive=False)
|
| 220 |
-
crop_size.render()
|
| 221 |
# crop_btn = gr.Button('Crop it', variant='primary', interactive=True)
|
|
|
|
| 222 |
fig1 = gr.Image(value=Image.open('assets/elevation.jpg'), type='pil', image_mode='RGB', height=256, show_label=False, tool=None, interactive=False)
|
| 223 |
|
| 224 |
with gr.Column(scale=0.8):
|
| 225 |
-
input_block = gr.Image(type='pil', image_mode='RGBA', label="Input to
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
cfg_scale_1 = gr.Slider(1.0, 5.0, 2.0, step=0.1, label='Classifier free guidance 1', interactive=True)
|
| 229 |
-
cfg_scale_2 = gr.Slider(0.5, 1.5, 1.0, step=0.1, label='Classifier free guidance 2', interactive=True)
|
| 230 |
-
sample_num = gr.Slider(1, 2, 1, step=1, label='Sample num', interactive=False, info='How many instance (16 images per instance)')
|
| 231 |
-
sample_steps = gr.Slider(10, 300, 50, step=10, label='Sample steps', interactive=False)
|
| 232 |
-
batch_view_num = gr.Slider(1, 16, 16, step=1, label='Batch num', interactive=True)
|
| 233 |
seed = gr.Number(6033, label='Random seed', interactive=True)
|
| 234 |
run_btn = gr.Button('Run generation', variant='primary', interactive=True)
|
| 235 |
|
|
|
|
| 236 |
|
| 237 |
-
output_block = gr.Image(type='pil', image_mode='RGB', label="Outputs of SyncDreamer", height=256, interactive=False)
|
| 238 |
-
|
| 239 |
-
def update_guide2(text, im):
|
| 240 |
-
if im is None:
|
| 241 |
-
return _USER_GUIDE0
|
| 242 |
-
else:
|
| 243 |
-
return text
|
| 244 |
-
update_guide = lambda GUIDE_TEXT: gr.update(value=GUIDE_TEXT)
|
| 245 |
|
| 246 |
-
image_block.clear(fn=partial(update_guide, _USER_GUIDE0), outputs=[guide_text], queue=False)
|
| 247 |
image_block.change(fn=partial(sam_predict, mask_predictor, removal), inputs=[image_block], outputs=[sam_block], queue=True) \
|
| 248 |
-
.success(fn=resize_inputs, inputs=[sam_block, crop_size], outputs=[input_block], queue=True)
|
| 249 |
-
.success(fn=partial(update_guide2, _USER_GUIDE2), inputs=[image_block], outputs=[guide_text], queue=False)\
|
| 250 |
|
| 251 |
-
|
| 252 |
-
|
| 253 |
-
# crop_btn.click(fn=resize_inputs, inputs=[sam_block, crop_size], outputs=[input_block], queue=False)\
|
| 254 |
-
# .success(fn=partial(update_guide, _USER_GUIDE2), outputs=[guide_text], queue=False)
|
| 255 |
|
| 256 |
-
|
| 257 |
-
|
|
|
|
|
|
|
| 258 |
|
| 259 |
demo.queue().launch(share=False, max_threads=80) # auth=("admin", os.environ['PASSWD'])
|
| 260 |
|
|
|
|
| 24 |
|
| 25 |
Procedure: </br>
|
| 26 |
**Step 1**. Upload an image or select an example. ==> The foreground is masked out by SAM and we crop it as inputs. </br>
|
| 27 |
+
**Step 2**. Select "Elevation angle "and click "Run generation". ==> Generate multiview images. The **Elevation angle** is the elevation of the input image. (This costs about 45s.) </br>
|
| 28 |
You may adjust the **Crop size** and **Elevation angle** to get a better result! <br>
|
| 29 |
To reconstruct a NeRF or a 3D mesh from the generated images, please refer to our [github repository](https://github.com/byeongjun-park/HarmonyView). <br>
|
| 30 |
We have heavily borrowed codes from [Syncdreamer](https://huggingface.co/spaces/liuyuan-pal/SyncDreamer), which is an our strong baseline.
|
| 31 |
'''
|
| 32 |
_USER_GUIDE0 = "Step1: Please upload an image in the block above (or choose an example shown in the left)."
|
| 33 |
# _USER_GUIDE1 = "Step1: Please select a **Crop size** and click **Crop it**."
|
| 34 |
+
_USER_GUIDE2 = "Step2: Please choose a **Elevation angle** and click **Run Generate**. The **Elevation angle** is the elevation of the input image. This costs about 45s."
|
| 35 |
_USER_GUIDE3 = "Generated multiview images are shown below! (You may adjust the **Crop size** and **Elevation angle** to get a better result!)"
|
| 36 |
|
| 37 |
others = '''**Step 1**. Select "Crop size" and click "Crop it". ==> The foreground object is centered and resized. </br>'''
|
|
|
|
| 65 |
image = self.interface([image])[0]
|
| 66 |
return image
|
| 67 |
|
| 68 |
+
def resize_inputs(original_image, sam_image, crop_size, background_removal):
|
| 69 |
+
image_input = original_image if background_removal == "Original Image" else sam_image
|
| 70 |
if image_input is None: return None
|
| 71 |
alpha_np = np.asarray(image_input)[:, :, 3]
|
| 72 |
coords = np.stack(np.nonzero(alpha_np), 1)[:, (1, 0)]
|
|
|
|
| 195 |
with gr.Row():
|
| 196 |
with gr.Column(scale=1):
|
| 197 |
gr.Markdown('# ' + _TITLE)
|
| 198 |
+
|
|
|
|
| 199 |
gr.Markdown(_DESCRIPTION)
|
| 200 |
|
| 201 |
with gr.Row(variant='panel'):
|
|
|
|
| 211 |
|
| 212 |
with gr.Column(scale=0.8):
|
| 213 |
image_block.render()
|
| 214 |
+
# guide_text = gr.Markdown(_USER_GUIDE0, visible=True)
|
| 215 |
+
crop_size.render()
|
| 216 |
fig0 = gr.Image(value=Image.open('assets/crop_size.jpg'), type='pil', image_mode='RGB', height=256, show_label=False, tool=None, interactive=False)
|
| 217 |
|
| 218 |
|
| 219 |
with gr.Column(scale=0.8):
|
| 220 |
sam_block = gr.Image(type='pil', image_mode='RGBA', label="SAM output", height=256, interactive=False)
|
|
|
|
| 221 |
# crop_btn = gr.Button('Crop it', variant='primary', interactive=True)
|
| 222 |
+
elevation.render()
|
| 223 |
fig1 = gr.Image(value=Image.open('assets/elevation.jpg'), type='pil', image_mode='RGB', height=256, show_label=False, tool=None, interactive=False)
|
| 224 |
|
| 225 |
with gr.Column(scale=0.8):
|
| 226 |
+
input_block = gr.Image(type='pil', image_mode='RGBA', label="Input to HarmonyView", height=256, interactive=False)
|
| 227 |
+
with gr.Accordion('Advanced options', open=True):
|
| 228 |
+
background_removal = gr.CheckboxGroup(["Original Image", "SAM Output"], label="Input to HarmonyView", info="Which image do you want for the input?")
|
| 229 |
+
cfg_scale_1 = gr.Slider(1.0, 5.0, 2.0, step=0.1, label='Classifier free guidance 1', info='How consistent to be with the input image', interactive=True)
|
| 230 |
+
cfg_scale_2 = gr.Slider(0.5, 1.5, 1.0, step=0.1, label='Classifier free guidance 2', info='How diverse a novel view to create', interactive=True)
|
|
|
|
|
|
|
|
|
|
| 231 |
seed = gr.Number(6033, label='Random seed', interactive=True)
|
| 232 |
run_btn = gr.Button('Run generation', variant='primary', interactive=True)
|
| 233 |
|
| 234 |
+
output_block = gr.Image(type='pil', image_mode='RGB', label="Outputs of HarmonyView", height=256, interactive=False)
|
| 235 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 236 |
|
|
|
|
| 237 |
image_block.change(fn=partial(sam_predict, mask_predictor, removal), inputs=[image_block], outputs=[sam_block], queue=True) \
|
| 238 |
+
.success(fn=resize_inputs, inputs=[image_block, sam_block, crop_size, background_removal], outputs=[input_block], queue=True)
|
|
|
|
| 239 |
|
| 240 |
+
background_removal.change(fn=resize_inputs, inputs=[image_block, sam_block, crop_size, background_removal], outputs=[input_block], queue=True)
|
| 241 |
+
crop_size.change(fn=resize_inputs, inputs=[image_block, sam_block, crop_size, background_removal], outputs=[input_block], queue=True)
|
|
|
|
|
|
|
| 242 |
|
| 243 |
+
sample_num = 1
|
| 244 |
+
sample_steps = 50
|
| 245 |
+
batch_view_num = 16
|
| 246 |
+
run_btn.click(partial(generate, model), inputs=[sample_steps, batch_view_num, sample_num, cfg_scale_1, cfg_scale_2, seed, input_block, elevation], outputs=[output_block], queue=True)
|
| 247 |
|
| 248 |
demo.queue().launch(share=False, max_threads=80) # auth=("admin", os.environ['PASSWD'])
|
| 249 |
|