F# 延迟像素读取

F# 延迟像素读取,f#,pixel,lazy-evaluation,F#,Pixel,Lazy Evaluation,我想将图像像素延迟加载到三维整数数组中。 例如,简单地说,它是这样的: for i=0 to Width for j=0 to Height let point=image.GetPixel(i,j) pixels.[0,i,j] <- point.R pixels.[1,i,j] <- point.G pixels.[2,i,j] <- point.B for i=0 to Width for

我想将图像像素延迟加载到三维整数数组中。 例如,简单地说,它是这样的:

   for i=0 to Width 
     for j=0 to Height
       let point=image.GetPixel(i,j)
       pixels.[0,i,j] <- point.R
       pixels.[1,i,j] <- point.G
       pixels.[2,i,j] <- point.B
for i=0 to Width 
  for j=0 to Height 
    let point = lazy image.GetPixel(i,j) 
    pixels.[0,i,j] <- lazy point.Value.R 
    pixels.[1,i,j] <- lazy point.Value.G 
    pixels.[2,i,j] <- lazy point.Value.B
open System.Drawing

let lazyPixels (image:Bitmap) =
    let Width = image.Width
    let Height = image.Height
    let pixels : Lazy<byte>[,,] = Array3D.zeroCreate 3 Width Height
    for i = 0 to Width-1 do
        for j = 0 to Height-1 do
            let point = lazy image.GetPixel(i,j)
            pixels.[0,i,j] <- lazy point.Value.R
            pixels.[1,i,j] <- lazy point.Value.G
            pixels.[2,i,j] <- lazy point.Value.B
    pixels

如何用懒惰的方式来做呢?

你说的懒惰是什么意思

数组不是惰性数据类型,这意味着如果要使用数组,需要在初始化期间加载所有像素。如果我们使用一维数组,另一种选择是使用seq,它是惰性的,但您只能按顺序访问元素。对于多维数组,没有什么能像seq那样,所以您需要使用其他东西

可能最接近的选择是使用三维惰性值数组lazy[,]。这是一个访问像素的延迟thunk数组,仅当您实际读取该位置的值时才进行计算。您可以这样初始化它:

   for i=0 to Width 
     for j=0 to Height
       let point=image.GetPixel(i,j)
       pixels.[0,i,j] <- point.R
       pixels.[1,i,j] <- point.G
       pixels.[2,i,j] <- point.B
for i=0 to Width 
  for j=0 to Height 
    let point = lazy image.GetPixel(i,j) 
    pixels.[0,i,j] <- lazy point.Value.R 
    pixels.[1,i,j] <- lazy point.Value.G 
    pixels.[2,i,j] <- lazy point.Value.B
open System.Drawing

let lazyPixels (image:Bitmap) =
    let Width = image.Width
    let Height = image.Height
    let pixels : Lazy<byte>[,,] = Array3D.zeroCreate 3 Width Height
    for i = 0 to Width-1 do
        for j = 0 to Height-1 do
            let point = lazy image.GetPixel(i,j)
            pixels.[0,i,j] <- lazy point.Value.R
            pixels.[1,i,j] <- lazy point.Value.G
            pixels.[2,i,j] <- lazy point.Value.B
    pixels
该代码段创建一个延迟值,读取像素点,然后创建三个延迟值以获取各个颜色组件。访问颜色组件时,点值通过访问值进行计算

代码其余部分的唯一区别是需要调用Value,例如pixels。[0,10,10]。Value以获取像素的实际颜色分量


您可以定义更复杂的数据结构,例如您自己的类型,它支持索引并且是惰性的,但是我认为惰性值数组应该是一个很好的起点。

缓慢的是调用GetPixel。如果您只想在需要时调用它,可以使用如下内容:

   for i=0 to Width 
     for j=0 to Height
       let point=image.GetPixel(i,j)
       pixels.[0,i,j] <- point.R
       pixels.[1,i,j] <- point.G
       pixels.[2,i,j] <- point.B
for i=0 to Width 
  for j=0 to Height 
    let point = lazy image.GetPixel(i,j) 
    pixels.[0,i,j] <- lazy point.Value.R 
    pixels.[1,i,j] <- lazy point.Value.G 
    pixels.[2,i,j] <- lazy point.Value.B
open System.Drawing

let lazyPixels (image:Bitmap) =
    let Width = image.Width
    let Height = image.Height
    let pixels : Lazy<byte>[,,] = Array3D.zeroCreate 3 Width Height
    for i = 0 to Width-1 do
        for j = 0 to Height-1 do
            let point = lazy image.GetPixel(i,j)
            pixels.[0,i,j] <- lazy point.Value.R
            pixels.[1,i,j] <- lazy point.Value.G
            pixels.[2,i,j] <- lazy point.Value.B
    pixels

上的C示例中采用,正如其他评论中已经提到的,您可以在3D数组中使用延迟像素加载,但这只会使GetPixel操作延迟,而不是3D数组的内存分配,因为在调用Array3D的创建方法时,数组已经分配

如果要使内存分配和GetPixel变为惰性,则可以使用如下代码所示的序列:

let getPixels (bmp:Bitmap) =
  seq {
        for i = 0 to bmp.Height-1 do
            yield seq {
                            for j = 0 to bmp.Width-1 do
                                let pixel = bmp.GetPixel(j,i)
                                yield (pixel.R,pixel.G,pixel.B)
                       }
  }

感谢您提供有关如何使用锁定位的示例。在创建3d阵列的最后一行中,您在做什么?这对我不起作用。@Gos-Doh。我返回的是索引,而不是值。现在修好了。