We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
`ns-train semantic-nerfw` fails looking for images_4 png instead of jpg
**Describe the bug**
`ns-train semantic-nerfw` fails looking for image png instead of jpg

**To Reproduce**
Steps to reproduce the behavior:
1. Install nerfstudio.  (0.1.10, 0.1.11, latest main)
2. `ns-download-data friends` complains, so you must download from the GDrive link and extract into data/friends manually
3. `ns-train semantic-nerfw`
4. See error about PIL/Image.py -- but notice that it is looking for image png, rather than jpg which is present and specified in cameras.json

**Expected behavior**
Training should not fail.
`ns-train semantic-nerfw` fails looking for images_4 png instead of jpg
**Describe the bug**
`ns-train semantic-nerfw` fails looking for image png instead of jpg

**To Reproduce**
Steps to reproduce the behavior:
1. Install nerfstudio.  (0.1.10, 0.1.11, latest main)
2. `ns-download-data friends` complains, so you must download from the GDrive link and extract into data/friends manually
3. `ns-train semantic-nerfw`
4. See error about PIL/Image.py -- but notice that it is looking for image png, rather than jpg which is present and specified in cameras.json

**Expected behavior**
Training should not fail.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `nerfstudio/data/dataparsers/friends_dataparser.py`
Content:
```
1 # Copyright 2022 The Nerfstudio Team. All rights reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 """Data parser for friends dataset"""
16 from __future__ import annotations
17 
18 from dataclasses import dataclass, field
19 from pathlib import Path
20 from typing import Type
21 
22 import torch
23 from rich.console import Console
24 
25 from nerfstudio.cameras.cameras import Cameras, CameraType
26 from nerfstudio.data.dataparsers.base_dataparser import (
27     DataParser,
28     DataParserConfig,
29     DataparserOutputs,
30     Semantics,
31 )
32 from nerfstudio.data.scene_box import SceneBox
33 from nerfstudio.utils.io import load_from_json
34 
35 CONSOLE = Console()
36 
37 
38 @dataclass
39 class FriendsDataParserConfig(DataParserConfig):
40     """Friends dataset parser config"""
41 
42     _target: Type = field(default_factory=lambda: Friends)
43     """target class to instantiate"""
44     data: Path = Path("data/friends/TBBT-big_living_room")
45     """Directory specifying location of data."""
46     include_semantics: bool = True
47     """whether or not to include loading of semantics data"""
48     downscale_factor: int = 4
49     scene_scale: float = 2.0
50     """
51     Sets the bounding cube to have edge length of this size.
52     The longest dimension of the Friends axis-aligned bbox will be scaled to this value.
53     """
54 
55 
56 @dataclass
57 class Friends(DataParser):
58     """Friends Dataset"""
59 
60     config: FriendsDataParserConfig
61 
62     def _generate_dataparser_outputs(self, split="train"):  # pylint: disable=unused-argument,too-many-statements
63 
64         cameras_json = load_from_json(self.config.data / "cameras.json")
65         frames = cameras_json["frames"]
66         bbox = torch.tensor(cameras_json["bbox"])
67 
68         downscale_suffix = f"_{self.config.downscale_factor}" if self.config.downscale_factor != 1 else ""
69         images_folder = f"images{downscale_suffix}"
70         segmentations_folder = f"segmentations{downscale_suffix}"
71 
72         image_filenames = []
73         fx = []
74         fy = []
75         cx = []
76         cy = []
77         camera_to_worlds = []
78         for frame in frames:
79             # unpack data
80             image_filename = self.config.data / images_folder / frame["image_name"]
81             intrinsics = torch.tensor(frame["intrinsics"])
82             camtoworld = torch.tensor(frame["camtoworld"])[:3]
83             # append data
84             image_filenames.append(image_filename)
85             fx.append(intrinsics[0, 0])
86             fy.append(intrinsics[1, 1])
87             cx.append(intrinsics[0, 2])
88             cy.append(intrinsics[1, 2])
89             camera_to_worlds.append(camtoworld)
90         fx = torch.stack(fx)
91         fy = torch.stack(fy)
92         cx = torch.stack(cx)
93         cy = torch.stack(cy)
94         camera_to_worlds = torch.stack(camera_to_worlds)
95 
96         # rotate the cameras and box 90 degrees about the x axis to put the z axis up
97         rotation = torch.tensor([[1, 0, 0], [0, 0, -1], [0, 1, 0]], dtype=torch.float32)
98         camera_to_worlds[:, :3] = rotation @ camera_to_worlds[:, :3]
99         bbox = (rotation @ bbox.T).T
100 
101         scene_scale = self.config.scene_scale
102 
103         # -- set the scene box ---
104         scene_box = SceneBox(aabb=bbox)
105         # center the box and adjust the cameras too
106         center = scene_box.get_center()
107         scene_box.aabb -= center
108         camera_to_worlds[..., 3] -= center
109         # scale the longest dimension to match the cube size
110         lengths = scene_box.aabb[1] - scene_box.aabb[0]
111         longest_dim = torch.argmax(lengths)
112         longest_length = lengths[longest_dim]
113         scale = scene_scale / longest_length
114         scene_box.aabb = scene_box.aabb * scale  # box
115         camera_to_worlds[..., 3] *= scale  # cameras
116 
117         # --- semantics ---
118         if self.config.include_semantics:
119             filenames = [
120                 Path(
121                     str(image_filename)
122                     .replace(f"/{images_folder}/", f"/{segmentations_folder}/thing/")
123                     .replace(".jpg", ".png")
124                 )
125                 for image_filename in image_filenames
126             ]
127             panoptic_classes = load_from_json(self.config.data / "panoptic_classes.json")
128             classes = panoptic_classes["thing"]
129             colors = torch.tensor(panoptic_classes["thing_colors"], dtype=torch.float32) / 255.0
130             semantics = Semantics(filenames=filenames, classes=classes, colors=colors, mask_classes=["person"])
131 
132         assert torch.all(cx[0] == cx), "Not all cameras have the same cx. Our Cameras class does not support this."
133         assert torch.all(cy[0] == cy), "Not all cameras have the same cy. Our Cameras class does not support this."
134 
135         cameras = Cameras(
136             fx=fx,
137             fy=fy,
138             cx=float(cx[0]),
139             cy=float(cy[0]),
140             camera_to_worlds=camera_to_worlds,
141             camera_type=CameraType.PERSPECTIVE,
142         )
143         cameras.rescale_output_resolution(scaling_factor=1.0 / self.config.downscale_factor)
144 
145         dataparser_outputs = DataparserOutputs(
146             image_filenames=image_filenames,
147             cameras=cameras,
148             scene_box=scene_box,
149             metadata={"semantics": semantics} if self.config.include_semantics else {},
150         )
151         return dataparser_outputs
152
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/nerfstudio/data/dataparsers/friends_dataparser.py b/nerfstudio/data/dataparsers/friends_dataparser.py
--- a/nerfstudio/data/dataparsers/friends_dataparser.py
+++ b/nerfstudio/data/dataparsers/friends_dataparser.py
@@ -116,12 +116,11 @@
 
         # --- semantics ---
         if self.config.include_semantics:
+            empty_path = Path()
+            replace_this_path = str(empty_path / images_folder / empty_path)
+            with_this_path = str(empty_path / segmentations_folder / "thing" / empty_path)
             filenames = [
-                Path(
-                    str(image_filename)
-                    .replace(f"/{images_folder}/", f"/{segmentations_folder}/thing/")
-                    .replace(".jpg", ".png")
-                )
+                Path(str(image_filename).replace(replace_this_path, with_this_path).replace(".jpg", ".png"))
                 for image_filename in image_filenames
             ]
             panoptic_classes = load_from_json(self.config.data / "panoptic_classes.json")

{"golden_diff": "diff --git a/nerfstudio/data/dataparsers/friends_dataparser.py b/nerfstudio/data/dataparsers/friends_dataparser.py\n--- a/nerfstudio/data/dataparsers/friends_dataparser.py\n+++ b/nerfstudio/data/dataparsers/friends_dataparser.py\n@@ -116,12 +116,11 @@\n \n         # --- semantics ---\n         if self.config.include_semantics:\n+            empty_path = Path()\n+            replace_this_path = str(empty_path / images_folder / empty_path)\n+            with_this_path = str(empty_path / segmentations_folder / \"thing\" / empty_path)\n             filenames = [\n-                Path(\n-                    str(image_filename)\n-                    .replace(f\"/{images_folder}/\", f\"/{segmentations_folder}/thing/\")\n-                    .replace(\".jpg\", \".png\")\n-                )\n+                Path(str(image_filename).replace(replace_this_path, with_this_path).replace(\".jpg\", \".png\"))\n                 for image_filename in image_filenames\n             ]\n             panoptic_classes = load_from_json(self.config.data / \"panoptic_classes.json\")\n", "issue": "`ns-train semantic-nerfw` fails looking for images_4 png instead of jpg\n**Describe the bug**\r\n`ns-train semantic-nerfw` fails looking for image png instead of jpg\r\n\r\n**To Reproduce**\r\nSteps to reproduce the behavior:\r\n1. Install nerfstudio.  (0.1.10, 0.1.11, latest main)\r\n2. `ns-download-data friends` complains, so you must download from the GDrive link and extract into data/friends manually\r\n3. `ns-train semantic-nerfw`\r\n4. See error about PIL/Image.py -- but notice that it is looking for image png, rather than jpg which is present and specified in cameras.json\r\n\r\n**Expected behavior**\r\nTraining should not fail.\n`ns-train semantic-nerfw` fails looking for images_4 png instead of jpg\n**Describe the bug**\r\n`ns-train semantic-nerfw` fails looking for image png instead of jpg\r\n\r\n**To Reproduce**\r\nSteps to reproduce the behavior:\r\n1. Install nerfstudio.  (0.1.10, 0.1.11, latest main)\r\n2. `ns-download-data friends` complains, so you must download from the GDrive link and extract into data/friends manually\r\n3. `ns-train semantic-nerfw`\r\n4. See error about PIL/Image.py -- but notice that it is looking for image png, rather than jpg which is present and specified in cameras.json\r\n\r\n**Expected behavior**\r\nTraining should not fail.\n", "before_files": [{"content": "# Copyright 2022 The Nerfstudio Team. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Data parser for friends dataset\"\"\"\nfrom __future__ import annotations\n\nfrom dataclasses import dataclass, field\nfrom pathlib import Path\nfrom typing import Type\n\nimport torch\nfrom rich.console import Console\n\nfrom nerfstudio.cameras.cameras import Cameras, CameraType\nfrom nerfstudio.data.dataparsers.base_dataparser import (\n    DataParser,\n    DataParserConfig,\n    DataparserOutputs,\n    Semantics,\n)\nfrom nerfstudio.data.scene_box import SceneBox\nfrom nerfstudio.utils.io import load_from_json\n\nCONSOLE = Console()\n\n\n@dataclass\nclass FriendsDataParserConfig(DataParserConfig):\n    \"\"\"Friends dataset parser config\"\"\"\n\n    _target: Type = field(default_factory=lambda: Friends)\n    \"\"\"target class to instantiate\"\"\"\n    data: Path = Path(\"data/friends/TBBT-big_living_room\")\n    \"\"\"Directory specifying location of data.\"\"\"\n    include_semantics: bool = True\n    \"\"\"whether or not to include loading of semantics data\"\"\"\n    downscale_factor: int = 4\n    scene_scale: float = 2.0\n    \"\"\"\n    Sets the bounding cube to have edge length of this size.\n    The longest dimension of the Friends axis-aligned bbox will be scaled to this value.\n    \"\"\"\n\n\n@dataclass\nclass Friends(DataParser):\n    \"\"\"Friends Dataset\"\"\"\n\n    config: FriendsDataParserConfig\n\n    def _generate_dataparser_outputs(self, split=\"train\"):  # pylint: disable=unused-argument,too-many-statements\n\n        cameras_json = load_from_json(self.config.data / \"cameras.json\")\n        frames = cameras_json[\"frames\"]\n        bbox = torch.tensor(cameras_json[\"bbox\"])\n\n        downscale_suffix = f\"_{self.config.downscale_factor}\" if self.config.downscale_factor != 1 else \"\"\n        images_folder = f\"images{downscale_suffix}\"\n        segmentations_folder = f\"segmentations{downscale_suffix}\"\n\n        image_filenames = []\n        fx = []\n        fy = []\n        cx = []\n        cy = []\n        camera_to_worlds = []\n        for frame in frames:\n            # unpack data\n            image_filename = self.config.data / images_folder / frame[\"image_name\"]\n            intrinsics = torch.tensor(frame[\"intrinsics\"])\n            camtoworld = torch.tensor(frame[\"camtoworld\"])[:3]\n            # append data\n            image_filenames.append(image_filename)\n            fx.append(intrinsics[0, 0])\n            fy.append(intrinsics[1, 1])\n            cx.append(intrinsics[0, 2])\n            cy.append(intrinsics[1, 2])\n            camera_to_worlds.append(camtoworld)\n        fx = torch.stack(fx)\n        fy = torch.stack(fy)\n        cx = torch.stack(cx)\n        cy = torch.stack(cy)\n        camera_to_worlds = torch.stack(camera_to_worlds)\n\n        # rotate the cameras and box 90 degrees about the x axis to put the z axis up\n        rotation = torch.tensor([[1, 0, 0], [0, 0, -1], [0, 1, 0]], dtype=torch.float32)\n        camera_to_worlds[:, :3] = rotation @ camera_to_worlds[:, :3]\n        bbox = (rotation @ bbox.T).T\n\n        scene_scale = self.config.scene_scale\n\n        # -- set the scene box ---\n        scene_box = SceneBox(aabb=bbox)\n        # center the box and adjust the cameras too\n        center = scene_box.get_center()\n        scene_box.aabb -= center\n        camera_to_worlds[..., 3] -= center\n        # scale the longest dimension to match the cube size\n        lengths = scene_box.aabb[1] - scene_box.aabb[0]\n        longest_dim = torch.argmax(lengths)\n        longest_length = lengths[longest_dim]\n        scale = scene_scale / longest_length\n        scene_box.aabb = scene_box.aabb * scale  # box\n        camera_to_worlds[..., 3] *= scale  # cameras\n\n        # --- semantics ---\n        if self.config.include_semantics:\n            filenames = [\n                Path(\n                    str(image_filename)\n                    .replace(f\"/{images_folder}/\", f\"/{segmentations_folder}/thing/\")\n                    .replace(\".jpg\", \".png\")\n                )\n                for image_filename in image_filenames\n            ]\n            panoptic_classes = load_from_json(self.config.data / \"panoptic_classes.json\")\n            classes = panoptic_classes[\"thing\"]\n            colors = torch.tensor(panoptic_classes[\"thing_colors\"], dtype=torch.float32) / 255.0\n            semantics = Semantics(filenames=filenames, classes=classes, colors=colors, mask_classes=[\"person\"])\n\n        assert torch.all(cx[0] == cx), \"Not all cameras have the same cx. Our Cameras class does not support this.\"\n        assert torch.all(cy[0] == cy), \"Not all cameras have the same cy. Our Cameras class does not support this.\"\n\n        cameras = Cameras(\n            fx=fx,\n            fy=fy,\n            cx=float(cx[0]),\n            cy=float(cy[0]),\n            camera_to_worlds=camera_to_worlds,\n            camera_type=CameraType.PERSPECTIVE,\n        )\n        cameras.rescale_output_resolution(scaling_factor=1.0 / self.config.downscale_factor)\n\n        dataparser_outputs = DataparserOutputs(\n            image_filenames=image_filenames,\n            cameras=cameras,\n            scene_box=scene_box,\n            metadata={\"semantics\": semantics} if self.config.include_semantics else {},\n        )\n        return dataparser_outputs\n", "path": "nerfstudio/data/dataparsers/friends_dataparser.py"}], "after_files": [{"content": "# Copyright 2022 The Nerfstudio Team. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Data parser for friends dataset\"\"\"\nfrom __future__ import annotations\n\nfrom dataclasses import dataclass, field\nfrom pathlib import Path\nfrom typing import Type\n\nimport torch\nfrom rich.console import Console\n\nfrom nerfstudio.cameras.cameras import Cameras, CameraType\nfrom nerfstudio.data.dataparsers.base_dataparser import (\n    DataParser,\n    DataParserConfig,\n    DataparserOutputs,\n    Semantics,\n)\nfrom nerfstudio.data.scene_box import SceneBox\nfrom nerfstudio.utils.io import load_from_json\n\nCONSOLE = Console()\n\n\n@dataclass\nclass FriendsDataParserConfig(DataParserConfig):\n    \"\"\"Friends dataset parser config\"\"\"\n\n    _target: Type = field(default_factory=lambda: Friends)\n    \"\"\"target class to instantiate\"\"\"\n    data: Path = Path(\"data/friends/TBBT-big_living_room\")\n    \"\"\"Directory specifying location of data.\"\"\"\n    include_semantics: bool = True\n    \"\"\"whether or not to include loading of semantics data\"\"\"\n    downscale_factor: int = 4\n    scene_scale: float = 2.0\n    \"\"\"\n    Sets the bounding cube to have edge length of this size.\n    The longest dimension of the Friends axis-aligned bbox will be scaled to this value.\n    \"\"\"\n\n\n@dataclass\nclass Friends(DataParser):\n    \"\"\"Friends Dataset\"\"\"\n\n    config: FriendsDataParserConfig\n\n    def _generate_dataparser_outputs(self, split=\"train\"):  # pylint: disable=unused-argument,too-many-statements\n\n        cameras_json = load_from_json(self.config.data / \"cameras.json\")\n        frames = cameras_json[\"frames\"]\n        bbox = torch.tensor(cameras_json[\"bbox\"])\n\n        downscale_suffix = f\"_{self.config.downscale_factor}\" if self.config.downscale_factor != 1 else \"\"\n        images_folder = f\"images{downscale_suffix}\"\n        segmentations_folder = f\"segmentations{downscale_suffix}\"\n\n        image_filenames = []\n        fx = []\n        fy = []\n        cx = []\n        cy = []\n        camera_to_worlds = []\n        for frame in frames:\n            # unpack data\n            image_filename = self.config.data / images_folder / frame[\"image_name\"]\n            intrinsics = torch.tensor(frame[\"intrinsics\"])\n            camtoworld = torch.tensor(frame[\"camtoworld\"])[:3]\n            # append data\n            image_filenames.append(image_filename)\n            fx.append(intrinsics[0, 0])\n            fy.append(intrinsics[1, 1])\n            cx.append(intrinsics[0, 2])\n            cy.append(intrinsics[1, 2])\n            camera_to_worlds.append(camtoworld)\n        fx = torch.stack(fx)\n        fy = torch.stack(fy)\n        cx = torch.stack(cx)\n        cy = torch.stack(cy)\n        camera_to_worlds = torch.stack(camera_to_worlds)\n\n        # rotate the cameras and box 90 degrees about the x axis to put the z axis up\n        rotation = torch.tensor([[1, 0, 0], [0, 0, -1], [0, 1, 0]], dtype=torch.float32)\n        camera_to_worlds[:, :3] = rotation @ camera_to_worlds[:, :3]\n        bbox = (rotation @ bbox.T).T\n\n        scene_scale = self.config.scene_scale\n\n        # -- set the scene box ---\n        scene_box = SceneBox(aabb=bbox)\n        # center the box and adjust the cameras too\n        center = scene_box.get_center()\n        scene_box.aabb -= center\n        camera_to_worlds[..., 3] -= center\n        # scale the longest dimension to match the cube size\n        lengths = scene_box.aabb[1] - scene_box.aabb[0]\n        longest_dim = torch.argmax(lengths)\n        longest_length = lengths[longest_dim]\n        scale = scene_scale / longest_length\n        scene_box.aabb = scene_box.aabb * scale  # box\n        camera_to_worlds[..., 3] *= scale  # cameras\n\n        # --- semantics ---\n        if self.config.include_semantics:\n            empty_path = Path()\n            replace_this_path = str(empty_path / images_folder / empty_path)\n            with_this_path = str(empty_path / segmentations_folder / \"thing\" / empty_path)\n            filenames = [\n                Path(str(image_filename).replace(replace_this_path, with_this_path).replace(\".jpg\", \".png\"))\n                for image_filename in image_filenames\n            ]\n            panoptic_classes = load_from_json(self.config.data / \"panoptic_classes.json\")\n            classes = panoptic_classes[\"thing\"]\n            colors = torch.tensor(panoptic_classes[\"thing_colors\"], dtype=torch.float32) / 255.0\n            semantics = Semantics(filenames=filenames, classes=classes, colors=colors, mask_classes=[\"person\"])\n\n        assert torch.all(cx[0] == cx), \"Not all cameras have the same cx. Our Cameras class does not support this.\"\n        assert torch.all(cy[0] == cy), \"Not all cameras have the same cy. Our Cameras class does not support this.\"\n\n        cameras = Cameras(\n            fx=fx,\n            fy=fy,\n            cx=float(cx[0]),\n            cy=float(cy[0]),\n            camera_to_worlds=camera_to_worlds,\n            camera_type=CameraType.PERSPECTIVE,\n        )\n        cameras.rescale_output_resolution(scaling_factor=1.0 / self.config.downscale_factor)\n\n        dataparser_outputs = DataparserOutputs(\n            image_filenames=image_filenames,\n            cameras=cameras,\n            scene_box=scene_box,\n            metadata={\"semantics\": semantics} if self.config.include_semantics else {},\n        )\n        return dataparser_outputs\n", "path": "nerfstudio/data/dataparsers/friends_dataparser.py"}]}