一、grib文件簡介
WMO是世界氣象組織,world meteorology organization。
GRIB是WMO開發的一種用於交換和存儲規則分布數據的二進制文件格式。最初GRIB表示“二進制格點”(GRIdded Binary),后來擴展為“二進制的通用規則分布信息”(General Regularly-distributed Information in Binary form)。
GRIB 是與計算機無關的壓縮的二進制編碼,主要用來表示數值天氣預報的產品資料。現行的GRIB 碼版本有GRIB1 和GRIB2 兩種格式。 GRIB2較之GRIB1具有更多優點而被廣泛使用。如:表示多維數據、模塊性結構、支持多種壓縮方式、IEEE標准浮點表示法等。
二、grib相關的庫
1、python
grib文件解析有三種方式,pygrib、wgrib、pupygrib。
pupygrib是純python版的grib文件解析方式,但是它只解析了個大概,並沒有解析section7中的數據。
wgrib本身是用C語言實現的庫,python中的wgrib是在命令行的基礎上做了一些封裝。
pupygrib一個例子
···python
import pupygrib as g
filepath = r"C:\Users\weidiao\Desktop\NAFP_T639_1_FTM-38-NEHE-WIU-281X281-100-1000-999998-002-999998-2018111200-216.GRB"
def parse(filepath):
messages = list(g.read(open(filepath, mode='rb')))
if len(messages) > 1:
raise Exception("I didn't expect len(message)>1,but now len(messages)={}".format(len(messages)))
message = messages[0]
for section_id, section in enumerate(message):
print('=' * 10)
print('section', section_id)
for attr in dir(section):
if not attr.startswith('__'):
print(attr, getattr(section, attr))
if not message[5].dataRepresentationTemplateNumber == 40:
# 只能解壓jpeg2000格式的文件
raise Exception("cannot parse dataRepresentationTemplateNumber {}".format(message[5].dataRepresentationTemplateNumber))
return message[7]._data[6:]
def get_data(filepath):
data = parse(filepath)
print('\n' * 3)
print(len(data))
print(dir(data))
print(data[:40].tolist())
parse(filepath)
···
2、java
jgrib已經不活躍了:http://jgrib.sourceforge.net/
jgribx是jrib的替代品 https://github.com/spidru/JGribX
github上有好多,但是質量良莠不齊https://github.com/search?q=grib
三、grib文件格式簡介
grib文件包含從0到8共9個section,每個section用途不一樣。
section0有16個字節,分別表示GRIB(4字節的字符串),接下來5-6字節保留備用,第7個字節表示discipline也就是所遵守的規范,第8字節表示版本號,一般為2。第9到第16字節共8個字節(一個long型數字)表示整個GRIB message所占字節數。
總之,section0描述的是整個message的信息,是統領全文的作用。
section1至少有21字節,表示一堆版本號和時間。
總之,section1描述的也是數據格式的元信息。
section2是給用戶自己用的,用戶可以在這里自由發揮。
section3是網格定義區域。
section5是數據格式描述區域,描述了section7中數據的壓縮方式。
section7是最重要的部分,從第6個字節開始存儲的是壓縮的字節數據。
NCEP 官網文檔
http://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/
四、jpeg2000
JPEG 全名為 Joint Photographic Experts Group,它是一個在國際標准組織(ISO)下從事靜態圖像壓縮標准制定的委員會。它制定出了第一套國標靜態圖像壓縮標准:ISO 10918-1 就是我們俗稱的 JPEG 了。由於JPEG優良的品質,使得它在短短的幾年內就獲得極大的成功,目前網站上百分之八十的圖像都是采用JPEG的壓縮標准。然而,隨著多媒體應用領域的激增,傳統JPEG壓縮技術已無法滿足人們對多媒體圖像資料的要求。因此,更高壓縮率以及更多新功能的新一代靜態圖像壓縮技術 JPEG 2000 就誕生了。JPEG 2000 正式名稱為 “ISO 15444” ,同樣是由JPEG 組織負責制定。自1997年三月開始籌划,但這幾年間,在算法選取問題上耽誤了不少時間,人們普遍預計要到2000年十二月JPEG2000才能制定完成! 但在2000年3 月的東京的一個會議上,可能是由於數字照相機廠商們施加壓力,規定基本編碼系統的最終協議草案提前出台,終於不用改名為 JPEG2001 了。
JPEG 2000是基於小波變換的圖像壓縮標准,由Joint Photographic Experts Group組織創建和維護。JPEG 2000通常被認為是未來取代JPEG(基於離散余弦變換)的下一代圖像壓縮標准。JPEG 2000文件的副檔名通常為.jp2,MIME類型是image/jp2。
JPEG2000的壓縮比更高,而且不會產生原先的基於離散余弦變換的JPEG標准產生的塊狀模糊瑕疵。JPEG2000同時支持有損壓縮和無損壓縮。另外,JPEG2000也支持更復雜的漸進式顯示和下載。
JPEG2000是國際標准化組織(ISO)發布的標准,文檔代碼為ISO/IEC 15444-1:2000。雖然JPEG2000在技術上有一定的優勢,但是到目前為止(2006年),網絡上采用JPEG2000技術制作的圖像文件數量仍然很少,並且大多數的瀏覽器仍然沒有內置支持JPEG2000圖像文件的顯示。但是,由於JPEG2000在無損壓縮下仍然能有比較好的壓縮率,所以JPEG2000在圖像品質要求比較高的醫學圖像的分析和處理中已經有了一定程度的廣泛應用。
JPEG2000的優點
1、JPEG2000 作為JPEG升級版,高壓縮(低碼率)是其目標,其壓縮率比 JPEG 高約 30% 左右。
2、JPEG2000 同時支持有損和無損壓縮,而 JPEG 只能支持有損壓縮。因此它適合保存重要圖片。
3、JPEG2000 能實現漸進傳輸,這是JPEG2000的一個極其重要的特征。這也就是我們對 GIF 格式圖像常說的“漸現”特性。它先傳輸圖像的輪廓,然后逐步傳輸數據,不斷提高圖像質量,讓圖象由朦朧到清晰顯示,而不必是像現在的 JPEG 一樣,由上到下慢慢顯示。
4、JPEG2000 支持所謂的“感興趣區域”特性,你可以任意指定圖像上你感興趣區域的壓縮質量,還可以選擇指定的部份先解壓縮。這樣我們就可以很方便的突出重點了。
JPEG2000存在版權和專利的風險。這也許是目前JPEG2000技術沒有得到廣泛應用的原因之一。JPEG2000標准本身是沒有授權費用,但是,因為編碼的核心部分的各種演算法被大量注冊專利,所以一般認為,不太可能避開這些專利費用開發出免授權費的商用編碼器。
五、glymur並不好用
使用jpg壓縮glymur自帶j2k圖片,結果壓縮之后比j2k要小,這說明jpeg2000似乎不太好用,不知是glymur的問題還是jpeg2000的問題。
import glymur
jp2file = glymur.data.nemo() # just a path to a JPEG2000 file
print(jp2file)
jp2 = glymur.Jp2k(jp2file)
fullres = jp2[:]
print(fullres.shape)
io.imsave('nemo.jpg', fullres)
做了其他實驗也是這樣。
import os
import pylab as plt
from skimage import io
import glymur
def transform(filepath):
target = os.path.join(filepath, 'target')
if not os.path.exists(target):
os.mkdir(target)
for i in filter(lambda file: os.path.isfile(os.path.join(filepath, file)), os.listdir(filepath)):
img = io.imread(os.path.join(filepath, i))
jp = glymur.Jp2k(os.path.join(target, i + '.j2k'), data=img)
print(jp)
def show_difference(filepath):
target = os.path.join(filepath, 'target')
for i in filter(lambda file: os.path.isfile(os.path.join(filepath, file)), os.listdir(filepath)):
original = io.imread(os.path.join(filepath, i))
jp_path = os.path.join(target, i + '.j2k')
jp = glymur.Jp2k(jp_path)
fig, (one, two) = plt.subplots(1, 2)
one.imshow(original)
one.set_title('original {}'.format(os.path.getsize(os.path.join(filepath, i))))
two.imshow(jp[:])
two.set_title('compressed {}'.format(os.path.getsize(jp_path)))
plt.show()
transform('imgs')
print('transform over')
show_difference('imgs')
參考資料
百度百科
https://baike.baidu.com/item/GRIB2/13466125?fr=aladdin
wmo grib2官網文檔
http://www.wmo.int/pages/prog/www/WMOCodes/WMO306_vI2/LatestVERSION/LatestVERSION.html
pupygrib官網 https://notabug.org/mjakob/pupygrib
pupygrib pypi https://pypi.org/project/pupygrib/
wgrip官網
http://www.cpc.ncep.noaa.gov/products/wesley/wgrib.html
wgrip用法
https://blog.csdn.net/m0_37600626/article/details/79311129
python glymur解析jpeg2000
https://glymur.readthedocs.io/en/latest/
pyopenjpeg已經不維護了,作者推薦使用glymur
https://github.com/khughitt/pyopenjpeg
glymur和pyopenjpeg是在openjpeg上用python封裝了一層,它需要依賴openjpeg動態鏈接庫,所以我們需要把這個動態鏈接庫放到全局路徑下。
zygrib:http://www.zygrib.org/#section_windows
zygrib是一個可視化工具。
openjpeg是一個用C語言實現的jpeg2000壓縮、解壓縮算法,非常高端的算法,一般人實現不了,這整個庫都是為了一個jpeg2000算法。
https://www.openjpeg.org/
jpeg2000算法-百度百科
https://baike.baidu.com/item/JPEG 2000/8097196?fr=aladdin
jpeg2000編解碼原理
https://blog.csdn.net/ytang_/article/details/76571635
jpeg和jpeg2000
https://blog.csdn.net/lg1259156776/article/details/49010219
java解析grib
http://jgrib.sourceforge.net/
https://mvnrepository.com/search?q=grib