2016-12-30 15 views
3

위도 및 경도 데이터가있는 Python의 Basemap 모듈을 사용하여 RGB 이미지를 플로팅하는 데 문제가 있습니다. 이제 내가 원하는 플롯을 만들 수 있지만, 문제는 얼마나 느린가하는 것입니다. 단일 채널 데이터를 RGB 데이터보다 훨씬 빠르게 플로팅 할 수 있고, 일반적으로 RGB 이미지를 플로팅 할 수 있기 때문입니다. 빠른. 위도/경도 데이터가 있기 때문에 상황이 복잡해집니다. 나는이 문제에 대한 해결책을 체크 아웃했습니다Python basemap을 사용하여 geolocated RGB 데이터를 더 빠르게 플로팅하는 방법

How to plot an irregular spaced RGB image using python and basemap?

내가 지금 어디 오전에 도착하는 방법입니다. 근본적으로 다음 문제로 이어집니다. 베이스 맵에서 pcolormesh 메서드를 사용할 때 RGB 데이터를 플롯하려면 RGB 데이터를 점별로 매핑하는 colorTuple 매개 변수를 정의해야합니다. 배열 크기가 2000x1000 정도이므로이 작업을 수행하려면 시간이 필요합니다. 나는 아래 보이는 무슨 말인지의 조각 (더 아래 전체 작업 코드) :

if one_channel: 
    m.pcolormesh(lons, lats, img[:,:,0], latlon=True) 
else: 
    # This is the part that is slow, but I don't know how to 
    # accurately plot the data otherwise. 

    mesh_rgb = img[:, :-1, :] 
    colorTuple = mesh_rgb.reshape((mesh_rgb.shape[0] * mesh_rgb.shape[1]), 3) 

    # What you put in for the image doesn't matter because of the color mapping 
    m.pcolormesh(lons, lats, img[:,:,0], latlon=True,color=colorTuple) 

하나 개의 채널을 음모를 꾸미고, 그것은 약 10 초 정도의지도를 만들 수 있습니다. RGB 데이터를 플로팅 할 때 3-4 분이 걸릴 수 있습니다. 주어진 데이터의 3 배 밖에되지 않는다는 것을 감안할 때, 특히 RGB 데이터를 플로팅하는 것이 직사각형 이미지를 만들 때 하나의 채널 데이터만큼 빠르기 때문에 더 좋은 방법이 있어야한다고 생각합니다.

제 질문은 : 다른 계산 모듈 (예 : Bokeh)을 사용하거나 색상 매핑을 변경하는 방법으로이 계산을 빠르게 할 수 있습니까? 내가 신중하게 선택된지도 경계와 함께 imshow을 사용해 보았지만 이미지가지도의 전체 범위로 확대되기 때문에 데이터의 정확한 매핑을 위해서는 충분하지 않습니다.

from pyhdf.SD import SD,SDC 
import numpy as np 
from scipy.interpolate import interp1d 
import matplotlib.pyplot as plt 
from mpl_toolkits.basemap import Basemap 

def get_hdf_attr(infile,dataset,attr): 

    f = SD(infile,SDC.READ) 
    data = f.select(dataset) 
    index = data.attr(attr).index() 
    attr_out = data.attr(index).get() 
    f.end() 

    return attr_out 

def get_hdf_dataset(infile,dataset): 

    f = SD(infile,SDC.READ) 
    data = f.select(dataset)[:] 
    f.end() 

    return data 

class make_rgb: 

    def __init__(self,file_name): 

     sds_250 = get_hdf_dataset(file_name, 'EV_250_Aggr1km_RefSB') 
     scales_250 = get_hdf_attr(file_name, 'EV_250_Aggr1km_RefSB', 'reflectance_scales') 
     offsets_250 = get_hdf_attr(file_name, 'EV_250_Aggr1km_RefSB', 'reflectance_offsets') 

     sds_500 = get_hdf_dataset(file_name, 'EV_500_Aggr1km_RefSB') 
     scales_500 = get_hdf_attr(file_name, 'EV_500_Aggr1km_RefSB', 'reflectance_scales') 
     offsets_500 = get_hdf_attr(file_name, 'EV_500_Aggr1km_RefSB', 'reflectance_offsets') 

     data_shape = sds_250.shape 

     along_track = data_shape[1] 
     cross_track = data_shape[2] 

     rgb = np.zeros((along_track, cross_track, 3)) 

     rgb[:, :, 0] = (sds_250[0, :, :] - offsets_250[0]) * scales_250[0] 
     rgb[:, :, 1] = (sds_500[1, :, :] - offsets_500[1]) * scales_500[1] 
     rgb[:, :, 2] = (sds_500[0, :, :] - offsets_500[0]) * scales_500[0] 

     rgb[rgb > 1] = 1.0 
     rgb[rgb < 0] = 0.0 

     lin = np.array([0, 30, 60, 120, 190, 255])/255.0 
     nonlin = np.array([0, 110, 160, 210, 240, 255])/255.0 

     scale = interp1d(lin, nonlin, kind='quadratic') 

     self.img = scale(rgb) 

    def plot_image(self): 

     fig = plt.figure(figsize=(10, 10)) 
     ax = fig.add_subplot(111) 

     ax.set_yticks([]) 
     ax.set_xticks([]) 
     plt.imshow(self.img, interpolation='nearest') 
     plt.show() 

    def plot_geo(self,geo_file,one_channel=False): 

     fig = plt.figure(figsize=(10, 10)) 
     ax = fig.add_subplot(111) 

     lats = get_hdf_dataset(geo_file, 0) 
     lons = get_hdf_dataset(geo_file, 1) 

     lat_0 = np.mean(lats) 
     lat_range = [np.min(lats), np.max(lats)] 

     lon_0 = np.mean(lons) 
     lon_range = [np.min(lons), np.max(lons)] 

     map_kwargs = dict(projection='cass', resolution='l', 
          llcrnrlat=lat_range[0], urcrnrlat=lat_range[1], 
          llcrnrlon=lon_range[0], urcrnrlon=lon_range[1], 
          lat_0=lat_0, lon_0=lon_0) 

     m = Basemap(**map_kwargs) 

     if one_channel: 
      m.pcolormesh(lons, lats, self.img[:,:,0], latlon=True) 
     else: 
      # This is the part that is slow, but I don't know how to 
      # accurately plot the data otherwise. 
      mesh_rgb = self.img[:, :-1, :] 
      colorTuple = mesh_rgb.reshape((mesh_rgb.shape[0] * mesh_rgb.shape[1]), 3) 
      m.pcolormesh(lons, lats, self.img[:,:,0], latlon=True,color=colorTuple) 

     m.drawcoastlines() 
     m.drawcountries() 

     plt.show() 

if __name__ == '__main__': 

    # https://ladsweb.nascom.nasa.gov/archive/allData/6/MOD021KM/2015/183/ 
    data_file = 'MOD021KM.A2015183.1005.006.2015183195350.hdf' 

    # https://ladsweb.nascom.nasa.gov/archive/allData/6/MOD03/2015/183/ 
    geo_file = 'MOD03.A2015183.1005.006.2015183192656.hdf' 

    # Very Fast 
    make_rgb(data_file).plot_image() 

    # Also Fast, takes about 10 seconds 
    make_rgb(data_file).plot_geo(geo_file,one_channel=True) 

    # Much slower, takes several minutes 
    make_rgb(data_file).plot_geo(geo_file) 

답변

3

내가 켭니다 colorTuple의 모든 부분의 값에 추가 된 1.0에서이 문제를 해결 : 아래

올바른 모듈과 예제는 작동합니다 내 코드의 버전을 박탈하다 RGBA 배열로 변환합니다. 나는 pcolormesh 함수를 조사한 결과, RGBA를 RGBA 배열로 4 번 변환하는 컬러 변환기를 호출하는 것으로 나타 났으며, 매번 약 50 초가 걸렸습니다. 시작하려면 RGBA 배열을 지정하면이를 우회하여 적절한 시간대에 플롯을 생성합니다. 추가 된 추가 코드 줄은 아래와 같습니다.

if one_channel: 
    m.pcolormesh(lons, lats, img[:,:,0], latlon=True) 
else: 
    mesh_rgb = img[:, :-1, :] 
    colorTuple = mesh_rgb.reshape((mesh_rgb.shape[0] * mesh_rgb.shape[1]), 3) 

    # ADDED THIS LINE 
    colorTuple = np.insert(colorTuple,3,1.0,axis=1) 

    # What you put in for the image doesn't matter because of the color mapping 
    m.pcolormesh(lons, lats, img[:,:,0], latlon=True,color=colorTuple)