sha*_*nus 5 wolfram-mathematica
我有一个非常大的浮点图像数据:
In[25]:= Dimensions[daylightImgd]
Out[25]= {18, 2002, 2989}
In[26]:= daylightImgd[[1, 1]][[1 ;; 10]]
Out[26]= {0.0122293, 0.0104803, 0.0103955, 0.0115533, 0.0118063, \
0.0120648, 0.0122957, 0.011398, 0.0117426, 0.0119997}
Run Code Online (Sandbox Code Playgroud)
我可以使用DumpSave a la成功地将整个图像阵列保存到磁盘:
DumpSave["thisWorks.mx", daylightImgd]
Run Code Online (Sandbox Code Playgroud)
倾倒这个巨人(861兆字节文件)只需不到10秒.如果我对这些图像进行下采样,则la:
downsample[image_, f_] := Module[{w, h}, h = Dimensions[image][[1]];
w = Dimensions[image][[2]];
Table[image[[i, j]], {i, 1, h, f}, {j, 1, w, f}]]
In[26]:= daylightImgdDown = downsample[#, 4] & /@ daylightImgd;
In[27]:= Dimensions[daylightImgdDown]
Out[27]= {18, 500, 748}
In[28]:= daylightImgdDown[[1, 1]][[1 ;; 10]]
Out[28]= {0.0122293, 0.0118063, 0.0117426, 0.0119349, 0.0109443, \
0.0121632, 0.0121304, 0.00681408, 0.0101728, 0.00603242}
Run Code Online (Sandbox Code Playgroud)
突然间我不能再倾倒了; 这东西永远挂起并旋转 - 或者至少持续很长时间,直到我杀死它并且最大化CPU:
In[31]:= DumpSave["broken.mx", daylightImgdDown]; (* Hangs forever *)
Run Code Online (Sandbox Code Playgroud)
到目前为止,我可以确定,一切都是应有的:下采样图像具有正确的尺寸; 你可以通过ArrayPlot绘制它们,一切看起来都很棒; 手动列出第一行看起来很好.简而言之,所有内容都与非下采样图像相同,但是在DumpSave悬挂的小得多的数据集上.
救命?
更新:评论迈克尔的答案
哇.感谢您提供了非常彻底的答案,这个答案不仅回答了我的问题,还教会了我一些外围的东西.
对于你的参考,pack-ness的问题比用你的一个替换我的下行样本[]有点棘手.由于我试图转储的数组是一个包含18个图像的数组 - 换句话说是一个3d数组 - 而且由于我通过Map运算符应用了下采样,因此3d数组的打包错误(根据PackedArrayQ) )使用您的任何下采样重写.
但是,如果我获取这些应用程序的输出,然后打包生成的3d数组,那么整个3d数组都被打包,只有这样我才可以DumpSave它.奇怪的是,正如ByteCount所报告的那样,这个最终的打包过程虽然是成功的DumpSave所必需的,但似乎几乎没有改变尺寸.也许这在代码中更容易:
In[42]:= downsample3[image_, f_] :=
Module[{w, h}, h = Dimensions[image][[1]];
w = Dimensions[image][[2]];
Developer`ToPackedArray@Table[image[[i, j]], {i, 1, h, f}, {j, 1, w, f}]]
In[43]:= daylightImgdDown = downsample3[#, downsampleSize] & /@ daylightImgd;
In[44]:= ByteCount[daylightImgdDown]
Out[44]= 53966192
In[45]:= Developer`PackedArrayQ[daylightImgdDown]
Out[45]= False
In[46]:= dd = Developer`ToPackedArray[daylightImgdDown];
In[47]:= Developer`PackedArrayQ[dd]
Out[47]= True
In[48]:= ByteCount[dd]
Out[48]= 53963844
In[49]:= DumpSave["daylightImgdDown.mx", dd]; (* works now! *)
Run Code Online (Sandbox Code Playgroud)
再次,非常感谢.
没有实际数据,一个有根据的猜测是大型数据DumpSave快速的原因是因为它是一个所谓的"打包数组",即一个机器大小的浮点数数组,在Mathematica中具有非常有效的表示.您的downsample函数(由于使用Table)不返回打包数组,该数组在内存中要大得多,在下采样4X后可能比原始数组大.ByteCount可能在那里说明.
您可以检查packed-array-ness,PackedArrayQ并尝试打包一个解压缩的数组ToPackedArray,两者都在Developer上下文中找到.
如果我的猜测是正确的,有两种解决方案.一个是使用ToPackedArray如下所示:
downsample[image_, f_] := Module[{w, h}, h = Dimensions[image][[1]];
w = Dimensions[image][[2]];
Developer`ToPackedArray@Table[image[[i, j]], {i, 1, h, f}, {j, 1, w, f}]]
Run Code Online (Sandbox Code Playgroud)
更妙的是简单地取代你用Table用Take,应该在这种情况下返回压缩数组,并作为额外的奖励会比使用快了很多Table.
downsample[image_, f_] := Take[image, {1,-1,f}, {1,-1,f}]
Run Code Online (Sandbox Code Playgroud)
您可能还对Mathematica 7 中的所有新图像处理功能感兴趣.
希望有所帮助!