0

I am working with an NDVI script that I did not write and I am trying to get it to run. The problem it's having is the old Type Error: Can't convert bytes object to str implicitly. I had never seen the struct package until yesterday, and after quite a bit of research I understand the concept generally, but not exactly specifically.

I am dealing with tiff files and trying to create an NDVI image. Here is the code sample. If anyone could help me understand this a bit more and help me solve the problem I would greatly appreciate it!

## The function which loops through the input image and
## calculates the output NDVI value to be outputted.
def calcNDVI(self, filePath, outFilePath):

    # Open the inputted dataset
    dataset = gdal.Open(filePath, gdal.GA_ReadOnly)

    # Check the dataset successfully opened
    if dataset is None:
        print("The dataset could not be opened")
        sys.exit(-1)

    # Create the output dataset
    outDataset = self.createOutputImage(outFilePath, dataset)
    # Check the datasets successfully created
    if outDataset is None:
        print("Could not create output image")
        sys.exit(-1)

    # Get hold of the RED and NIR image bands from the image
    # Note that the image bands are hard coded to handle
    # landsat 8 TIFFs that produce separate images per band
    # which are mosaiced together where 
    # Red = band 1 and NIR = band 2
    red_band = dataset.GetRasterBand(1)
    nir_band = dataset.GetRasterBand(2)

    # Retrieve the number of lines within the image
    numLines = red_band.YSize

    # Loop through each line in turn:
    for line in range(numLines):
        # Define variable for output line
        outputLine = ''

        # Read in data for the current line from the
        # image band representing the red wavelength
        red_scanline = red_band.ReadRaster(0, line, red_band.XSize, 1, \
                red_band.XSize, 1, gdal.GDT_Float32)
        # Unpack the line of data to be read as floating point data
        red_tuple = struct.unpack('f' * red_band.XSize, red_scanline)

        # Read in data for the current line from the
        # image band representing the NIR wavelength
        nir_scanline = nir_band.ReadRaster(0, line, nir_band.XSize, 1, \
                nir_band.XSize, 1, gdal.GDT_Float32)
        # Unpack the line of data to be read as floating point data
        nir_tuple = struct.unpack('f' * nir_band.XSize, nir_scanline)

        # Loop through the columns within the image
        for i in range(len(red_tuple)):
            # Calculate the NDVI for the current pixel
            ndvi_lower = (nir_tuple[i] + red_tuple[i])
            ndvi_upper = (nir_tuple[i] - red_tuple[i])
            ndvi = 0
            # Be careful of zero divide
            if ndvi_lower == 0:
                ndvi = 0
            else:
                ndvi = ndvi_upper/ndvi_lower

            # Add the current pixel to the output line
            outputLine = outputLine + struct.pack('f', ndvi)

            # Write the completed line to the output image
            outDataset.GetRasterBand(1).WriteRaster(0, line, red_band.XSize, 1, \
            outputLine, buf_xsize=red_band.XSize, buf_ysize=1, buf_type = gdal.GDT_Float32)

            # Delete the output line following write
            del outputLine

And the output when ran:

outputLine = outputLine + struct.pack('f', ndvi)

TypeError: Can't convert 'bytes' object to str implicitly

Again, any help is greatly appreciated! Also, there are several questions on this site and elsewhere about this particular struct error, but nothing that deals with images specifically.

Thanks!

Chris
  • 89
  • 1
  • 2
  • 9

1 Answers1

0

Ok I figured out the answer if anyone has a similar question and this stays up! The output line that was causing the error:

outputLine = outputLine + struct.pack('f', ndvi)

Can be fixed with a very simple solution:

outputLine = outputLine + str(struct.pack('f', ndvi))

Python cannot convert bytes object implicitly, but you can do it explicitly.

Chris
  • 89
  • 1
  • 2
  • 9