{"id":1568,"date":"2026-10-28T06:58:23","date_gmt":"2026-10-28T06:58:23","guid":{"rendered":"https:\/\/helpwithmygisassignment.com\/blog\/?p=1568"},"modified":"2026-10-28T06:58:23","modified_gmt":"2026-10-28T06:58:23","slug":"fine-tuning-yolov8","status":"publish","type":"post","link":"https:\/\/helpwithmygisassignment.com\/blog\/fine-tuning-yolov8\/","title":{"rendered":"Fine-Tuning YOLOv8 for Automated Object Detection on High-Resolution Satellite Orthophotos"},"content":{"rendered":"<div id=\"model-response-message-contentr_5888ed83c95e1bf3\" class=\"markdown markdown-main-panel md-content enable-luminous-fast-follows enable-updated-hr-color stronger tutor-markdown-rendering\" dir=\"ltr\" aria-busy=\"false\" aria-live=\"polite\">\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_89 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/fine-tuning-yolov8\/#Fine-Tuning_YOLOv8_for_Automated_Object_Detection_on_High-Resolution_Satellite_Orthophotos\" >Fine-Tuning YOLOv8 for Automated Object Detection on High-Resolution Satellite Orthophotos<\/a><ul class='ez-toc-list-level-2' ><li class='ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/fine-tuning-yolov8\/#Introduction\" >Introduction<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/fine-tuning-yolov8\/#Preparing_Training_Data\" >Preparing Training Data<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/fine-tuning-yolov8\/#Tiling_High-Resolution_GeoTIFF_Orthophotos\" >Tiling High-Resolution GeoTIFF Orthophotos<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/fine-tuning-yolov8\/#Annotating_Bounding_Boxes_and_Spatial_Coordinate_Conversions\" >Annotating Bounding Boxes and Spatial Coordinate Conversions<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/fine-tuning-yolov8\/#Step-by-Step_Code_Walkthrough\" >Step-by-Step Code Walkthrough<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/fine-tuning-yolov8\/#1_Setting_up_the_Environment_and_Dataset_Configuration_YAML\" >1. Setting up the Environment and Dataset Configuration YAML<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/fine-tuning-yolov8\/#2_Fine-Tuning_YOLOv8_Training_a_Pre-Trained_Model\" >2. Fine-Tuning YOLOv8: Training a Pre-Trained Model<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/fine-tuning-yolov8\/#3_Running_Batch_Inference_on_Large_Mosaic_Orthophotos\" >3. Running Batch Inference on Large Mosaic Orthophotos<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/fine-tuning-yolov8\/#4_Converting_Pixel-Space_Predictions_to_Geographic_Vector_Coordinates\" >4. Converting Pixel-Space Predictions to Geographic Vector Coordinates<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/fine-tuning-yolov8\/#Conclusion\" >Conclusion<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<h1 class=\"\" data-path-to-node=\"0\"><span class=\"ez-toc-section\" id=\"Fine-Tuning_YOLOv8_for_Automated_Object_Detection_on_High-Resolution_Satellite_Orthophotos\"><\/span>Fine-Tuning YOLOv8 for Automated Object Detection on High-Resolution Satellite Orthophotos<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<h2 data-path-to-node=\"1\"><span class=\"ez-toc-section\" id=\"Introduction\"><\/span>Introduction<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<div>In the fields of Geographic Information Systems (GIS) and remote sensing, extracting features from high-resolution aerial and satellite imagery has traditionally relied on pixel-based classification, spectral indices (such as NDVI or NDBI), and classic morphological image processing. While these methods are computationally lightweight, they frequently struggle with spatial context, scale variations, and complex urban backgrounds.<\/div>\n<div>Modern deep learning-based object detection\u2014specifically Ultralytics YOLOv8\u2014has revolutionized automated feature extraction. By treating geospatial object detection as an end-to-end regression and classification problem, YOLOv8 enables real-time, high-precision identification and counting of infrastructure elements like vehicles, solar panels, buildings, and wind turbines across vast regional orthomosaics.<\/div>\n<h2 data-path-to-node=\"5\"><span class=\"ez-toc-section\" id=\"Preparing_Training_Data\"><\/span>Preparing Training Data<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-1741\" src=\"https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_kjo0trkjo0trkjo0-1024x572.jpg\" alt=\"Fine-Tuning YOLOv8 high-resolution GeoTIFF orthophotos tiling workflow\" width=\"1024\" height=\"572\" srcset=\"https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_kjo0trkjo0trkjo0-1024x572.jpg 1024w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_kjo0trkjo0trkjo0-300x167.jpg 300w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_kjo0trkjo0trkjo0-768x429.jpg 768w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_kjo0trkjo0trkjo0.jpg 1376w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<div><a href=\"https:\/\/helpwithmygisassignment.com\/blog\/cloud-optimized-geotiff-web-map-architecture\/\">High-resolution GeoTIFF orthophotos<\/a> often span gigabytes or terabytes, rendering them too large to pass directly into convolutional neural networks. Preparing training data requires systematic tiling and spatial reference management.<\/div>\n<h3 data-path-to-node=\"7\"><span class=\"ez-toc-section\" id=\"Tiling_High-Resolution_GeoTIFF_Orthophotos\"><\/span>Tiling High-Resolution GeoTIFF Orthophotos<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<div>Deep learning models typically operate on fixed input dimensions, such as <span class=\"math-inline\" data-math=\"640 \\times 640\" data-index-in-node=\"74\">$640 \\times 640$<\/span> pixels. Using Python libraries like <code data-path-to-node=\"8\" data-index-in-node=\"125\">rasterio<\/code> and <code data-path-to-node=\"8\" data-index-in-node=\"138\">gdal<\/code>, large GeoTIFF orthophotos must be systematically sliced into smaller chips. To prevent edge-artifact clipping where objects are cut off mid-feature,<span class=\"\"> it is standard practice to incorporate an overlap buffer (e.<\/span><span class=\"\">g.,<\/span><span class=\"\"> 10% to 15%) between adjacent tiles.<\/span><\/div>\n<div class=\"code-block ng-tns-c977757771-12 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation\" data-hveid=\"0\" data-ved=\"0CAAQhtANahcKEwjPx5yAw9SXAxUAAAAAHQAAAAAQOw\">\n<div class=\"formatted-code-block-internal-container ng-tns-c977757771-12\">\n<div class=\"animated-opacity ng-tns-c977757771-12\">\n<div class=\"code-block-decoration header-formatted gds-emphasized-body-m ng-tns-c977757771-12 ng-star-inserted\">\n<p><span class=\"ng-tns-c977757771-12\">Python<\/span><\/p>\n<div class=\"buttons ng-tns-c977757771-12 ng-star-inserted\"><\/div>\n<\/div>\n<pre class=\"ng-tns-c977757771-12\"><code class=\"code-container formatted ng-tns-c977757771-12\" role=\"text\" data-test-id=\"code-content\"><span class=\"hljs-keyword\">import<\/span> rasterio\r\n<span class=\"hljs-keyword\">from<\/span> rasterio.windows <span class=\"hljs-keyword\">import<\/span> Window\r\n<span class=\"hljs-keyword\">import<\/span> os\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">tile_geotiff<\/span>(<span class=\"hljs-params\">image_path, output_dir, tile_size=<span class=\"hljs-number\">640<\/span>, overlap=<span class=\"hljs-number\">64<\/span><\/span>):<\/span>\r\n    os.makedirs(output_dir, exist_ok=<span class=\"hljs-literal\">True<\/span>)\r\n    <span class=\"hljs-keyword\">with<\/span> rasterio.<span class=\"hljs-built_in\">open<\/span>(image_path) <span class=\"hljs-keyword\">as<\/span> src:\r\n        width = src.width\r\n        height = src.height\r\n        \r\n        stride = tile_size - overlap\r\n        <span class=\"hljs-keyword\">for<\/span> y <span class=\"hljs-keyword\">in<\/span> <span class=\"hljs-built_in\">range<\/span>(<span class=\"hljs-number\">0<\/span>, height, stride):\r\n            <span class=\"hljs-keyword\">for<\/span> x <span class=\"hljs-keyword\">in<\/span> <span class=\"hljs-built_in\">range<\/span>(<span class=\"hljs-number\">0<\/span>, width, stride):\r\n                w = <span class=\"hljs-built_in\">min<\/span>(tile_size, width - x)\r\n                h = <span class=\"hljs-built_in\">min<\/span>(tile_size, height - y)\r\n                \r\n                window = Window(x, y, w, h)\r\n                transform = rasterio.windows.transform(window, src.transform)\r\n                \r\n                kwargs = src.meta.copy()\r\n                kwargs.update({\r\n                    <span class=\"hljs-string\">'height'<\/span>: h,\r\n                    <span class=\"hljs-string\">'width'<\/span>: w,\r\n                    <span class=\"hljs-string\">'transform'<\/span>: transform\r\n                })\r\n                \r\n                out_path = os.path.join(output_dir, <span class=\"hljs-string\">f\"tile_<span class=\"hljs-subst\">{x}<\/span>_<span class=\"hljs-subst\">{y}<\/span>.tif\"<\/span>)\r\n                <span class=\"hljs-keyword\">with<\/span> rasterio.<span class=\"hljs-built_in\">open<\/span>(out_path, <span class=\"hljs-string\">'w'<\/span>, **kwargs) <span class=\"hljs-keyword\">as<\/span> dst:\r\n                    dst.write(src.read(window=window))\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<h3 data-path-to-node=\"10\"><span class=\"ez-toc-section\" id=\"Annotating_Bounding_Boxes_and_Spatial_Coordinate_Conversions\"><\/span>Annotating Bounding Boxes and Spatial Coordinate Conversions<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<div>Annotations for YOLOv8 must be formatted as plain text files (<code data-path-to-node=\"11\" data-index-in-node=\"62\">.txt<\/code>) corresponding to each image tile, where each row represents a bounding box using normalized center coordinates:<\/div>\n<div data-path-to-node=\"12\">\n<div class=\"math-block\" data-math=\"\\text{class\\_id } x_{center} y_{center} width height\">$$\\text{class\\_id } x_{center} y_{center} width height$$<\/div>\n<\/div>\n<div>When vector ground truth data exists as GIS shapefiles or GeoJSON layers in real-world geographic coordinate systems (e.g., EPSG:4326 WGS84 or local UTM zones), you must transform those geometries into pixel space relative to each individual tile&#8217;s affine transformation matrix before writing the YOLO text labels.<\/div>\n<h2 data-path-to-node=\"15\"><span class=\"ez-toc-section\" id=\"Step-by-Step_Code_Walkthrough\"><\/span>Step-by-Step Code Walkthrough<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<div class=\"attachment-container search-images md-has-block-component\"><\/div>\n<h3 data-path-to-node=\"18\"><span class=\"ez-toc-section\" id=\"1_Setting_up_the_Environment_and_Dataset_Configuration_YAML\"><\/span>1. Setting up the Environment and Dataset Configuration YAML<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<div>First, install the Ultralytics package and initialize your dataset configuration file (<code data-path-to-node=\"19\" data-index-in-node=\"87\">dataset.yaml<\/code>), which points to your training and validation image directories and defines your target classes.<\/div>\n<div class=\"code-block ng-tns-c977757771-13 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation\" data-hveid=\"0\" data-ved=\"0CAAQhtANahcKEwjPx5yAw9SXAxUAAAAAHQAAAAAQQA\">\n<div class=\"formatted-code-block-internal-container ng-tns-c977757771-13\">\n<div class=\"animated-opacity ng-tns-c977757771-13\">\n<div class=\"code-block-decoration header-formatted gds-emphasized-body-m ng-tns-c977757771-13 ng-star-inserted\">\n<p><span class=\"ng-tns-c977757771-13\">YAML<\/span><\/p>\n<div class=\"buttons ng-tns-c977757771-13 ng-star-inserted\"><\/div>\n<\/div>\n<pre class=\"ng-tns-c977757771-13\"><code class=\"code-container formatted ng-tns-c977757771-13\" role=\"text\" data-test-id=\"code-content\"><span class=\"hljs-comment\"># dataset.yaml<\/span>\r\n<span class=\"hljs-attr\">path:<\/span> <span class=\"hljs-string\">\/path\/to\/geospatial_dataset<\/span>\r\n<span class=\"hljs-attr\">train:<\/span> <span class=\"hljs-string\">images\/train<\/span>\r\n<span class=\"hljs-attr\">val:<\/span> <span class=\"hljs-string\">images\/val<\/span>\r\n\r\n<span class=\"hljs-attr\">names:<\/span>\r\n  <span class=\"hljs-attr\">0:<\/span> <span class=\"hljs-string\">solar_panel<\/span>\r\n  <span class=\"hljs-attr\">1:<\/span> <span class=\"hljs-string\">vehicle<\/span>\r\n  <span class=\"hljs-attr\">2:<\/span> <span class=\"hljs-string\">building_footprint<\/span>\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<h3 data-path-to-node=\"21\"><span class=\"ez-toc-section\" id=\"2_Fine-Tuning_YOLOv8_Training_a_Pre-Trained_Model\"><\/span>2. Fine-Tuning YOLOv8: Training a Pre-Trained Model<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-1743\" src=\"https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_6cz0ag6cz0ag6cz0-1024x572.jpg\" alt=\"Fine-Tuning YOLOv8 model training and custom object detection output\" width=\"1024\" height=\"572\" srcset=\"https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_6cz0ag6cz0ag6cz0-1024x572.jpg 1024w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_6cz0ag6cz0ag6cz0-300x167.jpg 300w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_6cz0ag6cz0ag6cz0-768x429.jpg 768w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_6cz0ag6cz0ag6cz0.jpg 1376w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<div>Load a pre-trained YOLOv8 weights file (e.g., <code data-path-to-node=\"22\" data-index-in-node=\"46\">yolov8x.pt<\/code>) and fine-tune the model on your custom aerial dataset. Fine-tuning leverages transfer learning, allowing the network to adapt its feature extractors to overhead remote sensing perspectives.<\/div>\n<div class=\"code-block ng-tns-c977757771-14 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation\" data-hveid=\"0\" data-ved=\"0CAAQhtANahcKEwjPx5yAw9SXAxUAAAAAHQAAAAAQQQ\">\n<div class=\"formatted-code-block-internal-container ng-tns-c977757771-14\">\n<div class=\"animated-opacity ng-tns-c977757771-14\">\n<div class=\"code-block-decoration header-formatted gds-emphasized-body-m ng-tns-c977757771-14 ng-star-inserted\">\n<p><span class=\"ng-tns-c977757771-14\">Python<\/span><\/p>\n<div class=\"buttons ng-tns-c977757771-14 ng-star-inserted\"><\/div>\n<\/div>\n<pre class=\"ng-tns-c977757771-14\"><code class=\"code-container formatted ng-tns-c977757771-14\" role=\"text\" data-test-id=\"code-content\"><span class=\"hljs-keyword\">from<\/span> ultralytics <span class=\"hljs-keyword\">import<\/span> YOLO\r\n\r\n<span class=\"hljs-comment\"># Load a pre-trained YOLOv8 model (e.g., Extra Large model for high accuracy)<\/span>\r\nmodel = YOLO(<span class=\"hljs-string\">\"yolov8x.pt\"<\/span>)\r\n\r\n<span class=\"hljs-comment\"># Fine-tune the model on custom geospatial classes<\/span>\r\nresults = model.train(\r\n    data=<span class=\"hljs-string\">\"dataset.yaml\"<\/span>,\r\n    epochs=<span class=\"hljs-number\">50<\/span>,\r\n    imgsz=<span class=\"hljs-number\">640<\/span>,\r\n    batch=<span class=\"hljs-number\">16<\/span>,\r\n    device=<span class=\"hljs-number\">0<\/span>,\r\n    workers=<span class=\"hljs-number\">8<\/span>,\r\n    box=<span class=\"hljs-number\">7.5<\/span>,\r\n    cls=<span class=\"hljs-number\">0.5<\/span>,\r\n    patience=<span class=\"hljs-number\">10<\/span>,\r\n    save=<span class=\"hljs-literal\">True<\/span>,\r\n    project=<span class=\"hljs-string\">\"geospatial_yolo\"<\/span>,\r\n    name=<span class=\"hljs-string\">\"solar_panel_detector\"<\/span>\r\n)\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<h3 data-path-to-node=\"24\"><span class=\"ez-toc-section\" id=\"3_Running_Batch_Inference_on_Large_Mosaic_Orthophotos\"><\/span>3. Running Batch Inference on Large Mosaic Orthophotos<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<div>Once trained, the model can perform batch inference across extensive regional orthomosaics. To learn more about efficient raster processing workflows prior to inference, check out our guide on <a class=\"ng-star-inserted\" href=\"https:\/\/www.google.com\/search?q=https:\/\/example.com\/raster-processing-guide\" target=\"_blank\" rel=\"noopener\" data-hveid=\"0\" data-ved=\"0CAAQ_4QMahcKEwjPx5yAw9SXAxUAAAAAHQAAAAAQQg\">Python raster processing techniques<\/a>.<\/div>\n<div class=\"code-block ng-tns-c977757771-15 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation\" data-hveid=\"0\" data-ved=\"0CAAQhtANahcKEwjPx5yAw9SXAxUAAAAAHQAAAAAQQw\">\n<div class=\"formatted-code-block-internal-container ng-tns-c977757771-15\">\n<div class=\"animated-opacity ng-tns-c977757771-15\">\n<div class=\"code-block-decoration header-formatted gds-emphasized-body-m ng-tns-c977757771-15 ng-star-inserted\">\n<p><span class=\"ng-tns-c977757771-15\">Python<\/span><\/p>\n<div class=\"buttons ng-tns-c977757771-15 ng-star-inserted\"><\/div>\n<\/div>\n<pre class=\"ng-tns-c977757771-15\"><code class=\"code-container formatted ng-tns-c977757771-15\" role=\"text\" data-test-id=\"code-content\"><span class=\"hljs-keyword\">import<\/span> glob\r\n\r\n<span class=\"hljs-comment\"># Load the fine-tuned custom weights<\/span>\r\ntrained_model = YOLO(<span class=\"hljs-string\">\"geospatial_yolo\/solar_panel_detector\/weights\/best.pt\"<\/span>)\r\n\r\n<span class=\"hljs-comment\"># Run batch prediction across all inference tiles<\/span>\r\ninference_results = trained_model.predict(\r\n    source=<span class=\"hljs-string\">\"\/path\/to\/inference_tiles\/*.tif\"<\/span>,\r\n    conf=<span class=\"hljs-number\">0.45<\/span>,\r\n    iou=<span class=\"hljs-number\">0.5<\/span>,\r\n    save_txt=<span class=\"hljs-literal\">True<\/span>,\r\n    save_conf=<span class=\"hljs-literal\">True<\/span>\r\n)\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<h3 data-path-to-node=\"27\"><span class=\"ez-toc-section\" id=\"4_Converting_Pixel-Space_Predictions_to_Geographic_Vector_Coordinates\"><\/span>4. Converting Pixel-Space Predictions to Geographic Vector Coordinates<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-1744\" src=\"https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_qsptfvqsptfvqspt-1-1024x572.jpg\" alt=\"Fine-Tuning YOLOv8 converting pixel predictions to geographic vector coordinates\" width=\"1024\" height=\"572\" srcset=\"https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_qsptfvqsptfvqspt-1-1024x572.jpg 1024w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_qsptfvqsptfvqspt-1-300x167.jpg 300w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_qsptfvqsptfvqspt-1-768x429.jpg 768w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_qsptfvqsptfvqspt-1.jpg 1376w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<div>YOLOv8 outputs predictions in pixel coordinates relative to each image tile. To integrate these detections into GIS software for spatial analysis, you must convert them back into real-world geographic coordinates using <code class=\"\" data-path-to-node=\"28\" data-index-in-node=\"219\">rasterio<\/code><span class=\"\"> and <\/span><code class=\"\" data-path-to-node=\"28\" data-index-in-node=\"232\">geopandas<\/code><span class=\"\">.<\/span><\/div>\n<div class=\"code-block ng-tns-c977757771-16 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation\" data-hveid=\"0\" data-ved=\"0CAAQhtANahcKEwjPx5yAw9SXAxUAAAAAHQAAAAAQRA\">\n<div class=\"formatted-code-block-internal-container ng-tns-c977757771-16\">\n<div class=\"animated-opacity ng-tns-c977757771-16\">\n<div class=\"code-block-decoration header-formatted gds-emphasized-body-m ng-tns-c977757771-16 ng-star-inserted\">\n<p><span class=\"ng-tns-c977757771-16\">Python<\/span><\/p>\n<div class=\"buttons ng-tns-c977757771-16 ng-star-inserted\"><\/div>\n<\/div>\n<pre class=\"ng-tns-c977757771-16\"><code class=\"code-container formatted ng-tns-c977757771-16\" role=\"text\" data-test-id=\"code-content\"><span class=\"hljs-keyword\">import<\/span> geopandas <span class=\"hljs-keyword\">as<\/span> gpd\r\n<span class=\"hljs-keyword\">from<\/span> shapely.geometry <span class=\"hljs-keyword\">import<\/span> box\r\n<span class=\"hljs-keyword\">import<\/span> rasterio\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">pixels_to_gis<\/span>(<span class=\"hljs-params\">tile_tif_path, yolo_txt_path, output_shp_path<\/span>):<\/span>\r\n    <span class=\"hljs-keyword\">with<\/span> rasterio.<span class=\"hljs-built_in\">open<\/span>(tile_tif_path) <span class=\"hljs-keyword\">as<\/span> src:\r\n        transform = src.transform\r\n        crs = src.crs\r\n        \r\n        geometries = []\r\n        confidences = []\r\n        \r\n        <span class=\"hljs-keyword\">with<\/span> <span class=\"hljs-built_in\">open<\/span>(yolo_txt_path, <span class=\"hljs-string\">'r'<\/span>) <span class=\"hljs-keyword\">as<\/span> f:\r\n            <span class=\"hljs-keyword\">for<\/span> line <span class=\"hljs-keyword\">in<\/span> f.readlines():\r\n                parts = line.strip().split()\r\n                cls_id, x_c, y_c, w, h, conf = <span class=\"hljs-built_in\">map<\/span>(<span class=\"hljs-built_in\">float<\/span>, parts)\r\n                \r\n                img_w, img_h = src.width, src.height\r\n                x_min = (x_c - w \/ <span class=\"hljs-number\">2<\/span>) * img_w\r\n                x_max = (x_c + w \/ <span class=\"hljs-number\">2<\/span>) * img_w\r\n                y_min = (y_c - h \/ <span class=\"hljs-number\">2<\/span>) * img_h\r\n                y_max = (y_c + h \/ <span class=\"hljs-number\">2<\/span>) * img_h\r\n                \r\n                <span class=\"hljs-comment\"># Convert pixel coordinates to spatial coordinates using affine transform<\/span>\r\n                ul_x, ul_y = rasterio.transform.xy(transform, y_min, x_min)\r\n                lr_x, lr_y = rasterio.transform.xy(transform, y_max, x_max)\r\n                \r\n                geom = box(ul_x, lr_y, lr_x, ul_y)\r\n                geometries.append(geom)\r\n                confidences.append(conf)\r\n                \r\n        gdf = gpd.GeoDataFrame({<span class=\"hljs-string\">'confidence'<\/span>: confidences, <span class=\"hljs-string\">'geometry'<\/span>: geometries}, crs=crs)\r\n        gdf.to_file(output_shp_path, driver=<span class=\"hljs-string\">'ESRI Shapefile'<\/span>)\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div>For more advanced vector post-processing workflows\u2014such as refining building polygons derived from bounding boxes\u2014refer to our tutorial on <a class=\"ng-star-inserted\" href=\"https:\/\/www.google.com\/search?q=https:\/\/example.com\/sam-qgis-extraction\" target=\"_blank\" rel=\"noopener\" data-hveid=\"0\" data-ved=\"0CAAQ_4QMahcKEwjPx5yAw9SXAxUAAAAAHQAAAAAQTw\">Segment Anything Model (SAM) building extraction in QGIS<\/a>.<\/div>\n<h2 data-path-to-node=\"32\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<div>Fine-tuning Ultralytics YOLOv8 for high-resolution satellite orthophotos bridges the gap between modern computer vision and traditional geospatial analytics. By combining systematic raster tiling, transfer learning, and affine transformation pipelines, developers and geospatial scientists can automate large-scale feature extraction with exceptional speed and accuracy.b<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Fine-Tuning YOLOv8 for Automated Object Detection on High-Resolution Satellite Orthophotos Introduction In the fields of Geographic Information Systems (GIS) and remote sensing, extracting features from high-resolution aerial and satellite imagery has traditionally relied on pixel-based classification, spectral indices (such as NDVI or NDBI), and classic morphological image processing. While these methods are computationally lightweight, they &#8230; <a title=\"Fine-Tuning YOLOv8 for Automated Object Detection on High-Resolution Satellite Orthophotos\" class=\"read-more\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/fine-tuning-yolov8\/\" aria-label=\"Read more about Fine-Tuning YOLOv8 for Automated Object Detection on High-Resolution Satellite Orthophotos\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":1743,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,4],"tags":[],"class_list":["post-1568","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","category-gis-articles"],"_links":{"self":[{"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/posts\/1568","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/comments?post=1568"}],"version-history":[{"count":3,"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/posts\/1568\/revisions"}],"predecessor-version":[{"id":1745,"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/posts\/1568\/revisions\/1745"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/media\/1743"}],"wp:attachment":[{"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/media?parent=1568"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/categories?post=1568"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/tags?post=1568"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}