יותר

רסטר מסווג מחדש באמצעות פיתון, גדל וחושש

רסטר מסווג מחדש באמצעות פיתון, גדל וחושש


ברצוני לסווג מחדש קובץ רסטר מרסטר עם 10 כיתות לרסטר עם 8 כיתות באמצעות פייתון, GDAL ו / או קהה. הכיתות מיוצגות כמספרים שלמים. ניסיתי לעקוב אחר השלבים מהפוסט הזה לסווג מחדש רסטרים באמצעות GDAL ופייתון? , המסמך numpy.equal וגם gdal_calc doc. עם זאת, ללא הועיל.

לקובץ הראסטר שיש לסווג מחדש יש ערכים שלמים הנעים בין 0 ל -11 והוא כולל גם את הערכים 100 ו -255. להלן נראה הסיווג מחדש (מערך: לערך):

נודטה: 4, 0: 4, 1: 1, 2: 2, 3: 3, 4: 3, 5: 4, 6: 5, 7: 5, 8: 6, 9: 7, 10: 8, 100: nodata, 255: nodata,

מה שהצלחתי לעשות הוא לבחור את קובץ ה- raster שיש לסווג מחדש באמצעות tkinter.FileDialog ולקבל את המידע על ה- raster כגון geotransform, וגודל פיקסל עם class = gdal.Open (raster, GA_ReadOnly).

כיצד אוכל לפתור את האמור לעיל.

אולי כדאי להזכיר כי הרסטרים שיש לסווג מחדש יכולים להיות גדולים למדי במקרים מסוימים (500 מגה עד 5 גיגה).


הנה לך סקריפט פיתון פשוט לסיווג מחדש, כתבתי אותו וזה עובד בשבילי:

מאת osgeo ייבא מנהל התקן gdal = gdal.GetDriverByName ('GTiff') קובץ = gdal.Open ('/ בית / משתמש / סביבת עבודה / raster.tif') פס = קובץ. עבור j בטווח (file.RasterXSize): עבור i בטווח (file.RasterYSize): אם lista [i, j] <200: lista [i, j] = 1 elif 200 

פשוט שנה את הטווחים.

אני מקווה שזה יעזור.


במקום לעשות את הסיווג מחדש ככפול לולאה המתואר על ידי dmh126, עשה זאת באמצעותnp.where:

# סיווג מחדש רשימה [np.where (lista <200)] = 1 lista [np.where ((200  800)] = 5

במערך של 6163 על 3537 פיקסלים (41.6mb) הסיווג נעשה תוך 1.59 שניות, שם זה לוקח 12 דקות 41s באמצעות הכפול לולאה. בסך הכל רק מהירות של 478x.

בשורה התחתונה, לעולם אל תשתמש בכפול לשימוש בלולאהקהה


להלן דוגמה בסיסית המשתמשת ב- rasterio ו- dumped:

ייבא את rasterio כ- rio ייבא numpy כמו np עם rio.open ('~ / rasterio / tests / data / rgb1.tif') כ- src: קרא את ה- raster למערך (שורות, cols, עומק), # dstack זה לתוך (עומק, שורות, עמודים) מערך, # הסכום לאורך הציר האחרון (~ = גווני אפור) אפור = np.mean (np.dstack (src.read ()), ציר = 2) # קרא את פרופיל הקובץ srcprof = src .profile.copy () שיעורים = 5 # Breaks הוא מערך של הפסקות המחלקה: [0. 51. 102. 153. 204.] breaks = (np.arange (מחלקות) / float (מחלקות)) * grey.max () # סווג את הרסטר המסווג = np.sum (np.dstack ([(אפור 

רק כדי להשלים את התשובה מאת @Mattijn, אני חושב שזה יוביל לבעיה אם מחלקות הקלט חופפות למחלקות הפלט. אני לא רוצה שהערך החדש שלי ישתנה לפי הכלל הבא.

אני לא יודע אם אני מאבד מהירות אבל עלי לעשות העתק עמוק:

list_dest = lista.copy () list_dest [np.where (lista <0)] = 0 list_dest [np.where ((0 <= lista) & (lista <= 1))] = 1 list_dest [np.where (( 1 

במקרים מסוימים, דיגיטציה קהה יכולה להיות שימושית כדי לעבור במהירות מטווחים לפחים.

ייבא את rasterio ייבא מטומטם כ- np עם rasterio.open ('my_raster.tif') כ- src: array = src.read () פרופיל = src.profile bins = np.array ([- 1., - 0.7, -0.4, 0.2 , 1]) inds = np.digitize (מערך, פחים) עם rasterio.open ('output_raster.tif', 'w', ** פרופיל) כ- dst: dst.write (inds)

הנה גישה נוספת של Rasterio שפרצתי יחד באמצעות ספר הבישול של Rasterio ותשובת @ Mattijn.

ייבא rasterio ייבא numpy כמו np עם rasterio.open ('input_raster.tif') כ- src: # קרא כ- array מערך numpy = src.read () פרופיל = src.profile # סווג מחדש את המערך [np.where (array == 0) ] = מערך 4 [np.where (מערך == 2)] = 1 # וכן הלאה ... עם rasterio.open ('output_raster.tif', 'w', ** פרופיל) כ- dst: # כתוב לדיסק dst. כתוב (מערך)

עם תמיכה בשולחן RGB Raster צבעוני:

ייבא מטומטם כ- np מ osgeo יבוא gdal path_inDs = "/data/OCS_2016.extract.tif" path_outDs = "/data/OCS_2016.postpython.tif" driver = gdal.GetDriverByName ('GTiff') file = gdal.Open (path_inDs) אם הקובץ אינו: הדפס ('לא ניתן היה לפתוח קובץ תמונה') sys.exit (1) band = file.GetRasterBand (1) lista = band.ReadAsArray () # רשימה מחדש של רשימה [np.where (lista == 31)] = 16 # צור קובץ קובץ חדש 2 = driver.Create (path_outDs, file.RasterXSize, file.RasterYSize, 1, gdal.GPI_RGB) file2.GetRasterBand (1) .WriteArray (lista) # system ref system system = file.GetProjection () georef = file.GetGeoTransform () meta = file.GetMetadata () צבעים = file.GetRasterBand (1) .GetRasterColorTable () file2.SetProjection (proj) file2.SetGeoTransform (georef) file2.SetMetadata (meta) file2.Get .SetRasterColorTable (צבעים) file2.FlushCache () del file2

חלופה מעט שונה יכולה להיות הבאה:

ייבא מטומטם כ- np מ- osgeo ייבא gdal original = gdal.Open ('** PATH **  origianl_raster.tif') # קרא את פס הקובץ המקורי = original.GetRasterBand (1) # בהנחה שיש לקובץ רק מערך פס אחד = band.ReadAsArray () # צור מערך חדש עם ערכים מסווגים מחדש new_array = np.where (band_array == np.nan, 4, np.where (band_array == 0, 4, np.where (band_array == 1, 1 , np.where (band_array == 2, 2, np.where (band_array == 3, 3, np.where (band_array == 4, 3, np.where (band_array == 5, 4, np.where) (band_array == 6, 5, np.where (band_array == 7, 5, np.where (band_array == 8, 6, np.where (band_array == 9, 7, np.where (band_array == 10, 8, np.where (band_array == 100, np.nan, np.nan))))))))))))) # השורה האחרונה כוללת גם ערכים שווים 255, מכיוון שהם היחידים שנותרו # create and שמור רסטר מסווג מחדש כקובץ חדש outDs = gdal.GetDriverByName ('GTiff'). צור ("** PATH **  reclassified_raster.tif", original.RasterXSize, original.RasterYSize, 1, gdal.GDT_Float32) outBand = outDs . GetRast erBand (1) outBand.WriteArray (new_array) outDs.SetGeoTransform (original.GetGeoTransform ()) outDs.SetProjection (original.GetProjection ()) # cache flush outDs.FlushCache ()

סקריפט זה משחק עם numpy.where (https://docs.scipy.org/doc/numpy/reference/generated/numpy.where.html): בכל השלבים מלבד האחרון, במקום להחזיר ערך כאשר התנאי אינו מסופק, הוא מחזיר עוד מקום אחר. וזה ממשיך עד שנחשבים לכל הערכים האפשריים של הרסטר.


הנה גישה לסיווג מחדש שרירותי של רסטרים שלמים המונעת שימוש במיליון שיחות לnp.where. קטעי Rasterio שנלקחו מתשובת @ Aaron:

ייבא rasterio ייבא numpy כמו np # בנה "מערך בדיקת מידע" שבו האינדקס הוא הערך המקורי והערך # הוא הערך המסווג מחדש. הגדרת כל הערכים המסווגים מחדש זולה # מכיוון שהזיכרון מוקצה פעם אחת בלבד למערך החיפוש. Lookup = np.arange (255, dtype = np.uint8) Lookup [5] = 10 Lookup [6] = 100 Lookup [7] = 200 עם rasterio.open ('input_raster.tif') כ src: # קרא כמטומטם מערך מערך = src.read () פרופיל = src.profile # סיווג מחדש בפעולה אחת באמצעות מערך שידור = lookup [מערך] עם rasterio.open ('output_raster.tif', 'w', ** פרופיל) כ- dst: # כתוב לדיסק dst.write (מערך)

צפו בסרטון: Python GIS - Read raster data as numpy array GDAL