sobel过滤器的Scala实现
Scala implementation of sobel filter
我正在 IT 学校项目中寻求帮助。我们需要创建一个程序来检测卫星照片中的道路。我们小组决定使用一个函数来检测边缘。我们在 Internet 上搜索了不同的解决方案和过滤器,我们决定使用 Sobel 过滤器。
我们已尝试在 Scala 中实现此过滤器,但没有成功。我们使用不同的网页来帮助我们,其中一些在 Whosebug 上 (here). We use this one to help us and try to translate the code : Sobel filter in Ruby.
Start Code --
codeGrey(); // This function transform the RGB in grey level
var sobel_x: Array[Array[Double]] = Array(
Array(-1, 0, 1),
Array(-2, 0, 2),
Array(-1, 0, 1))
var sobel_y: Array[Array[Double]] = Array(
Array(1, 2, 1),
Array(0, 0, 0),
Array(-1, -2, 1))
for (x <- 1 to wrappedImage.height - 2) {
for (y <- 1 to wrappedImage.width - 2) {
var a = (image2D(x - 1)(y - 1) & 0x00FF0000) >> 16
var b = (image2D(x)(y - 1) & 0x00FF0000) >> 16
var c = (image2D(x + 1)(y - 1) & 0x00FF0000) >> 16
var d = (image2D(x - 1)(y) & 0x00FF0000) >> 16
var e = (image2D(x)(y) & 0x00FF0000) >> 16
var f = (image2D(x + 1)(y) & 0x00FF0000) >> 16
var g = (image2D(x - 1)(y + 1) & 0x00FF0000) >> 16
var h = (image2D(x)(y + 1) & 0x00FF0000) >> 16
var i = (image2D(x + 1)(y + 1) & 0x00FF0000) >> 16
var pixel_x =
(sobel_x(0)(0) * a) + (sobel_x(0)(1) * b) + (sobel_x(0)(2) * c) +
(sobel_x(1)(0) * d) + (sobel_x(1)(1) * e) + (sobel_x(1)(2) * f) +
(sobel_x(2)(0) * g) + (sobel_x(2)(1) * h) + (sobel_x(2)(2) * i);
var pixel_y =
(sobel_y(0)(0) * a) + (sobel_x(0)(1) * b) + (sobel_x(0)(2) * c) +
(sobel_y(1)(0) * d) + (sobel_x(1)(1) * e) + (sobel_x(1)(2) * f) +
(sobel_y(2)(0) * g) + (sobel_x(2)(1) * h) + (sobel_x(2)(2) * i);
var res = (Math.sqrt((pixel_x * pixel_x) + (pixel_y * pixel_y)).ceil).toInt
image2D(x)(y) = 0xFF000000 + (res * 65536 + res * 256 + res);
}
}
End Code --
此实现返回的图像只是黑白像素图像,我不知道为什么。我没有图像处理方面的经验,我们在 8 周前学习了 Scala,所以这无济于事。
对不起,我的英语不是很好,如果我写得不正确,请原谅我。
我不确定我掌握了你解决方案的所有细节,总之这里有一些观察:
- 考虑使用 vals 而不是 vars:Scala 更喜欢
不可变的,你并没有真正改变任何这些变量。
- 在 Scala 中,您可以将嵌套的 for 循环编写为一个超过两个的循环
变量(查看此处了解详细信息:
Nested iteration in Scala)。我认为它使代码更清晰。
- 我假设 image2D 是你所在的数组数组
抱着你的形象。在你嵌套的 for 循环的最后一行
改变当前像素值。这不好,因为你会
稍后在计算 a,b,..,h,i 时访问相同的像素
值。当前迭代期间的中心像素是侧面像素
在下一次迭代中。我认为你应该把结果写在
不同的矩阵。
我正在 IT 学校项目中寻求帮助。我们需要创建一个程序来检测卫星照片中的道路。我们小组决定使用一个函数来检测边缘。我们在 Internet 上搜索了不同的解决方案和过滤器,我们决定使用 Sobel 过滤器。
我们已尝试在 Scala 中实现此过滤器,但没有成功。我们使用不同的网页来帮助我们,其中一些在 Whosebug 上 (here). We use this one to help us and try to translate the code : Sobel filter in Ruby.
Start Code --
codeGrey(); // This function transform the RGB in grey level
var sobel_x: Array[Array[Double]] = Array(
Array(-1, 0, 1),
Array(-2, 0, 2),
Array(-1, 0, 1))
var sobel_y: Array[Array[Double]] = Array(
Array(1, 2, 1),
Array(0, 0, 0),
Array(-1, -2, 1))
for (x <- 1 to wrappedImage.height - 2) {
for (y <- 1 to wrappedImage.width - 2) {
var a = (image2D(x - 1)(y - 1) & 0x00FF0000) >> 16
var b = (image2D(x)(y - 1) & 0x00FF0000) >> 16
var c = (image2D(x + 1)(y - 1) & 0x00FF0000) >> 16
var d = (image2D(x - 1)(y) & 0x00FF0000) >> 16
var e = (image2D(x)(y) & 0x00FF0000) >> 16
var f = (image2D(x + 1)(y) & 0x00FF0000) >> 16
var g = (image2D(x - 1)(y + 1) & 0x00FF0000) >> 16
var h = (image2D(x)(y + 1) & 0x00FF0000) >> 16
var i = (image2D(x + 1)(y + 1) & 0x00FF0000) >> 16
var pixel_x =
(sobel_x(0)(0) * a) + (sobel_x(0)(1) * b) + (sobel_x(0)(2) * c) +
(sobel_x(1)(0) * d) + (sobel_x(1)(1) * e) + (sobel_x(1)(2) * f) +
(sobel_x(2)(0) * g) + (sobel_x(2)(1) * h) + (sobel_x(2)(2) * i);
var pixel_y =
(sobel_y(0)(0) * a) + (sobel_x(0)(1) * b) + (sobel_x(0)(2) * c) +
(sobel_y(1)(0) * d) + (sobel_x(1)(1) * e) + (sobel_x(1)(2) * f) +
(sobel_y(2)(0) * g) + (sobel_x(2)(1) * h) + (sobel_x(2)(2) * i);
var res = (Math.sqrt((pixel_x * pixel_x) + (pixel_y * pixel_y)).ceil).toInt
image2D(x)(y) = 0xFF000000 + (res * 65536 + res * 256 + res);
}
}
End Code --
此实现返回的图像只是黑白像素图像,我不知道为什么。我没有图像处理方面的经验,我们在 8 周前学习了 Scala,所以这无济于事。 对不起,我的英语不是很好,如果我写得不正确,请原谅我。
我不确定我掌握了你解决方案的所有细节,总之这里有一些观察:
- 考虑使用 vals 而不是 vars:Scala 更喜欢 不可变的,你并没有真正改变任何这些变量。
- 在 Scala 中,您可以将嵌套的 for 循环编写为一个超过两个的循环 变量(查看此处了解详细信息: Nested iteration in Scala)。我认为它使代码更清晰。
- 我假设 image2D 是你所在的数组数组 抱着你的形象。在你嵌套的 for 循环的最后一行 改变当前像素值。这不好,因为你会 稍后在计算 a,b,..,h,i 时访问相同的像素 值。当前迭代期间的中心像素是侧面像素 在下一次迭代中。我认为你应该把结果写在 不同的矩阵。