2010-08-25 100 views
5

我有一个非常大的阵列浮点图像数据:莫名其妙Mathematica7 DumpSave []问题

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} 

我可以保存此整个图像阵列到磁盘成功地使用DumpSave一拉:

DumpSave["thisWorks.mx", daylightImgd] 

倾倒这个巨人(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} 

然后突然我不能dumpumps了;东西挂起并不断旋转 - 或至少多分钟,直到我杀了它,并马克塞斯CPU:

In[31]:= DumpSave["broken.mx", daylightImgdDown]; (* Hangs forever *) 

到目前为止,我能确定,一切都因为它应该是:采样图像有正确的尺寸;你可以通过ArrayPlot绘制它们,一切看起来都很棒;手动列出第一行看起来不错。简而言之,所有内容都与未下采样的图像相同,但小数据集DumpSave会挂起。

帮助?

UPDATE:迈克尔的回答

哇评论。感谢您提供了非常透彻的答案,这不仅回答了我的问题,而且教会了我一些外围的东西。

为了供您参考,包装的问题比仅仅使用你的其中一个取代我的下采样[]有点棘手。由于我试图转储的数组是一个包含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`[email protected][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! *) 

再次,非常感谢。

回答

6

没有实际的数据,一个有根据的猜测是大数组DumpSave很快的原因是因为它是一个所谓的“打包数组”,也就是一个机器大小的浮点数的数组,它有一个在Mathematica中非常高效的表示形式。您的downsample函数(由于使用了Table)不会返回一个打包阵列,这个阵列在内存上要大得多,可能会比下采样4X后的阵列还要大。 ByteCount可能是说明性的。

您可以使用PackedArrayQ检查packed-array-ness,并尝试打包一个包含ToPackedArray的解包数组,这两个数组均位于Developer上下文中。

有两种解决方案,如果我的猜测是正确的。一种是使用ToPackedArray如图所示:

downsample[image_, f_] := Module[{w, h}, h = Dimensions[image][[1]]; 
    w = Dimensions[image][[2]]; 
    Developer`[email protected][image[[i, j]], {i, 1, h, f}, {j, 1, w, f}]] 

更妙的是简单地与Take更换您的Table使用,应在这种情况下返回压缩数组,并作为额外的奖励是一个很大的速度比使用Table

downsample[image_, f_] := Take[image, {1,-1,f}, {1,-1,f}] 

您可能也有兴趣在所有的新image processing functionality Mathematica中7

希望帮助!

+0

哇,很好的答案!有兴趣听到这是否解决了提问者的问题。 – dreeves 2010-08-25 18:21:23

相关问题