Реализация фильтра Собеля на Scala

Я ищу помощь в проекте ИТ-школы. Нам нужно создать программу, которая может распознавать дороги на спутниковом снимке. Наша группа решила использовать функцию для обнаружения ребер. Мы ищем различные решения и фильтры в Интернете, и мы решаем использовать фильтр Собеля.

Мы пытались реализовать этот фильтр в Scala, но это не сработало. Мы используем разные веб-страницы, чтобы помочь нам, некоторые из них находятся на StackOverflow (здесь). Мы используем это, чтобы помочь нам и попытаться перевести код: Фильтр Собеля в 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 --

Изображение, возвращаемое этой реализацией, представляет собой просто изображение с черно-белыми пикселями, и я не знаю, почему. У меня нет опыта в обработке изображений, и мы изучили Scala 8 недель назад, так что это не помогает. Извините, мой английский не идеален, поэтому, пожалуйста, простите меня, если я не правильно написал.


person Guillaume Koenig    schedule 21.11.2015    source источник
comment
Какого результата вы ожидаете? В одном из примеров, которые вы связали с вопросом, вывод приложения оператора Sobel также состоит из черных и белых пикселей.   -  person tkroman    schedule 22.11.2015
comment
Результатом, который мы ожидаем, было новое изображение с краями. Исходное изображение: koenigguillaume.me/6.jpg Результат: koenigguillaume.me/outputImage.jpg Но результат не очень хороший, у меня нет краев на этом новом изображении, как здесь: stackoverflow.com/questions/17815687/.   -  person Guillaume Koenig    schedule 22.11.2015


Ответы (1)


Я не уверен, что понимаю все детали вашего решения, в любом случае вот некоторые наблюдения:

  1. подумайте об использовании val вместо var: Scala предпочитает неизменяемые, и вы на самом деле не меняете ни одну из этих переменных.
  2. В scala вы можете писать вложенные циклы как одну над двумя переменными (подробнее см. здесь: Вложенная итерация в Скала). Я думаю, что это делает код чище.
  3. Я предполагаю, что image2D — это массив массивов, в котором вы держите свое изображение. В последней строке вашего вложенного цикла for вы меняете текущее значение пикселя. Это нехорошо, потому что вы получите доступ к тому же пикселю позже, когда будете вычислять значения a, b,.., h, i. Центральный пиксель во время текущей итерации является боковым пикселем во время следующей итерации. Я думаю, вам следует записать результат в другую матрицу.
person Chosmos    schedule 22.11.2015
comment
Спасибо Хомос. Я создал новое прозрачное изображение с той же высотой и шириной, и оно работает! Для замены моих варов я предпочитаю подождать, потому что проект еще не завершен, но я держу это в уме. - person Guillaume Koenig; 24.11.2015