예제 #1
0
def create_feed_dict(data_index):
    # create feed dict
    current_image_RGB = cv2.imread(imageNames_RGB[data_index])
    current_image_Red = cv2.imread(imageNames_Red[data_index])
    current_image_NIR = cv2.imread(imageNames_NIR[data_index])
    current_image_Red_Edge = cv2.imread(imageNames_Red_Edge[data_index])
    current_image_Green = cv2.imread(imageNames_Green[data_index])

    current_image_green, _, _ = cv2.split(current_image_Green)
    current_image_red, _, _ = cv2.split(current_image_Red)
    current_image_nir, _, _ = cv2.split(current_image_NIR)
    current_image_red_edge,_, _ = cv2.split(current_image_Red_Edge)

    channel_marge = cv2.merge([current_image_red, current_image_nir, current_image_red_edge])
    channel_6 = np.concatenate((channel_marge, current_image_RGB), axis=2)


    ndvi = (current_image_nir - current_image_red) / (current_image_nir + current_image_red)


    VIgreen = (current_image_green - current_image_red) / (current_image_green + current_image_red)

    gndvi = (current_image_nir - current_image_green) / (current_image_nir + current_image_green)
    ndre = (current_image_nir - current_image_red_edge) / (current_image_nir + current_image_red_edge)
    savi = ((current_image_nir - current_image_red) / (current_image_nir + current_image_red) + 0.5) * 1.5

    data_index = str(data_index)

    masked_ndvi = np.ma.masked_outside(ndvi, 0.45, 1.2)
    fig, axis = plotutils.plotwithcolorbar(masked_ndvi, 'ndvi', figsize=figsize)
    plt.draw()
    fig.savefig(Training_path + data_index + '_ndvi.png')
    plt.close(fig)

    masked_vigreen = np.ma.masked_outside(VIgreen, 0.0, 0.2)
    fig, axis = plotutils.plotwithcolorbar(masked_vigreen, 'vi_green', figsize=figsize)
    plt.draw()
    fig.savefig(Training_path + data_index + '_vigreen.png')
    plt.close(fig)

    masked_gndvi = np.ma.masked_outside(gndvi, -1, 1)
    fig, axis = plotutils.plotwithcolorbar(masked_gndvi, 'gndvi', figsize=figsize)
    plt.draw()
    fig.savefig(Training_path + data_index + '_gndvi.png')
    plt.close(fig)

    masked_ndre = np.ma.masked_outside(ndre, -1, 1)
    fig, axis = plotutils.plotwithcolorbar(masked_ndre, 'ndre', figsize=figsize)
    plt.draw()
    fig.savefig(Training_path + data_index + '_ndre.png')
    plt.close(fig)

    masked_savi = np.ma.masked_outside(savi, -1, 1)
    fig, axis = plotutils.plotwithcolorbar(masked_savi, 'savi', figsize=figsize)
    plt.draw()
    fig.savefig(Training_path + data_index + '_savi.png')
    plt.close(fig)
예제 #2
0
 def plot_raw(self, title=None, figsize=None):
     ''' Create a single plot of the raw image '''
     if title is None:
         title = '{} Band {} Raw DN'.format(self.band_name, self.band_index)
     return plotutils.plotwithcolorbar(self.raw(),
                                       title=title,
                                       figsize=figsize)
예제 #3
0
 def plot_undistorted_radiance(self, title=None, figsize=None):
     ''' Create a single plot of the undistorted radiance '''
     if title is None:
         title = '{} Band {} Undistorted Radiance'.format(
             self.band_name, self.band_index)
     return plotutils.plotwithcolorbar(self.undistorted(self.radiance()),
                                       title=title,
                                       figsize=figsize)
예제 #4
0
 def plot_vignette(self, title=None, figsize=None):
     ''' Create a single plot of the vignette '''
     if title is None:
         title = '{} Band {} Vignette'.format(self.band_name,
                                              self.band_index)
     return plotutils.plotwithcolorbar(self.plottable_vignette(),
                                       title=title,
                                       figsize=figsize)
예제 #5
0
 def plot_radiance(self, title=None, figsize=None):
     ''' Create a single plot of the image converted to radiance '''
     if title is None:
         title = '{} Band {} Radiance'.format(self.band_name,
                                              self.band_index)
     return plotutils.plotwithcolorbar(self.radiance(),
                                       title=title,
                                       figsize=figsize)
예제 #6
0
 def plot_intensity(self, title=None, figsize=None):
     ''' Create a single plot of the image converted to uncalibrated intensity '''
     if title is None:
         title = '{} Band {} Intensity (DN*sec)'.format(
             self.band_name, self.band_index)
     return plotutils.plotwithcolorbar(self.intensity(),
                                       title=title,
                                       figsize=figsize)
예제 #7
0
def align(pair):
    """ Determine an alignment matrix between two images
    @input:
    Dictionary of the following form:
    {
        'warp_mode':  cv2.MOTION_* (MOTION_AFFINE, MOTION_HOMOGRAPHY)
        'max_iterations': Maximum number of solver iterations
        'epsilon_threshold': Solver stopping threshold
        'ref_index': index of reference image
        'match_index': index of image to match to reference
    }
    @returns:
    Dictionary of the following form:
    {
        'ref_index': index of reference image
        'match_index': index of image to match to reference
        'warp_matrix': transformation matrix to use to map match image to reference image frame
    }

    Major props to Alexander Reynolds ( https://stackoverflow.com/users/5087436/alexander-reynolds ) for his
    insight into the pyramided matching process found at
    https://stackoverflow.com/questions/45997891/cv2-motion-euclidean-for-the-warp-mode-in-ecc-image-alignment-method

    """
    warp_mode = pair['warp_mode']
    max_iterations = pair['max_iterations']
    epsilon_threshold = pair['epsilon_threshold']
    ref_index = pair['ref_index']
    match_index = pair['match_index']
    translations = pair['translations']

    # Initialize the matrix to identity
    if warp_mode == cv2.MOTION_HOMOGRAPHY:
        warp_matrix = np.array(
            [[1, 0, translations[1]], [0, 1, translations[0]], [0, 0, 1]],
            dtype=np.float32)
    else:
        # warp_matrix = np.array([[1,0,0],[0,1,0]], dtype=np.float32)
        warp_matrix = np.array(
            [[1, 0, translations[1]], [0, 1, translations[0]]],
            dtype=np.float32)

    w = pair['ref_image'].shape[1]

    nol = int(w / (1280 / 3)) - 1

    print("number of pyramid levels: {}".format(nol))

    warp_matrix[0][2] /= (2**nol)
    warp_matrix[1][2] /= (2**nol)

    if ref_index != match_index:

        show_debug_images = pair['debug']
        # construct grayscale pyramid
        gray1 = pair['ref_image']
        gray2 = pair['match_image']
        if gray2.shape[0] < gray1.shape[0]:
            cv2.resize(gray2,
                       None,
                       fx=gray1.shape[0] / gray2.shape[0],
                       fy=gray1.shape[0] / gray2.shape[0],
                       interpolation=cv2.INTER_AREA)
        gray1_pyr = [gray1]
        gray2_pyr = [gray2]

        for level in range(nol):
            gray1_pyr[0] = gaussian(normalize(gray1_pyr[0]))
            gray1_pyr.insert(
                0,
                cv2.resize(gray1_pyr[0],
                           None,
                           fx=1 / 2,
                           fy=1 / 2,
                           interpolation=cv2.INTER_AREA))
            gray2_pyr[0] = gaussian(normalize(gray2_pyr[0]))
            gray2_pyr.insert(
                0,
                cv2.resize(gray2_pyr[0],
                           None,
                           fx=1 / 2,
                           fy=1 / 2,
                           interpolation=cv2.INTER_AREA))

        # Terminate the optimizer if either the max iterations or the threshold are reached
        criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT,
                    max_iterations, epsilon_threshold)
        # run pyramid ECC
        for level in range(nol + 1):
            grad1 = gradient(gray1_pyr[level])
            grad2 = gradient(gray2_pyr[level])

            if show_debug_images:
                import micasense.plotutils as plotutils
                plotutils.plotwithcolorbar(gray1_pyr[level],
                                           "ref level {}".format(level))
                plotutils.plotwithcolorbar(gray2_pyr[level],
                                           "match level {}".format(level))
                plotutils.plotwithcolorbar(grad1,
                                           "ref grad level {}".format(level))
                plotutils.plotwithcolorbar(grad2,
                                           "match grad level {}".format(level))
                print("Starting warp for level {} is:\n {}".format(
                    level, warp_matrix))

            cc, warp_matrix = cv2.findTransformECC(grad1,
                                                   grad2,
                                                   warp_matrix,
                                                   warp_mode,
                                                   criteria,
                                                   inputMask=None,
                                                   gaussFiltSize=1)

            if show_debug_images:
                print("Warp after alignment level {} is \n{}".format(
                    level, warp_matrix))

            if level != nol:  # scale up only the offset by a factor of 2 for the next (larger image) pyramid level
                if warp_mode == cv2.MOTION_HOMOGRAPHY:
                    warp_matrix = warp_matrix * np.array(
                        [[1, 1, 2], [1, 1, 2], [0.5, 0.5, 1]],
                        dtype=np.float32)
                else:
                    warp_matrix = warp_matrix * np.array(
                        [[1, 1, 2], [1, 1, 2]], dtype=np.float32)

    return {
        'ref_index': pair['ref_index'],
        'match_index': pair['match_index'],
        'warp_matrix': warp_matrix
    }
예제 #8
0
def align(pair):
    """ Determine an alignment matrix between two images
    @input:
    Dictionary of the following form:
    {
        'warp_mode':  cv2.MOTION_* (MOTION_AFFINE, MOTION_HOMOGRAPHY)
        'max_iterations': Maximum number of solver iterations
        'epsilon_threshold': Solver stopping threshold
        'ref_index': index of reference image
        'match_index': index of image to match to reference
    }
    @returns:
    Dictionary of the following form:
    {
        'ref_index': index of reference image
        'match_index': index of image to match to reference
        'warp_matrix': transformation matrix to use to map match image to reference image frame
    }

    Major props to Alexander Reynolds ( https://stackoverflow.com/users/5087436/alexander-reynolds ) for his
    insight into the pyramided matching process found at
    https://stackoverflow.com/questions/45997891/cv2-motion-euclidean-for-the-warp-mode-in-ecc-image-alignment-method
    
    """
    warp_mode = pair['warp_mode']
    max_iterations = pair['max_iterations']
    epsilon_threshold = pair['epsilon_threshold']
    ref_index = pair['ref_index']
    match_index = pair['match_index']
    translations = pair['translations']
    close_range = pair['close_range']

    # Initialize the matrix to identity
    if warp_mode == cv2.MOTION_HOMOGRAPHY:
        # warp_matrix = np.array([[1,0,0],[0,1,0],[0,0,1]], dtype=np.float32)
        warp_matrix = pair['warp_matrix_init']
    else:
        # warp_matrix = np.array([[1,0,0],[0,1,0]], dtype=np.float32)
        warp_matrix = np.array(
            [[1, 0, translations[1]], [0, 1, translations[0]]],
            dtype=np.float32)

    w = pair['ref_image'].shape[1]

    if pair['pyramid_levels'] is None:
        nol = int(w / (1280 / 3)) - 1
    else:
        nol = pair['pyramid_levels']

    if pair['debug']:
        print("number of pyramid levels: {}".format(nol))

    warp_matrix[0][2] /= (2**nol)
    warp_matrix[1][2] /= (2**nol)

    if close_range:
        matrix_box = np.zeros((3, 3, 5), dtype=np.float32)
        matrix_box[:, :, 0] = np.array(
            [[1.01990501e+00, 6.60780396e-02, 1.61565981e+01],
             [1.02941529e-02, 1.04839095e+00, -5.93324724e+01],
             [-2.39299405e-06, 6.57833196e-05, 1.00000000e+00]],
            dtype=np.float32)
        matrix_box[:, :, 1] = np.array(
            [[9.64607505e-01, -5.80503997e-04, -1.90982485e+00],
             [-1.75293196e-02, 9.55154457e-01, -2.94900879e+01],
             [-4.10977951e-05, -2.78523751e-06, 1.00000000e+00]],
            dtype=np.float32)
        matrix_box[:, :, 3] = np.array(
            [[1.06259853e+00, 7.81775979e-02, 1.45072993e+01],
             [1.99893573e-02, 1.10691304e+00, -4.95636256e+01],
             [3.31475328e-05, 8.63813674e-05, 1.00000000e+00]],
            dtype=np.float32)
        matrix_box[:, :, 4] = np.array(
            [[1.00576555e+00, 3.10690919e-02, 5.54705923e+00],
             [4.39865262e-03, 1.02901756e+00, -2.45425948e+01],
             [-1.34695946e-05, 4.22982177e-05, 1.00000000e+00]],
            dtype=np.float32)
        warp_matrix = matrix_box[:, :, match_index]

#    if close_range:
#        matrix_box = np.zeros((3, 3, 5), dtype=np.float32)
#        matrix_box[:,:,0] = np.array([[ 9.85234288e-01, -6.02857058e-02, -1.97861800e+01],
#        [-9.13546319e-03,  9.54160086e-01,  5.71365581e+01],
#        [ 3.68473019e-06, -6.25908142e-05,  1.00000000e+00]], dtype=np.float32)
#        matrix_box[:,:,1] = np.array([[1.03681022e+00, 7.94539658e-04, 1.94929221e+00],
#        [2.05548527e-02, 1.04714741e+00, 3.08336762e+01],
#        [4.27748983e-05, 3.30673535e-06, 1.00000000e+00]], dtype=np.float32)
#        matrix_box[:,:,3] = np.array([[ 9.45799261e-01, -6.47190144e-02, -1.73228004e+01],
#        [-1.90123138e-02,  9.04237787e-01,  4.54668636e+01],
#        [-3.06740010e-05, -7.49444305e-05,  1.00000000e+00]], dtype=np.float32)
#        matrix_box[:,:,4] = np.array([[ 9.95893056e-01, -2.93410233e-02, -6.50957883e+00],
#        [-3.86456817e-03,  9.72735207e-01,  2.37574987e+01],
#        [ 1.36621685e-05, -4.07031605e-05,  1.00000000e+00]], dtype=np.float32)
#        warp_matrix = matrix_box[:,:, match_index]

    if ref_index != match_index:

        show_debug_images = pair['debug']
        # construct grayscale pyramid
        gray1 = pair['ref_image']
        gray2 = pair['match_image']
        if gray2.shape[0] < gray1.shape[0]:
            cv2.resize(gray2,
                       None,
                       fx=gray1.shape[0] / gray2.shape[0],
                       fy=gray1.shape[0] / gray2.shape[0],
                       interpolation=cv2.INTER_AREA)
        gray1_pyr = [gray1]
        gray2_pyr = [gray2]

        for level in range(nol):
            gray1_pyr[0] = gaussian(normalize(gray1_pyr[0]))
            gray1_pyr.insert(
                0,
                cv2.resize(gray1_pyr[0],
                           None,
                           fx=1 / 2,
                           fy=1 / 2,
                           interpolation=cv2.INTER_AREA))
            gray2_pyr[0] = gaussian(normalize(gray2_pyr[0]))
            gray2_pyr.insert(
                0,
                cv2.resize(gray2_pyr[0],
                           None,
                           fx=1 / 2,
                           fy=1 / 2,
                           interpolation=cv2.INTER_AREA))

        # Terminate the optimizer if either the max iterations or the threshold are reached
        criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT,
                    max_iterations, epsilon_threshold)
        # run pyramid ECC
        for level in range(nol + 1):
            grad1 = gradient(gray1_pyr[level])
            grad2 = gradient(gray2_pyr[level])

            if show_debug_images:
                import micasense.plotutils as plotutils
                plotutils.plotwithcolorbar(gray1_pyr[level],
                                           "ref level {}".format(level))
                plotutils.plotwithcolorbar(gray2_pyr[level],
                                           "match level {}".format(level))
                plotutils.plotwithcolorbar(grad1,
                                           "ref grad level {}".format(level))
                plotutils.plotwithcolorbar(grad2,
                                           "match grad level {}".format(level))
                print("Starting warp for level {} is:\n {}".format(
                    level, warp_matrix))


#            cc, warp_matrix = cv2.findTransformECC(grad1, grad2, warp_matrix, warp_mode, criteria)
#            print("image correlation = {:4.2f}".format(cc))
            if show_debug_images:
                print("Warp after alignment level {} is \n{}".format(
                    level, warp_matrix))

            if level != nol:  # scale up only the offset by a factor of 2 for the next (larger image) pyramid level
                if warp_mode == cv2.MOTION_HOMOGRAPHY:
                    warp_matrix = warp_matrix * np.array(
                        [[1, 1, 2], [1, 1, 2], [0.5, 0.5, 1]],
                        dtype=np.float32)
                else:
                    warp_matrix = warp_matrix * np.array(
                        [[1, 1, 2], [1, 1, 2]], dtype=np.float32)

    return {
        'ref_index': pair['ref_index'],
        'match_index': pair['match_index'],
        'warp_matrix': warp_matrix
    }
예제 #9
0
##############################################################################
#Calculate Radiance to Reflectance Conversion for Each Band using the Calibration Panel Images
#Need to perform manually for each band because masked panel area shifts

#PREFLIGHT CALIBRATION IMAGES
##############
#Band 1 (Blue)
#Plotting
imageName = os.path.join(CalibrationFolder_preflight, 'IMG_0002_1.tif')
imageRaw = plt.imread(
    imageName).T  # Read raw image DN values - 16 bit tif only
plt.imshow(imageRaw.T, cmap='gray')
plotutils.colormap('viridis')
# Optional: pick a color map: 'gray, viridis, plasma, inferno, magma, nipy_spectral'
fig = plotutils.plotwithcolorbar(imageRaw.T,
                                 title='Raw image values with colorbar')

#Image metadata
meta = metadata.Metadata(imageName, exiftoolPath=exiftoolPath)
bandName = meta.get_item('XMP:BandName')

#Converting raw images to Radiance
radianceImage, L, V, R = msutils.raw_image_to_radiance(meta, imageRaw.T)
plotutils.plotwithcolorbar(V, 'Vignette Factor')
plotutils.plotwithcolorbar(R, 'Row Gradient Factor')
plotutils.plotwithcolorbar(V * R, 'Combined Corrections')
plotutils.plotwithcolorbar(L, 'Vignette and row gradient corrected raw values')
plotutils.plotwithcolorbar(radianceImage,
                           'All factors applied and scaled to radiance')

#Mask to panel and calculate radiance
예제 #10
0
import micasense.metadata as metadata

sys.path.append('C:/Users/Isaac Miller/Documents/GitHub/imageprocessing')

exiftoolPath = None
if os.name == 'nt':
    exiftoolPath = 'C:/exiftool/exiftool.exe'

#  get calibration
panelPath = os.path.join('.', 'data', '0000SET', '000')
panelName = glob.glob(os.path.join(panelPath, 'IMG_0000_1.tif'))[0]

panelRaw = plt.imread(panelName)
panelMeta = metadata.Metadata(panelName, exiftoolPath=exiftoolPath)
radianceImage, L, V, R = msutils.raw_image_to_radiance(panelMeta, panelRaw)
plotutils.plotwithcolorbar(V, 'Vignette Factor')
plotutils.plotwithcolorbar(R, 'Row Gradient Factor')
plotutils.plotwithcolorbar(V * R, 'Combined Corrections')
plotutils.plotwithcolorbar(L, 'Vignette and row gradient corrected raw values')
plotutils.plotwithcolorbar(radianceImage,
                           'All factors applied and scaled to radiance')
markedImg = radianceImage.copy()
ulx = 660  # upper left column (x coordinate) of panel area
uly = 490  # upper left row (y coordinate) of panel area
lrx = 840  # lower right column (x coordinate) of panel area
lry = 670  # lower right row (y coordinate) of panel area
cv2.rectangle(markedImg, (ulx, uly), (lrx, lry), (0, 255, 0), 3)

# Our panel calibration by band (from MicaSense for our specific panel)
panelCalibration = {
    "Blue": 0.67,
예제 #11
0
    "Blue": 0.66,
    "Green": 0.67,
    "Red": 0.67,
    "Red edge": 0.66,
    "NIR": 0.6
}

# Select panel region from radiance image
print(
    'Mean Radiance in panel region: {:1.3f} W/m^2/nm/sr'.format(meanRadiance))
panelReflectance = panelCalibration[bandName]
radianceToReflectance = panelReflectance / meanRadiance
print('Radiance to reflectance conversion factor: {:1.5f}'.format(
    radianceToReflectance))
reflectanceImage = radianceImage * radianceToReflectance
plotutils.plotwithcolorbar(reflectanceImage, 'Converted Reflectane Image')

# ulx = int(numpy.min([nw_x,sw_x,ne_x,se_x])*1.2)
# lrx = int(numpy.max([nw_x,sw_x,ne_x,se_x])*0.8)
# uly = int(numpy.min([nw_y,sw_y,ne_y,se_y])*1.2)
# lry = int(numpy.max([nw_y,sw_y,ne_y,se_y])*0.8)
# markedImg = reflectanceImage.copy()
# cv2.rectangle(markedImg,(ulx,uly),(lrx,lry),(0,255,0),3)
# panelRegionRefl = reflectanceImage[uly:lry, ulx:lrx]
# panelRegionReflBlur = cv2.GaussianBlur(panelRegionRefl,(55,55),5)
# plotutils.plotwithcolorbar(panelRegionReflBlur, 'Smoothed panel region in reflectance image')
# print('Min Reflectance in panel region: {:1.2f}'.format(panelRegionRefl.min()))
# print('Max Reflectance in panel region: {:1.2f}'.format(panelRegionRefl.max()))
# print('Mean Reflectance in panel region: {:1.2f}'.format(panelRegionRefl.mean()))
# print('Standard deviation in region: {:1.4f}'.format(panelRegionRefl.std()))