I82*_*uch 9 functional-programming scala
我正在尝试计算Scala中图像的平均颜色,其中"average"被定义为redSum/numpixels,greenSum/numpixels,blueSum/numpixels.
这是我用来计算图像矩形区域(Raster)中的平均颜色的代码.
// A raster is an abstraction of a piece of an image and the underlying
// pixel data.
// For instance, we can get a raster than is of the upper left twenty
// pixel square of an image
def calculateColorFromRaster(raster:Raster): Color = {
var redSum = 0
var greenSum = 0
var blueSum = 0
val minX = raster.getMinX()
val minY = raster.getMinY()
val height = raster.getHeight()
val width = raster.getWidth()
val numPixels = height * width
val numChannels = raster.getNumBands()
val pixelBuffer = new Array[Int](width*height*numChannels)
val pixels = raster.getPixels(minX,minY,width,height,pixelBuffer)
// pixelBuffer now filled with r1,g1,b1,r2,g2,b2,...
// If there's an alpha channel, it will be r1,g1,b1,a1,r2,... but we skip the alpha
for (i <- 0 until numPixels) {
val redOffset = numChannels * i
val red = pixels(redOffset)
val green = pixels(redOffset+1)
val blue = pixels(redOffset+2)
redSum+=red
greenSum+=green
blueSum+=blue
}
new Color(redSum / numPixels, greenSum / numPixels, blueSum / numPixels)
}
Run Code Online (Sandbox Code Playgroud)
是否有更惯用的Scala方法总结不同的交错数组?某种方法可以在数组上进行投影,迭代每个第4个元素?我对Stack Overflow社区可以提供的任何专业知识感兴趣.
Ale*_*nov 10
pixels.grouped(3)
将返回一个Iterator[Array[Int]]
3元素数组.所以
val pixelRGBs = pixels.grouped(3)
val (redSum, greenSum, blueSum) =
pixelRGBs.foldLeft((0, 0, 0)) {case ((rSum, gSum, bSum), Array(r, g, b)) => (rSum + r, gSum + g, bSum + b)}
new Color(redSum / numPixels, greenSum / numPixels, blueSum / numPixels)
Run Code Online (Sandbox Code Playgroud)
更新:要处理3和4通道,我会写
pixels.grouped(numChannels).foldLeft((0, 0, 0)) {case ((rSum, gSum, bSum), Array(r, g, b, _*)) => (rSum + r, gSum + g, bSum + b)}
Run Code Online (Sandbox Code Playgroud)
_*
这里基本上是指"0或更多元素".请参阅http://programming-scala.labs.oreilly.com/ch03.html中的 "序列匹配"
对于这个问题,这是疯狂的过度杀伤,但是我对数据集进行了大量的分区缩减,并为它构建了一些实用功能.其中最常见的是reduceBy,它采用集合(实际上是Traversable),分区函数,映射函数和简化函数,并生成从分区到缩减/映射值的映射.
def reduceBy[A, B, C](t: Traversable[A], f: A => B, g: A => C, reducer: (C, C) => C): Map[B, C] = {
def reduceInto(map: Map[B, C], key: B, value: C): Map[B, C] =
if (map.contains(key)) {
map + (key -> reducer(map(key), value))
}
else {
map + (key -> value)
}
t.foldLeft(Map.empty[B, C])((m, x) => reduceInto(m, f(x), g(x)))
}
Run Code Online (Sandbox Code Playgroud)
鉴于重型机械,你的问题就变成了
val sumByColor:Map[Int, Int] = reduceBy(1 until numPixels, (i => i%numChannels), (i=>pixel(i)), (_+_))
return Color(sumByColor(0)/numPixels, sumByColor(1)/numPixels, sumByColor(2)/numPixels)
Run Code Online (Sandbox Code Playgroud)
在高阶编程的强大功能之前静音.
归档时间: |
|
查看次数: |
679 次 |
最近记录: |