I'm making a QGIS 3 processing algorithm to perform an unsupervised classification with K-Means. When I'm reading the image bands I realized that the following code only works when the image's pixel type is uint8.

(input is a QgsRasterLayer)

    #Getting input attributes
    band_count = input.bandCount()
    rows = input.height()
    cols = input.width()
    pixelType = input.dataProvider().dataType(1)

    #Making a matrix to store multiband data
    img = np.zeros((rows * cols, band_count),

    #Loading the bands into the matrix
    for b in range(band_count):
        img[:,b] = input.dataProvider().block(b+1, input.extent(), cols, rows).data()

When working with a uint16 image, the code returns:

ValueError: could not broadcast input array from shape (2557248) into shape (1278624)

How can I load my band pixels (in any type) into my img array ?

My uint16 image is getting blocks with the double of the size expected.

PS. I can make this work using GDAL, but I only want to use pyqgis.


I've found an answer!

I need to use Numpy frombuffer and gdal_array.GDALTypeCodeToNumericTypeCode to make my for loop look like this:

    #Loading the bands into the matrix
    for b in range(band_count):
        block = input.dataProvider().block(b+1, input.extent(), cols, rows).data()
        data = np.frombuffer(block, dtype=gdal_array.GDALTypeCodeToNumericTypeCode(pixelType))
        img[:,b] = data

PS. In order to use gdal_array I need to import it with:

from osgeo import gdal_array

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.