TransWikia.com

Georeferencing of PNG and Convert to TIFF using Python

Geographic Information Systems Asked on January 12, 2021

I have a PNG image which I am trying to georeference using four corners of coordinate information of the defined input image.

When I am trying to convert PNG to TIFF, I am getting 3 bands (R,G,B) raster. Then I have copied the metadata from the original raster and tried to save it as GeoTIFF along with copied metadata using rasterio library.

In the final output, I am getting only one e band as R band. but I want all the bands in my GeoTIFF output.

Below, I have attached, input PNG and output GeoTIFF images. While converting PNG to GeoTIFF, the blue and black features are missing. only yellow is capturing.

Below is my code,

import rasterio as rio
import numpy as np

#Input png image, to convert as geotiff
img = rio.open('C:/Users/Documents/Study_Area_2.png')
img = img.read([1,2,3])
img = img.astype('uint16')

# Input image for coordinate reference
with rio.open('C:/Users/Study_Area_2_RGB.tif') as src:
    naip_data_ras = src.read()
    naip_meta = src.profile

#output images
with rio.open('C:/Users/Georeferenced.tif', 'w', **naip_meta) as dst:
    dst.write(img,[1,2,3])

Input Png image

enter image description here

Output GeoTIFF

enter image description here

One Answer

edit: even more specific, the problem lies with .astype(uint16). Without this conversion, it loads fine. Also show(limg.read()) also works original: The problem lies with the show(rio.open(georeferenced.tif)). The data is saved properly, and when loaded all operations you would want to perform should work fine. if you're only interested in showing the image, you can show(limg.read([1,2,3])

Further, an (ugly) workaround would be to re-load and save the data. Then you can also resample so your rasters overlap (for calculations). When performed directly on the PNG, this crashed my kernel (sounds like a bug). I also changed the arguments for the rasterio.open('w') to use the shape of your img in stead of the reference image in case they do not exactly match. optionally, you could maybe resample your georeferenced image, so

import rasterio as rio
from rasterio.enums import Resampling
from rasterio.plot import show

#Input png image, to convert as geotiff
img = rio.open('/path/to.png')
img = img.read([1,2,3])
img = img.astype('uint16')
show(img) #shows true color

# Input image for coordinate reference
with rio.open('/path/to/reference.tif') as naip:
    #open georeferenced.tif for writing
    with rio.open(
        'georeferenced.tif',
        'w',
        driver='GTiff',
        count=img.shape[0],
        height=img.shape[1],
        width=img.shape[2],
        dtype=img.dtype,
        crs=naip.crs,
        transform=naip.transform,
        ) as dst:
            dst.write(img)

with rio.open('georeferenced.tif') as limg:
        show(limg) #1 band only shows
        show(limg.read([1,2,3])) #shows true color
        #resample so pixels overlap with reference
        limg = limg.read(out_shape=(3,naip.shape[0],naip.shape[1]),
                         resampling=Resampling.nearest)
        with rio.open('resampled.tif','w', 
                     driver='GTiff',
                     count=limg.shape[0],
                     height=limg.shape[1],
                     width=limg.shape[2],
                     dtype=limg.dtype,
                     crs=naip.crs,
                     transform=naip.transform,
                     ) as dst:
            dst.write(limg)

The writing is a bit verbose, but a passing of **naip.profile does not work, since the count is different, unless your reference layer has the same number of bands. an alternative would be storing naip.profile, and then changing the count manually.

Correct answer by Gevaert Joep on January 12, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP