mirror of
https://github.com/SikongJueluo/Mini-Nav.git
synced 2026-07-12 20:15:31 +08:00
refactor(verification): extract shared text_labels cell and hash codec
- Move inline _text_labels lists into a shared text_labels cell - Replace inline np.packbits hash encoding with bits_tensor_to_hash_bytes - Add static tests to verify notebook API usage patterns
This commit is contained in:
@@ -39,6 +39,7 @@ def project_imports():
|
|||||||
ObjectNode,
|
ObjectNode,
|
||||||
RoomNode,
|
RoomNode,
|
||||||
SimpleSceneGraph,
|
SimpleSceneGraph,
|
||||||
|
bits_tensor_to_hash_bytes,
|
||||||
query_image_against_scene_graph,
|
query_image_against_scene_graph,
|
||||||
)
|
)
|
||||||
from simulator import (
|
from simulator import (
|
||||||
@@ -59,6 +60,7 @@ def project_imports():
|
|||||||
RoomNode,
|
RoomNode,
|
||||||
SimpleSceneGraph,
|
SimpleSceneGraph,
|
||||||
TopDownSceneElements,
|
TopDownSceneElements,
|
||||||
|
bits_tensor_to_hash_bytes,
|
||||||
cfg_manager,
|
cfg_manager,
|
||||||
collect_room_views_by_room,
|
collect_room_views_by_room,
|
||||||
create_habitat_simulator,
|
create_habitat_simulator,
|
||||||
@@ -70,6 +72,24 @@ def project_imports():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell
|
||||||
|
def text_labels():
|
||||||
|
"""Shared text labels for detection during graph build and query."""
|
||||||
|
text_labels = [
|
||||||
|
"a chair",
|
||||||
|
"a table",
|
||||||
|
"a sofa",
|
||||||
|
"a cabinet",
|
||||||
|
"a shelf",
|
||||||
|
"a lamp",
|
||||||
|
"a picture",
|
||||||
|
"a window",
|
||||||
|
"a door",
|
||||||
|
"a plant",
|
||||||
|
]
|
||||||
|
return (text_labels,)
|
||||||
|
|
||||||
|
|
||||||
@app.cell
|
@app.cell
|
||||||
def habitat_setup(HabitatSimulatorConfig, RoomNode, create_habitat_simulator, np):
|
def habitat_setup(HabitatSimulatorConfig, RoomNode, create_habitat_simulator, np):
|
||||||
"""Initialize Habitat simulator and sample room nodes."""
|
"""Initialize Habitat simulator and sample room nodes."""
|
||||||
@@ -170,6 +190,7 @@ def collect_views(
|
|||||||
def build_scene_graph(
|
def build_scene_graph(
|
||||||
ObjectNode,
|
ObjectNode,
|
||||||
SimpleSceneGraph,
|
SimpleSceneGraph,
|
||||||
|
bits_tensor_to_hash_bytes,
|
||||||
cfg_manager,
|
cfg_manager,
|
||||||
mo,
|
mo,
|
||||||
np,
|
np,
|
||||||
@@ -178,6 +199,7 @@ def build_scene_graph(
|
|||||||
room_view_dataset,
|
room_view_dataset,
|
||||||
save_object_image,
|
save_object_image,
|
||||||
save_room_view,
|
save_room_view,
|
||||||
|
text_labels,
|
||||||
torch,
|
torch,
|
||||||
):
|
):
|
||||||
scene_graph = SimpleSceneGraph(
|
scene_graph = SimpleSceneGraph(
|
||||||
@@ -194,18 +216,6 @@ def build_scene_graph(
|
|||||||
_images = [item[2] for item in room_view_dataset]
|
_images = [item[2] for item in room_view_dataset]
|
||||||
_metadata = [(item[0], item[1]) for item in room_view_dataset]
|
_metadata = [(item[0], item[1]) for item in room_view_dataset]
|
||||||
|
|
||||||
_text_labels = [
|
|
||||||
"a chair",
|
|
||||||
"a table",
|
|
||||||
"a sofa",
|
|
||||||
"a cabinet",
|
|
||||||
"a shelf",
|
|
||||||
"a lamp",
|
|
||||||
"a picture",
|
|
||||||
"a window",
|
|
||||||
"a door",
|
|
||||||
"a plant",
|
|
||||||
]
|
|
||||||
inference_batch_size = 4
|
inference_batch_size = 4
|
||||||
image_batches = [
|
image_batches = [
|
||||||
_images[index : index + inference_batch_size]
|
_images[index : index + inference_batch_size]
|
||||||
@@ -229,7 +239,7 @@ def build_scene_graph(
|
|||||||
):
|
):
|
||||||
_batch_output = pipeline.process_batch(
|
_batch_output = pipeline.process_batch(
|
||||||
_batch_images,
|
_batch_images,
|
||||||
_text_labels,
|
text_labels,
|
||||||
batch_size=inference_batch_size,
|
batch_size=inference_batch_size,
|
||||||
return_debug_details=True,
|
return_debug_details=True,
|
||||||
)
|
)
|
||||||
@@ -296,9 +306,7 @@ def build_scene_graph(
|
|||||||
|
|
||||||
_obj_id = f"{_room_id}_v{_view_idx:03d}_m{_mask_idx:02d}"
|
_obj_id = f"{_room_id}_v{_view_idx:03d}_m{_mask_idx:02d}"
|
||||||
|
|
||||||
_bits_array = _hash_bits.detach().cpu().numpy().reshape(-1)
|
_hash_bytes = bits_tensor_to_hash_bytes(_hash_bits)
|
||||||
_bits_binary = (_bits_array > 0).astype(np.uint8)
|
|
||||||
_hash_bytes = np.packbits(_bits_binary).tobytes()
|
|
||||||
|
|
||||||
object_images[_obj_id] = _cropped
|
object_images[_obj_id] = _cropped
|
||||||
save_object_image(output_dir, _room_id, _obj_id, _view_idx, _mask_idx, _cropped)
|
save_object_image(output_dir, _room_id, _obj_id, _view_idx, _mask_idx, _cropped)
|
||||||
@@ -372,6 +380,7 @@ def query_matching(
|
|||||||
pipeline,
|
pipeline,
|
||||||
query_image_against_scene_graph,
|
query_image_against_scene_graph,
|
||||||
scene_graph,
|
scene_graph,
|
||||||
|
text_labels,
|
||||||
):
|
):
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
@@ -384,23 +393,11 @@ def query_matching(
|
|||||||
|
|
||||||
_query_image = Image.open(BytesIO(_file_contents)).convert("RGB")
|
_query_image = Image.open(BytesIO(_file_contents)).convert("RGB")
|
||||||
|
|
||||||
_text_labels = [
|
|
||||||
"a chair",
|
|
||||||
"a table",
|
|
||||||
"a sofa",
|
|
||||||
"a cabinet",
|
|
||||||
"a shelf",
|
|
||||||
"a lamp",
|
|
||||||
"a picture",
|
|
||||||
"a window",
|
|
||||||
"a door",
|
|
||||||
"a plant",
|
|
||||||
]
|
|
||||||
_query_results = query_image_against_scene_graph(
|
_query_results = query_image_against_scene_graph(
|
||||||
image=_query_image,
|
image=_query_image,
|
||||||
pipeline=pipeline,
|
pipeline=pipeline,
|
||||||
scene_graph=scene_graph,
|
scene_graph=scene_graph,
|
||||||
text_labels=_text_labels,
|
text_labels=text_labels,
|
||||||
top_k=5,
|
top_k=5,
|
||||||
batch_size=1,
|
batch_size=1,
|
||||||
)
|
)
|
||||||
@@ -425,6 +422,7 @@ def query_matching(
|
|||||||
"query_cropped": query_cropped,
|
"query_cropped": query_cropped,
|
||||||
"query_hash_hex": _best_result.query_hash.hex(),
|
"query_hash_hex": _best_result.query_hash.hex(),
|
||||||
"top_matches": top_matches,
|
"top_matches": top_matches,
|
||||||
|
"num_query_results": len(_query_results),
|
||||||
}
|
}
|
||||||
|
|
||||||
return query_cropped, query_result, top_matches
|
return query_cropped, query_result, top_matches
|
||||||
|
|||||||
20
tests/test_notebook_verification_static.py
Normal file
20
tests/test_notebook_verification_static.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
NOTEBOOK = Path(__file__).resolve().parents[1] / "notebooks" / "verification.py"
|
||||||
|
|
||||||
|
|
||||||
|
def test_verification_notebook_uses_scenegraph_query_api():
|
||||||
|
source = NOTEBOOK.read_text()
|
||||||
|
|
||||||
|
assert "query_image_against_scene_graph" in source
|
||||||
|
assert "text_labels=text_labels" in source
|
||||||
|
|
||||||
|
|
||||||
|
def test_verification_notebook_uses_hash_codec_for_object_hashes():
|
||||||
|
source = NOTEBOOK.read_text()
|
||||||
|
|
||||||
|
assert "bits_tensor_to_hash_bytes" in source
|
||||||
|
assert "np.packbits" not in source
|
||||||
Reference in New Issue
Block a user