2

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

3
3
+25

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.