{"id":1570,"date":"2026-10-28T07:12:10","date_gmt":"2026-10-28T07:12:10","guid":{"rendered":"https:\/\/helpwithmygisassignment.com\/blog\/?p=1570"},"modified":"2026-10-28T07:12:10","modified_gmt":"2026-10-28T07:12:10","slug":"super-resolution-sentinel-2","status":"publish","type":"post","link":"https:\/\/helpwithmygisassignment.com\/blog\/super-resolution-sentinel-2\/","title":{"rendered":"Super-Resolution Mapping: Enhancing Sentinel-2 Imagery Using Deep Learning"},"content":{"rendered":"<div id=\"model-response-message-contentr_6babe25fca782c86\" 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\/super-resolution-sentinel-2\/#Super-Resolution_Mapping_Enhancing_Sentinel-2_Imagery_Using_Deep_Learning\" >Super-Resolution Mapping: Enhancing Sentinel-2 Imagery Using Deep Learning<\/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\/super-resolution-sentinel-2\/#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\/super-resolution-sentinel-2\/#Workflow_Implementation\" >Workflow Implementation<\/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\/super-resolution-sentinel-2\/#1_Downloading_Multispectral_Sentinel-2_Bands_B2_B3_B4_B8\" >1. Downloading Multispectral Sentinel-2 Bands (B2, B3, B4, B8)<\/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\/super-resolution-sentinel-2\/#2_Preparing_Low-Resolution_and_High-Resolution_Patch_Pairs\" >2. Preparing Low-Resolution and High-Resolution Patch Pairs<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/super-resolution-sentinel-2\/#3_Deploying_Deep_Learning_Super-Resolution_Architectures\" >3. Deploying Deep Learning Super-Resolution Architectures<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/super-resolution-sentinel-2\/#4_Validating_Spectral_Fidelity_and_Hallucination_Checks\" >4. Validating Spectral Fidelity and Hallucination Checks<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/super-resolution-sentinel-2\/#Summary\" >Summary<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<h1 class=\"\" data-path-to-node=\"0\"><span class=\"ez-toc-section\" id=\"Super-Resolution_Mapping_Enhancing_Sentinel-2_Imagery_Using_Deep_Learning\"><\/span>Super-Resolution Mapping: Enhancing Sentinel-2 Imagery Using Deep Learning<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><span class=\"\"><b data-path-to-node=\"4,0\" data-index-in-node=\"0\">Super-Resolution Sentinel-2<\/b> workflows rely on advanced deep learning models. By incorporating batch normalization and skip connections, the network maintains stable gradient flow across deep multispectral feature layers without degrading original radiometric values. Open-source satellite constellations like the European Space Agency&#8217;s (ESA) Sentinel-2 mission have transformed Earth observation,<\/span> providing free, high-revisit <a href=\"https:\/\/helpwithmygisassignment.com\/blog\/cloud-optimized-geotiff-web-map-architecture\/\">multispectral imagery<\/a> across thirteen spectral bands. However, remote sensing scientists and GIS developers frequently encounter a persistent spatial resolution bottleneck. While Sentinel-2&#8217;s visible (B4-Red, B3-Green, B2-Blue) and Near-Infrared (B8-NIR) bands are acquired at <span class=\"math-inline\" data-math=\"10\\text{ m}\" data-index-in-node=\"437\">$10\\text{ m}$<\/span> spatial resolution, critical diagnostic bands such as RedEdge (B5, B6, B7), Narrow NIR (B8A), and Short-Wave Infrared (B11, B12) are captured at <span class=\"math-inline\" data-math=\"20\\text{ m}\" data-index-in-node=\"594\">$20\\text{ m}$<\/span>, while atmospheric bands (B1, B9, B10) are sampled at <span class=\"math-inline\" data-math=\"60\\text{ m}\" data-index-in-node=\"660\">$60\\text{ m}$<\/span>.<\/div>\n<div>Traditional resampling techniques\u2014such as nearest-neighbor, bilinear, or bicubic interpolation\u2014merely smooth pixel boundaries. They interpolate pixel values without recovering genuine sub-pixel spatial details, often introducing blurring that obscures fine urban structures, narrow riparian corridors, or fragmented agricultural field boundaries.<\/div>\n<div><b data-path-to-node=\"4\" data-index-in-node=\"0\">Super-Resolution Sentinel-2 Deep Learning Remote Sensing<\/b> bridges this gap by leveraging advanced Single Image Super-Resolution (SISR) neural networks, such as Enhanced Deep Residual Networks (EDSR) and Super-Resolution Generative Adversarial Networks (SRGANs). By learning complex non-linear mappings from low-resolution (LR) inputs to high-resolution (HR) ground-truth counterparts, these models upscale <span class=\"math-inline\" data-math=\"10\\text{ m}\" data-index-in-node=\"405\">$10\\text{ m}$<\/span> bands into finer spatial grids (e.g., <span class=\"math-inline\" data-math=\"2.5\\text{ m}\" data-index-in-node=\"455\">$2.5\\text{ m}$<\/span> or <span class=\"math-inline\" data-math=\"5\\text{ m}\" data-index-in-node=\"471\">$5\\text{ m}$<\/span>) while preserving critical radiometric and spectral integrity.<\/div>\n<h2 data-path-to-node=\"6\"><span class=\"ez-toc-section\" id=\"Workflow_Implementation\"><\/span>Workflow Implementation<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<div>Deploying a deep learning super-resolution pipeline for multispectral satellite imagery requires a disciplined, end-to-end engineering workflow: data acquisition, patch pair preparation, neural network training, and rigorous spectral validation.<\/div>\n<div class=\"attachment-container search-images md-has-block-component\"><\/div>\n<h3 data-path-to-node=\"10\"><span class=\"ez-toc-section\" id=\"1_Downloading_Multispectral_Sentinel-2_Bands_B2_B3_B4_B8\"><\/span>1. Downloading Multispectral Sentinel-2 Bands (B2, B3, B4, B8)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<div>To feed our deep learning pipeline, we must acquire surface reflectance (Level-2A) products. Using the Google Earth Engine (GEE) Python API or direct STAC API downloads, we can extract cloud-masked chips for specific regions of interest.<\/div>\n<div>For broader temporal modeling strategies, you can integrate these extraction routines with our guide on <a class=\"ng-star-inserted\" href=\"https:\/\/www.google.com\/search?q=https:\/\/example.com\/gee-timeseries-analysis\" target=\"_blank\" rel=\"noopener\" data-hveid=\"0\" data-ved=\"0CAAQ_4QMahgKEwjPx5yAw9SXAxUAAAAAHQAAAAAQjQE\">Google Earth Engine time-series analysis workflows<\/a>.<\/div>\n<div class=\"code-block ng-tns-c977757771-20 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation\" data-hveid=\"0\" data-ved=\"0CAAQhtANahgKEwjPx5yAw9SXAxUAAAAAHQAAAAAQjgE\">\n<div class=\"formatted-code-block-internal-container ng-tns-c977757771-20\">\n<div class=\"animated-opacity ng-tns-c977757771-20\">\n<div class=\"code-block-decoration header-formatted gds-emphasized-body-m ng-tns-c977757771-20 ng-star-inserted\">\n<p><span class=\"ng-tns-c977757771-20\">Python<\/span><\/p>\n<div class=\"buttons ng-tns-c977757771-20 ng-star-inserted\"><\/div>\n<\/div>\n<pre class=\"ng-tns-c977757771-20\"><code class=\"code-container formatted ng-tns-c977757771-20\" role=\"text\" data-test-id=\"code-content\"><span class=\"hljs-keyword\">import<\/span> ee\r\n<span class=\"hljs-comment\"># Initialize the Earth Engine API<\/span>\r\nee.Initialize()\r\n\r\n<span class=\"hljs-comment\"># Define Region of Interest (ROI) and date range<\/span>\r\nroi = ee.Geometry.Polygon([[[<span class=\"hljs-number\">36.7<\/span>, -<span class=\"hljs-number\">1.3<\/span>], [<span class=\"hljs-number\">37.1<\/span>, -<span class=\"hljs-number\">1.3<\/span>], [<span class=\"hljs-number\">37.1<\/span>, -<span class=\"hljs-number\">1.7<\/span>], [<span class=\"hljs-number\">36.7<\/span>, -<span class=\"hljs-number\">1.7<\/span>]]])\r\ncollection = (\r\n    ee.ImageCollection(<span class=\"hljs-string\">\"COPERNICUS\/S2_SR_HARMONIZED\"<\/span>)\r\n    .filterBounds(roi)\r\n    .filterDate(<span class=\"hljs-string\">\"2025-01-01\"<\/span>, <span class=\"hljs-string\">\"2025-12-31\"<\/span>)\r\n    .<span class=\"hljs-built_in\">filter<\/span>(ee.Filter.lt(<span class=\"hljs-string\">\"CLOUDY_PIXEL_PERCENTAGE\"<\/span>, <span class=\"hljs-number\">10<\/span>))\r\n)\r\n\r\n<span class=\"hljs-comment\"># Select 10m bands: B2 (Blue), B3 (Green), B4 (Red), B8 (NIR)<\/span>\r\nimage = collection.median().select([<span class=\"hljs-string\">\"B2\"<\/span>, <span class=\"hljs-string\">\"B3\"<\/span>, <span class=\"hljs-string\">\"B4\"<\/span>, <span class=\"hljs-string\">\"B8\"<\/span>]).clip(roi)\r\n\r\n<span class=\"hljs-comment\"># Export or process raster chips locally using geemap or rasterio<\/span>\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<h3 data-path-to-node=\"15\"><span class=\"ez-toc-section\" id=\"2_Preparing_Low-Resolution_and_High-Resolution_Patch_Pairs\"><\/span>2. Preparing Low-Resolution and High-Resolution Patch Pairs<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-1746\" src=\"https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_olm818olm818olm8-1024x572.jpg\" alt=\"Super-Resolution Sentinel-2 side-by-side comparison of bicubic interpolation versus deep learning upscaling\" width=\"1024\" height=\"572\" srcset=\"https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_olm818olm818olm8-1024x572.jpg 1024w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_olm818olm818olm8-300x167.jpg 300w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_olm818olm818olm8-768x429.jpg 768w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_olm818olm818olm8.jpg 1376w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<div>Training a supervised super-resolution network requires paired Low-Resolution (<span class=\"math-inline\" data-math=\"LR\" data-index-in-node=\"79\">$LR$<\/span>) and High-Resolution (<span class=\"math-inline\" data-math=\"HR\" data-index-in-node=\"104\">$HR$<\/span>) image patches. Following standard practice in SISR literature, we use original <span class=\"math-inline\" data-math=\"10\\text{ m}\" data-index-in-node=\"187\">$10\\text{ m}$<\/span> Sentinel-2 bands as our target High-Resolution (<span class=\"math-inline\" data-math=\"HR\" data-index-in-node=\"247\">$HR$<\/span>) images. We then generate corresponding Low-Resolution (<span class=\"math-inline\" data-math=\"LR\" data-index-in-node=\"306\">$LR$<\/span>) inputs by applying a Gaussian blur filter and downsampling the images by a scaling factor (<span class=\"math-inline\" data-math=\"s = 2\" data-index-in-node=\"401\">$s = 2$<\/span> or <span class=\"math-inline\" data-math=\"s = 4\" data-index-in-node=\"410\">$s = 4$<\/span>) via bicubic degradation.<\/div>\n<div class=\"code-block ng-tns-c977757771-21 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation\" data-hveid=\"0\" data-ved=\"0CAAQhtANahgKEwjPx5yAw9SXAxUAAAAAHQAAAAAQjwE\">\n<div class=\"formatted-code-block-internal-container ng-tns-c977757771-21\">\n<div class=\"animated-opacity ng-tns-c977757771-21\">\n<div class=\"code-block-decoration header-formatted gds-emphasized-body-m ng-tns-c977757771-21 ng-star-inserted\">\n<p><span class=\"ng-tns-c977757771-21\">Python<\/span><\/p>\n<div class=\"buttons ng-tns-c977757771-21 ng-star-inserted\"><\/div>\n<\/div>\n<pre class=\"ng-tns-c977757771-21\"><code class=\"code-container formatted ng-tns-c977757771-21\" role=\"text\" data-test-id=\"code-content\"><span class=\"hljs-keyword\">import<\/span> os\r\n<span class=\"hljs-keyword\">import<\/span> numpy <span class=\"hljs-keyword\">as<\/span> np\r\n<span class=\"hljs-keyword\">import<\/span> rasterio\r\n<span class=\"hljs-keyword\">from<\/span> skimage.transform <span class=\"hljs-keyword\">import<\/span> resize\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">create_lr_hr_pairs<\/span>(<span class=\"hljs-params\">input_ortho_path, hr_patch_dir, lr_patch_dir, patch_size=<span class=\"hljs-number\">256<\/span>, scale=<span class=\"hljs-number\">4<\/span><\/span>):<\/span>\r\n    os.makedirs(hr_patch_dir, exist_ok=<span class=\"hljs-literal\">True<\/span>)\r\n    os.makedirs(lr_patch_dir, exist_ok=<span class=\"hljs-literal\">True<\/span>)\r\n    \r\n    <span class=\"hljs-keyword\">with<\/span> rasterio.<span class=\"hljs-built_in\">open<\/span>(input_ortho_path) <span class=\"hljs-keyword\">as<\/span> src:\r\n        meta = src.meta.copy()\r\n        img = src.read() <span class=\"hljs-comment\"># Shape: (C, H, W)<\/span>\r\n        _, height, width = img.shape\r\n        \r\n        patch_id = <span class=\"hljs-number\">0<\/span>\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 - patch_size + <span class=\"hljs-number\">1<\/span>, patch_size):\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 - patch_size + <span class=\"hljs-number\">1<\/span>, patch_size):\r\n                <span class=\"hljs-comment\"># Extract HR patch<\/span>\r\n                hr_patch = img[:, y:y+patch_size, x:x+patch_size]\r\n                \r\n                <span class=\"hljs-comment\"># Skip patches with excessive nodata\/clouds<\/span>\r\n                <span class=\"hljs-keyword\">if<\/span> np.<span class=\"hljs-built_in\">all<\/span>(hr_patch == <span class=\"hljs-number\">0<\/span>):\r\n                    <span class=\"hljs-keyword\">continue<\/span>\r\n                \r\n                <span class=\"hljs-comment\"># Generate LR patch by downscaling<\/span>\r\n                lr_size = patch_size \/\/ scale\r\n                lr_patch = np.zeros((hr_patch.shape[<span class=\"hljs-number\">0<\/span>], lr_size, lr_size), dtype=np.float32)\r\n                <span class=\"hljs-keyword\">for<\/span> c <span class=\"hljs-keyword\">in<\/span> <span class=\"hljs-built_in\">range<\/span>(hr_patch.shape[<span class=\"hljs-number\">0<\/span>]):\r\n                    lr_patch[c] = resize(\r\n                        hr_patch[c], \r\n                        (lr_size, lr_size), \r\n                        order=<span class=\"hljs-number\">3<\/span>, \r\n                        anti_aliasing=<span class=\"hljs-literal\">True<\/span>\r\n                    )\r\n                \r\n                <span class=\"hljs-comment\"># Save patches as numpy arrays or GeoTIFFs<\/span>\r\n                np.save(os.path.join(hr_patch_dir, <span class=\"hljs-string\">f\"hr_<span class=\"hljs-subst\">{patch_id}<\/span>.npy\"<\/span>), hr_patch)\r\n                np.save(os.path.join(lr_patch_dir, <span class=\"hljs-string\">f\"lr_<span class=\"hljs-subst\">{patch_id}<\/span>.npy\"<\/span>), lr_patch)\r\n                patch_id += <span class=\"hljs-number\">1<\/span>\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<h3 data-path-to-node=\"19\"><span class=\"ez-toc-section\" id=\"3_Deploying_Deep_Learning_Super-Resolution_Architectures\"><\/span>3. Deploying Deep Learning Super-Resolution Architectures<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-1747\" src=\"https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_utxuy6utxuy6utxu-1024x572.jpg\" alt=\"Super-Resolution Sentinel-2 PyTorch residual network architecture with PixelShuffle upscaling\" width=\"1024\" height=\"572\" srcset=\"https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_utxuy6utxuy6utxu-1024x572.jpg 1024w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_utxuy6utxuy6utxu-300x167.jpg 300w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_utxuy6utxuy6utxu-768x429.jpg 768w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_utxuy6utxuy6utxu.jpg 1376w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<div>When building a neural network to <b data-path-to-node=\"20\" data-index-in-node=\"34\">upscale Sentinel 2 imagery neural network<\/b> architectures, residual blocks and sub-pixel convolution layers (PixelShuffle) are preferred over traditional transposed convolutions to avoid checkerboard artifacts.<span class=\"\"> Below is a PyTorch implementation of a lightweight Residual Super-Resolution block structure suited for multispectral raster processing (<\/span><code data-path-to-node=\"20\" data-index-in-node=\"380\">Satellite image super resolution Python<\/code>).<\/div>\n<div class=\"code-block ng-tns-c977757771-22 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation\" data-hveid=\"0\" data-ved=\"0CAAQhtANahgKEwjPx5yAw9SXAxUAAAAAHQAAAAAQkAE\">\n<div class=\"formatted-code-block-internal-container ng-tns-c977757771-22\">\n<div class=\"animated-opacity ng-tns-c977757771-22\">\n<div class=\"code-block-decoration header-formatted gds-emphasized-body-m ng-tns-c977757771-22 ng-star-inserted\">\n<p><span class=\"ng-tns-c977757771-22\">Python<\/span><\/p>\n<div class=\"buttons ng-tns-c977757771-22 ng-star-inserted\"><\/div>\n<\/div>\n<pre class=\"ng-tns-c977757771-22\"><code class=\"code-container formatted ng-tns-c977757771-22\" role=\"text\" data-test-id=\"code-content\"><span class=\"hljs-keyword\">import<\/span> torch\r\n<span class=\"hljs-keyword\">import<\/span> torch.nn <span class=\"hljs-keyword\">as<\/span> nn\r\n<span class=\"hljs-keyword\">import<\/span> torch.nn.functional <span class=\"hljs-keyword\">as<\/span> F\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">ResidualBlock<\/span>(<span class=\"hljs-params\">nn.Module<\/span>):<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span>(<span class=\"hljs-params\">self, channels<\/span>):<\/span>\r\n        <span class=\"hljs-built_in\">super<\/span>(ResidualBlock, self).__init__()\r\n        self.conv1 = nn.Conv2d(channels, channels, kernel_size=<span class=\"hljs-number\">3<\/span>, padding=<span class=\"hljs-number\">1<\/span>)\r\n        self.bn1 = nn.BatchNorm2d(channels)\r\n        self.relu = nn.ReLU(inplace=<span class=\"hljs-literal\">True<\/span>)\r\n        self.conv2 = nn.Conv2d(channels, channels, kernel_size=<span class=\"hljs-number\">3<\/span>, padding=<span class=\"hljs-number\">1<\/span>)\r\n        self.bn2 = nn.BatchNorm2d(channels)\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">forward<\/span>(<span class=\"hljs-params\">self, x<\/span>):<\/span>\r\n        residual = x\r\n        out = self.relu(self.bn1(self.conv1(x)))\r\n        out = self.bn2(self.conv2(out))\r\n        out += residual\r\n        <span class=\"hljs-keyword\">return<\/span> out\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">SatelliteSRNet<\/span>(<span class=\"hljs-params\">nn.Module<\/span>):<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span>(<span class=\"hljs-params\">self, in_channels=<span class=\"hljs-number\">4<\/span>, num_features=<span class=\"hljs-number\">64<\/span>, num_blocks=<span class=\"hljs-number\">8<\/span>, scale_factor=<span class=\"hljs-number\">4<\/span><\/span>):<\/span>\r\n        <span class=\"hljs-built_in\">super<\/span>(SatelliteSRNet, self).__init__()\r\n        self.initial_conv = nn.Conv2d(in_channels, num_features, kernel_size=<span class=\"hljs-number\">3<\/span>, padding=<span class=\"hljs-number\">1<\/span>)\r\n        \r\n        <span class=\"hljs-comment\"># Residual blocks backbone<\/span>\r\n        self.res_blocks = nn.Sequential(*[ResidualBlock(num_features) <span class=\"hljs-keyword\">for<\/span> _ <span class=\"hljs-keyword\">in<\/span> <span class=\"hljs-built_in\">range<\/span>(num_blocks)])\r\n        self.mid_conv = nn.Conv2d(num_features, num_features, kernel_size=<span class=\"hljs-number\">3<\/span>, padding=<span class=\"hljs-number\">1<\/span>)\r\n        \r\n        <span class=\"hljs-comment\"># Upsampling via PixelShuffle for 4x scaling<\/span>\r\n        self.upsample = nn.Sequential(\r\n            nn.Conv2d(num_features, num_features * (scale_factor ** <span class=\"hljs-number\">2<\/span>), kernel_size=<span class=\"hljs-number\">3<\/span>, padding=<span class=\"hljs-number\">1<\/span>),\r\n            nn.PixelShuffle(scale_factor),\r\n            nn.ReLU(inplace=<span class=\"hljs-literal\">True<\/span>)\r\n        )\r\n        self.final_conv = nn.Conv2d(num_features, in_channels, kernel_size=<span class=\"hljs-number\">3<\/span>, padding=<span class=\"hljs-number\">1<\/span>)\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">forward<\/span>(<span class=\"hljs-params\">self, x<\/span>):<\/span>\r\n        out1 = self.initial_conv(x)\r\n        out = self.res_blocks(out1)\r\n        out = self.mid_conv(out) + out1\r\n        out = self.upsample(out)\r\n        out = self.final_conv(out)\r\n        <span class=\"hljs-keyword\">return<\/span> out\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<h3 data-path-to-node=\"23\"><span class=\"ez-toc-section\" id=\"4_Validating_Spectral_Fidelity_and_Hallucination_Checks\"><\/span>4. Validating Spectral Fidelity and Hallucination Checks<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-1748\" src=\"https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_92ks3i92ks3i92ks-1024x572.jpg\" alt=\"Super-Resolution Sentinel-2 spectral fidelity validation and Spectral Angle Mapper error analysis map\" width=\"1024\" height=\"572\" srcset=\"https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_92ks3i92ks3i92ks-1024x572.jpg 1024w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_92ks3i92ks3i92ks-300x167.jpg 300w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_92ks3i92ks3i92ks-768x429.jpg 768w, https:\/\/helpwithmygisassignment.com\/blog\/wp-content\/uploads\/2026\/10\/Gemini_Generated_Image_92ks3i92ks3i92ks.jpg 1376w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<div>A central challenge in remote sensing super-resolution is preventing the neural network from &#8220;hallucinating&#8221; false spatial structures (e.g., inventing buildings or roads that do not exist in the physical terrain). Unlike natural RGB photographs where aesthetic sharpness is prioritized, satellite imagery demands strict radiometric and spectral consistency for downstream GIS applications like land-cover classification and change detection.<\/div>\n<div>We evaluate performance using quantitative mathematical metrics:<\/div>\n<ul data-path-to-node=\"26\">\n<li>\n<div><b data-path-to-node=\"26,0,0\" data-index-in-node=\"0\">Peak Signal-to-Noise Ratio (PSNR):<\/b> Measures reconstruction quality of pixel intensities.<\/div>\n<\/li>\n<li>\n<div><b data-path-to-node=\"26,1,0\" data-index-in-node=\"0\">Structural Similarity Index (SSIM):<\/b> Evaluates structural luminance, contrast, and structural preservation.<\/div>\n<\/li>\n<li>\n<div><b data-path-to-node=\"26,2,0\" data-index-in-node=\"0\">Spectral Angle Mapper (SAM):<\/b> Calculates the spectral angle between the spectral vectors of the super-resolved pixel<\/div>\n<div data-path-to-node=\"26,2,1\">\n<div class=\"math-block\" data-math=\"\\hat{x}\">$$\\hat{x}$$<\/div>\n<\/div>\n<div>and the reference pixel<\/div>\n<div data-path-to-node=\"26,2,3\">\n<div class=\"math-block\" data-math=\"x\">$$x$$<\/div>\n<\/div>\n<div>:<\/div>\n<\/li>\n<\/ul>\n<div data-path-to-node=\"27\">\n<div class=\"math-block\" data-math=\"\\text{SAM} = \\arccos \\left( \\frac{\\langle x, \\hat{x} \\rangle}{\\Vert{}x\\Vert{}_2 \\Vert{}\\hat{x}\\Vert{}_2} \\right)\">$$\\text{SAM} = \\arccos \\left( \\frac{\\langle x, \\hat{x} \\rangle}{\\Vert{}x\\Vert{}_2 \\Vert{}\\hat{x}\\Vert{}_2} \\right)$$<\/div>\n<\/div>\n<div>To better understand how multispectral super-resolution compares against high-dimensional analytical frameworks, explore our comparative analysis on <a class=\"ng-star-inserted\" href=\"https:\/\/www.google.com\/search?q=https:\/\/example.com\/hyperspectral-vs-multispectral-guide\" target=\"_blank\" rel=\"noopener\" data-hveid=\"0\" data-ved=\"0CAAQ_4QMahgKEwjPx5yAw9SXAxUAAAAAHQAAAAAQlgE\">hyperspectral vs. multispectral remote sensing data processing<\/a>.<\/div>\n<div class=\"code-block ng-tns-c977757771-23 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation\" data-hveid=\"0\" data-ved=\"0CAAQhtANahgKEwjPx5yAw9SXAxUAAAAAHQAAAAAQlwE\">\n<div class=\"formatted-code-block-internal-container ng-tns-c977757771-23\">\n<div class=\"animated-opacity ng-tns-c977757771-23\">\n<div class=\"code-block-decoration header-formatted gds-emphasized-body-m ng-tns-c977757771-23 ng-star-inserted\">\n<p><span class=\"ng-tns-c977757771-23\">Python<\/span><\/p>\n<div class=\"buttons ng-tns-c977757771-23 ng-star-inserted\"><\/div>\n<\/div>\n<pre class=\"ng-tns-c977757771-23\"><code class=\"code-container formatted ng-tns-c977757771-23\" role=\"text\" data-test-id=\"code-content\"><span class=\"hljs-keyword\">import<\/span> numpy <span class=\"hljs-keyword\">as<\/span> np\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">calculate_metrics<\/span>(<span class=\"hljs-params\">hr_image, sr_image<\/span>):<\/span>\r\n    <span class=\"hljs-comment\"># Mean Squared Error<\/span>\r\n    mse = np.mean((hr_image - sr_image) ** <span class=\"hljs-number\">2<\/span>)\r\n    <span class=\"hljs-keyword\">if<\/span> mse == <span class=\"hljs-number\">0<\/span>:\r\n        psnr = <span class=\"hljs-built_in\">float<\/span>(<span class=\"hljs-string\">'inf'<\/span>)\r\n    <span class=\"hljs-keyword\">else<\/span>:\r\n        max_pixel = <span class=\"hljs-number\">1.0<\/span>\r\n        psnr = <span class=\"hljs-number\">20<\/span> * np.log10(max_pixel \/ np.sqrt(mse))\r\n        \r\n    <span class=\"hljs-comment\"># Spectral Angle Mapper (SAM) calculation across channels<\/span>\r\n    dot_product = np.<span class=\"hljs-built_in\">sum<\/span>(hr_image * sr_image, axis=<span class=\"hljs-number\">0<\/span>)\r\n    norm_hr = np.linalg.norm(hr_image, axis=<span class=\"hljs-number\">0<\/span>)\r\n    norm_sr = np.linalg.norm(sr_image, axis=<span class=\"hljs-number\">0<\/span>)\r\n    \r\n    <span class=\"hljs-comment\"># Avoid division by zero<\/span>\r\n    epsilon = <span class=\"hljs-number\">1e-8<\/span>\r\n    cos_angle = dot_product \/ ((norm_hr * norm_sr) + epsilon)\r\n    cos_angle = np.clip(cos_angle, -<span class=\"hljs-number\">1.0<\/span>, <span class=\"hljs-number\">1.0<\/span>)\r\n    sam_rad = np.arccos(cos_angle)\r\n    mean_sam_deg = np.mean(np.rad2deg(sam_rad))\r\n    \r\n    <span class=\"hljs-keyword\">return<\/span> {<span class=\"hljs-string\">\"PSNR\"<\/span>: psnr, <span class=\"hljs-string\">\"Mean_SAM_Degrees\"<\/span>: mean_sam_deg}\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<h2 data-path-to-node=\"31\"><span class=\"ez-toc-section\" id=\"Summary\"><\/span>Summary<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<div>Enhancing open-source constellations through deep learning unlocks high-definition analytics without incurring the prohibitive costs of commercial very-high-resolution (VHR) tasking. By carefully formulating training data pipelines, building residual convolutional networks with PixelShuffle upscaling, and validating outputs using rigorous metrics like SAM and PSNR, geospatial engineers can reliably upscale <span class=\"math-inline\" data-math=\"10\\text{ m}\" data-index-in-node=\"410\">$10\\text{ m}$<\/span> Sentinel-2 bands into precision mapping grids tailored for modern GIS applications.<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Super-Resolution Mapping: Enhancing Sentinel-2 Imagery Using Deep Learning Introduction Super-Resolution Sentinel-2 workflows rely on advanced deep learning models. By incorporating batch normalization and skip connections, the network maintains stable gradient flow across deep multispectral feature layers without degrading original radiometric values. Open-source satellite constellations like the European Space Agency&#8217;s (ESA) Sentinel-2 mission have transformed Earth &#8230; <a title=\"Super-Resolution Mapping: Enhancing Sentinel-2 Imagery Using Deep Learning\" class=\"read-more\" href=\"https:\/\/helpwithmygisassignment.com\/blog\/super-resolution-sentinel-2\/\" aria-label=\"Read more about Super-Resolution Mapping: Enhancing Sentinel-2 Imagery Using Deep Learning\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":1746,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,4],"tags":[],"class_list":["post-1570","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\/1570","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=1570"}],"version-history":[{"count":2,"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/posts\/1570\/revisions"}],"predecessor-version":[{"id":1749,"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/posts\/1570\/revisions\/1749"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/media\/1746"}],"wp:attachment":[{"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/media?parent=1570"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/categories?post=1570"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/helpwithmygisassignment.com\/blog\/wp-json\/wp\/v2\/tags?post=1570"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}