예제 #1
0
    def read_datum(self, i, j, k, use_memmap=True):
        '''Reads the band `k` value for pixel at row `i` and column `j`.

        Arguments:

            `i`, `j`, `k` (integer):

                Row, column and band index, respectively.

            `use_memmap` (bool, default True):

                Specifies whether the file's memmap interface should be used
                to read the data. Setting this arg to True only has an effect
                if a memmap is being used (i.e., if `img.using_memmap` is True).
                
        Using this function is not an efficient way to iterate over bands or
        pixels. For such cases, use readBands or readPixel instead.
        '''
        import array

        if self._memmap is not None and use_memmap is True:
            datum = self._memmap[i, k, j]
            if self.scale_factor != 1:
                datum /= float(self.scale_factor)
            return datum

        d_col = self.sample_size
        d_band = d_col * self.ncols
        d_row = d_band * self.nbands

        self.fid.seek(self.offset + i * d_row + j * d_col + k * d_band, 0)
        vals = array.array(byte_typecode)
        vals.fromfile(self.fid, self.sample_size)
        arr = np.fromstring(tobytes(vals), dtype=self.dtype)
        return arr.tolist()[0] / float(self.scale_factor)
예제 #2
0
 def _add_signature(self, sampleID, calibrationID, instrument, environment,
                    measurement, xUnit, yUnit, minWavelength, maxWavelength,
                    xData, yData):
     import sqlite3
     import array
     sql = '''INSERT INTO Spectra (SampleID, SensorCalibrationID, Instrument,
              Environment, Measurement, XUnit, YUnit, MinWavelength, MaxWavelength,
              NumValues, XData, YData) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'''
     xBlob = sqlite3.Binary(tobytes(array.array(arraytypecode, xData)))
     yBlob = sqlite3.Binary(tobytes(array.array(arraytypecode, yData)))
     numValues = len(xData)
     self.cursor.execute(sql,
                         (sampleID, calibrationID, instrument, environment,
                          measurement, xUnit, yUnit, minWavelength,
                          maxWavelength, numValues, xBlob, yBlob))
     rowId = self.cursor.lastrowid
     self.db.commit()
     return rowId
예제 #3
0
    def read_bands(self, bands, use_memmap=True):
        '''Reads multiple bands from the image.

        Arguments:

            `bands` (list of ints):

                Indices of bands to read.

            `use_memmap` (bool, default True):

                Specifies whether the file's memmap interface should be used
                to read the data. Setting this arg to True only has an effect
                if a memmap is being used (i.e., if `img.using_memmap` is True).
                
        Returns:

           :class:`numpy.ndarray`

                An `MxNxL` array of values for the specified bands. `M` and `N`
                are the number of rows & columns in the image and `L` equals
                len(`bands`).
        '''
        from array import array

        if self._memmap is not None and use_memmap is True:
            data = np.array(self._memmap[:, :, bands])
            if self.scale_factor != 1:
                data = data / float(self.scale_factor)
            return data

        vals = array(byte_typecode)
        offset = self.offset
        delta = self.sample_size * self.nbands
        nVals = self.nrows * self.ncols
        sample_size = self.sample_size

        # Increments between bands
        delta_b = list(bands[:])
        for i in range(len(delta_b)):
            delta_b[i] *= self.sample_size

        f = self.fid

        # Pixel format is BIP
        for i in range(nVals):
            pixelOffset = offset + i * delta
            for j in range(len(bands)):
                f.seek(pixelOffset + delta_b[j], 0)        # Next band
                vals.fromfile(f, sample_size)
        arr = np.fromstring(tobytes(vals), dtype=self.dtype)
        arr = arr.reshape(self.nrows, self.ncols, len(bands))

        if self.scale_factor != 1:
            return arr / float(self.scale_factor)
        return arr
예제 #4
0
    def read_bands(self, bands, use_memmap=True):
        '''Reads multiple bands from the image.

        Arguments:

            `bands` (list of ints):

                Indices of bands to read.

            `use_memmap` (bool, default True):

                Specifies whether the file's memmap interface should be used
                to read the data. Setting this arg to True only has an effect
                if a memmap is being used (i.e., if `img.using_memmap` is True).
                
        Returns:

           :class:`numpy.ndarray`

                An `MxNxL` array of values for the specified bands. `M` and `N`
                are the number of rows & columns in the image and `L` equals
                len(`bands`).
        '''

        from array import array
        import numpy

        if self._memmap is not None and use_memmap is True:
            data = np.array(self._memmap[:, bands, :]).transpose((0, 2, 1))
            if self.scale_factor != 1:
                data = data / float(self.scale_factor)
            return data

        f = self.fid

        arr = numpy.empty((self.nrows, self.ncols, len(bands)), self.dtype)

        for i in range(self.nrows):
            vals = array(byte_typecode)
            row_offset = self.offset + i * (self.sample_size * self.nbands *
                                            self.ncols)

            # Pixel format is BIL, so read an entire line at a time.
            for j in range(len(bands)):
                f.seek(row_offset + bands[j] * self.sample_size * self.ncols,
                       0)
                vals.fromfile(f, self.ncols * self.sample_size)

            frame = numpy.fromstring(tobytes(vals), dtype=self.dtype)
            arr[i, :, :] = frame.reshape((len(bands), self.ncols)).transpose()

        if self.scale_factor != 1:
            return arr / float(self.scale_factor)

        return arr
예제 #5
0
    def read_pixel(self, row, col, use_memmap=True):
        '''Reads the pixel at position (row,col) from the file.

        Arguments:

            `row`, `col` (int):

                Indices of the row & column for the pixel

            `use_memmap` (bool, default True):

                Specifies whether the file's memmap interface should be used
                to read the data. Setting this arg to True only has an effect
                if a memmap is being used (i.e., if `img.using_memmap` is True).
                
        Returns:

           :class:`numpy.ndarray`

                A length-`B` array, where `B` is the number of image bands.
        '''

        from array import array

        if self._memmap is not None and use_memmap is True:
            data = np.array(self._memmap[:, row, col])
            if self.scale_factor != 1:
                data = data / float(self.scale_factor)
            return data

        vals = array(byte_typecode)
        delta = self.sample_size * (self.nbands - 1)
        offset = self.offset + row * self.nbands * self.ncols \
            * self.sample_size + col * self.sample_size

        f = self.fid
        nPixels = self.nrows * self.ncols

        ncols = self.ncols
        sampleSize = self.sample_size
        bandSize = sampleSize * nPixels
        rowSize = sampleSize * self.ncols

        for i in range(self.nbands):
            f.seek(
                self.offset + i * bandSize + row * rowSize + col * sampleSize,
                0)
            vals.fromfile(f, sampleSize)

        pixel = np.fromstring(tobytes(vals), dtype=self.dtype)

        if self.scale_factor != 1:
            return pixel / float(self.scale_factor)
        return pixel
예제 #6
0
    def read_band(self, band, use_memmap=True):
        '''Reads a single band from the image.

        Arguments:

            `band` (int):

                Index of band to read.

            `use_memmap` (bool, default True):

                Specifies whether the file's memmap interface should be used
                to read the data. Setting this arg to True only has an effect
                if a memmap is being used (i.e., if `img.using_memmap` is True).
                
        Returns:

           :class:`numpy.ndarray`

                An `MxN` array of values for the specified band.
        '''

        from array import array

        if self._memmap is not None and use_memmap is True:
            data = np.array(self._memmap[:, :, band])
            if self.scale_factor != 1:
                data = data / float(self.scale_factor)
            return data

        vals = array(byte_typecode)
        delta = self.sample_size * (self.nbands - 1)
        nVals = self.nrows * self.ncols
        sample_size = self.sample_size

        f = self.fid

        f.seek(self.offset + self.sample_size * band, 0)

        # Pixel format is BIP
        for i in range(nVals - 1):
            vals.fromfile(f, sample_size)
            f.seek(delta, 1)
        vals.fromfile(f, sample_size)

        arr = np.fromstring(tobytes(vals), dtype=self.dtype)
        arr = arr.reshape(self.nrows, self.ncols)

        if self.scale_factor != 1:
            return arr / float(self.scale_factor)
        return arr
예제 #7
0
    def read_pixel(self, row, col, use_memmap=True):
        '''Reads the pixel at position (row,col) from the file.

        Arguments:

            `row`, `col` (int):

                Indices of the row & column for the pixel

            `use_memmap` (bool, default True):

                Specifies whether the file's memmap interface should be used
                to read the data. Setting this arg to True only has an effect
                if a memmap is being used (i.e., if `img.using_memmap` is True).
                
        Returns:

           :class:`numpy.ndarray`

                A length-`B` array, where `B` is the number of image bands.
        '''
        from array import array

        if self._memmap is not None and use_memmap is True:
            data = np.array(self._memmap[row, col, :])
            if self.scale_factor != 1:
                data = data / float(self.scale_factor)
            return data

        vals = array(byte_typecode)

        f = self.fid
        f.seek(
            self.offset + self.sample_size * self.nbands *
            (row * self.ncols + col), 0)
        # Pixel format is BIP so read entire pixel.
        vals.fromfile(f, self.nbands * self.sample_size)

        pixel = np.fromstring(tobytes(vals), dtype=self.dtype)

        if self.scale_factor != 1:
            return pixel / float(self.scale_factor)
        return pixel
예제 #8
0
    def read_subimage(self, rows, cols, bands=None, use_memmap=False):
        '''
        Reads arbitrary rows, columns, and bands from the image.

        Arguments:

            `rows` (list of ints):

                Indices of rows to read.

            `cols` (list of ints):

                Indices of columns to read.

            `bands` (list of ints):

                Optional list of bands to read.  If not specified, all bands
                are read.

            `use_memmap` (bool, default False):

                Specifies whether the file's memmap interface should be used
                to read the data. Setting this arg to True only has an effect
                if a memmap is being used (i.e., if `img.using_memmap` is True).
                
        Returns:

           :class:`numpy.ndarray`

                An `MxNxL` array, where `M` = len(`rows`), `N` = len(`cols`),
                and `L` = len(bands) (or # of image bands if `bands` == None).
        '''

        from array import array
        import numpy

        if self._memmap is not None and use_memmap is True:
            if bands is None:
                data = np.array(self._memmap.take(rows, 0).take(cols, 2))
            else:
                data = np.array(
                    self._memmap.take(rows, 0).take(bands, 1).take(cols, 2))
            data = data.transpose((0, 2, 1))
            if self.scale_factor != 1:
                data = data / float(self.scale_factor)
            return data

        nSubRows = len(rows)  # Rows in sub-image
        nSubCols = len(cols)  # Cols in sub-image
        d_col = self.sample_size
        d_band = d_col * self.ncols
        d_row = d_band * self.nbands

        f = self.fid
        f.seek(self.offset, 0)

        # Increments between bands
        if bands is None:
            # Read all bands.
            bands = list(range(self.nbands))
        nSubBands = len(bands)

        arr = numpy.empty((nSubRows, nSubCols, nSubBands), self.dtype)

        offset = self.offset
        vals = array(byte_typecode)
        sample_size = self.sample_size

        # Pixel format is BIL
        for i in rows:
            for j in cols:
                for k in bands:
                    f.seek(offset + i * d_row + j * d_col + k * d_band, 0)
                    vals.fromfile(f, sample_size)
        subArray = numpy.fromstring(tobytes(vals), dtype=self.dtype)
        subArray = subArray.reshape((nSubRows, nSubCols, nSubBands))

        if self.scale_factor != 1:
            return subArray / float(self.scale_factor)
        return subArray
예제 #9
0
    def read_subregion(self,
                       row_bounds,
                       col_bounds,
                       bands=None,
                       use_memmap=True):
        '''
        Reads a contiguous rectangular sub-region from the image.

        Arguments:

            `row_bounds` (2-tuple of ints):

                (a, b) -> Rows a through b-1 will be read.

            `col_bounds` (2-tuple of ints):

                (a, b) -> Columnss a through b-1 will be read.

            `bands` (list of ints):

                Optional list of bands to read.  If not specified, all bands
                are read.

            `use_memmap` (bool, default True):

                Specifies whether the file's memmap interface should be used
                to read the data. Setting this arg to True only has an effect
                if a memmap is being used (i.e., if `img.using_memmap` is True).
                
        Returns:

           :class:`numpy.ndarray`

                An `MxNxL` array.
        '''

        from array import array
        import numpy

        if self._memmap is not None and use_memmap is True:
            if bands is None:
                data = np.array(self._memmap[row_bounds[0]:row_bounds[1], :,
                                             col_bounds[0]:col_bounds[1]])
            else:
                data = np.array(self._memmap[row_bounds[0]:row_bounds[1],
                                             bands,
                                             col_bounds[0]:col_bounds[1]])
            data = data.transpose((0, 2, 1))
            if self.scale_factor != 1:
                data = data / float(self.scale_factor)
            return data

        nSubRows = row_bounds[1] - row_bounds[0]  # Rows in sub-image
        nSubCols = col_bounds[1] - col_bounds[0]  # Cols in sub-image
        d_row = self.sample_size * self.ncols * self.nbands
        colStartPos = col_bounds[0] * self.sample_size

        f = self.fid
        f.seek(self.offset, 0)

        # Increments between bands
        if bands is None:
            # Read all bands.
            bands = list(range(self.nbands))

        arr = numpy.empty((nSubRows, nSubCols, len(bands)), self.dtype)

        offset = self.offset
        ncols = self.ncols
        sampleSize = self.sample_size
        nSubBands = len(bands)

        # Pixel format is BIL
        for i in range(row_bounds[0], row_bounds[1]):
            f.seek(offset + i * d_row + colStartPos, 0)
            rowPos = f.tell()
            vals = array(byte_typecode)
            for j in bands:
                f.seek(rowPos + j * ncols * sampleSize, 0)
                vals.fromfile(f, nSubCols * sampleSize)
            subArray = numpy.fromstring(tobytes(vals), dtype=self.dtype)
            subArray = subArray.reshape((nSubBands, nSubCols))
            arr[i - row_bounds[0], :, :] = numpy.transpose(subArray)

        if self.scale_factor != 1:
            return arr / float(self.scale_factor)
        return arr
예제 #10
0
    def read_subregion(self, row_bounds, col_bounds, bands=None,
                       use_memmap=True):
        '''
        Reads a contiguous rectangular sub-region from the image.

        Arguments:

            `row_bounds` (2-tuple of ints):

                (a, b) -> Rows a through b-1 will be read.

            `col_bounds` (2-tuple of ints):

                (a, b) -> Columnss a through b-1 will be read.

            `bands` (list of ints):

                Optional list of bands to read.  If not specified, all bands
                are read.

            `use_memmap` (bool, default True):

                Specifies whether the file's memmap interface should be used
                to read the data. Setting this arg to True only has an effect
                if a memmap is being used (i.e., if `img.using_memmap` is True).
                
        Returns:

           :class:`numpy.ndarray`

                An `MxNxL` array.
        '''
        import array

        if self._memmap is not None and use_memmap is True:
            if bands is None:
                data = np.array(self._memmap[row_bounds[0]: row_bounds[1],
                                             col_bounds[0]: col_bounds[1], :])
            else:
                data = np.array(self._memmap[row_bounds[0]: row_bounds[1],
                                             col_bounds[0]: col_bounds[1],
                                             bands])
            if self.scale_factor != 1:
                data = data / float(self.scale_factor)
            return data

        offset = self.offset
        nbands = self.nbands
        nSubRows = row_bounds[1] - row_bounds[0]  # Rows in sub-image
        nSubCols = col_bounds[1] - col_bounds[0]  # Cols in sub-image
        d_row = self.sample_size * self.ncols * self.nbands
        colStartPos = col_bounds[0] * self.sample_size * self.nbands
        vals = array.array(byte_typecode)
        nVals = self.nrows * self.ncols
        sample_size = self.sample_size

        # Increments between bands
        if bands is not None:
            allBands = 0
            nSubBands = len(bands)
            delta_b = bands[:]
            for i in range(len(delta_b)):
                delta_b[i] *= self.sample_size
        else:
            allBands = 1
            nSubBands = self.nbands

        f = self.fid

        # Pixel format is BIP
        for i in range(row_bounds[0], row_bounds[1]):
            f.seek(offset + i * d_row + colStartPos, 0)
            rowPos = f.tell()

            if allBands:
                # This is the simple one
                vals.fromfile(f, nSubCols * nbands * sample_size)
            else:
                # Need to pull out specific bands for each column.
                for j in range(nSubCols):
                    f.seek(rowPos + j * self.sample_size * self.nbands, 0)
                    pixelPos = f.tell()
                    for k in range(len(bands)):
                        f.seek(pixelPos + delta_b[k], 0)    # Next band
                        vals.fromfile(f, sample_size)
        arr = np.fromstring(tobytes(vals), dtype=self.dtype)
        arr = arr.reshape(nSubRows, nSubCols, nSubBands)

        if self.scale_factor != 1:
            return arr / float(self.scale_factor)
        return arr
예제 #11
0
def array_to_blob(arr):
    return sqlite3.Binary(tobytes(array.array(arraytypecode, arr)))