Почему оператор Sobel выглядит так?

для вычисления производной изображения оператор Собеля выглядит следующим образом:

[-1 0 1]
[-2 0 2]
[-1 0 1]

Я не совсем понял 2 вещи об этом!--3-->

1.Почему Центральный пиксель 0? Не могу ли я просто использовать оператор, как показано ниже,

[-1 1]
[-1 1]
[-1 1]

2.Почему Центральная строка в 2 раза больше остальных строк?

я погуглил свои вопросы, не нашел ответа, который может убедить меня. Пожалуйста, помогите мне.

3 ответов


в компьютерном зрении очень часто нет идеального, универсального способа что-то сделать. Чаще всего мы просто пробуем оператора, видим его результаты и проверяем, соответствуют ли они нашим потребностям. Это верно и для вычисления градиента: оператор Собеля является одним из многих способов вычисления градиента изображения, который доказал свою полезность во многих случаях.

на самом деле, более простой оператор градиента, который мы могли бы придумать, еще проще, чем тот, который вы предлагаете сверху:

[-1 1]

несмотря на свою простоту, у этого оператора есть первая проблема: когда вы его используете, вы вычисляете градиент между две позиции, а не at одну позицию. Если вы примените его к 2 пикселям (x,y) и (x+1,y), вы вычислили градиент в позиции (x,y) или (x+1,y)? В том, что вы вычислили это градиент на должность (x+0.5,y), и работать с половиной пикселей не очень удобно. Вот почему мы добавляем ноль в середина:

[-1 0 1]

применение этого к пикселям (x-1,y), (x,y) и (x+1,y) ясно даст вам градиент для центрального пикселя (x,y).

это также можно рассматривать как свертку двух [-1 1] фильтры: [-1 1 0] это вычисляет градиент в позиции (x-0.5,y), слева от пикселя, и [0 -1 1] это вычисляет градиент справа от пикселя.

теперь этот фильтр все еще имеет другой недостаток: он очень чувствителен к шум. Вот почему мы решили не применять его на одной строке пикселей, а на 3 строках: это позволяет получить средний градиент на этих 3 строках, что смягчит возможный шум:

[-1 0 1]
[-1 0 1]
[-1 0 1]

но это имеет тенденцию усреднять вещи немного слишком много: при применении к одной конкретной строке мы теряем многое из того, что делает деталь этой конкретной строки. Чтобы исправить это, мы хотим дать немного больше веса в центре строки, что позволит нам избавиться от возможного шума с учетом что происходит в предыдущей и следующей строках, но все же сохраняя специфику этой самой строки. Вот что дает фильтр Sobel:

[-1 0 1]
[-2 0 2]
[-1 0 1]

изменение коэффициентов может привести к другим операторам градиента, таким как оператор Шарра, который дает немного вес к центральному ряду:

[-3  0 3 ]
[-10 0 10]
[-3  0 3 ]

есть также математические причины для этого, такие как делимость из этих фильтров... но я предпочитаю видеть это как экспериментальное открытие, которое оказалось интересным математическим свойством, так как эксперимент, на мой взгляд, лежит в основе компьютерного зрения. Только ваше воображение является пределом для создания новых, пока оно соответствует вашим потребностям...


редактировать истинная причина, по которой оператор Sobel выглядит так, может быть найдено путем чтения интересная статья самого Собеля. Мой быстрое чтение этой статьи указывает на идею Собел был получить улучшенная оценка градиента путем усреднения по горизонтали, вертикальные и диагональные центральные различия. Теперь, когда ты сломал ... градиент в вертикальные и горизонтальные компоненты, диагональный центральный различия в обеих, пока вертикальный и горизонтальный центральные различия включены только в одно. Два избежать двойной таким образом, подсчет диагоналей должен иметь половину веса вертикальный и горизонтальный. Фактические веса 1 и 2 просто удобно для арифметики с фиксированной точкой (и фактически включает шкалу коэффициент 16).

Я согласен с @mbrenon в основном, но есть пара моментов, которые слишком сложно сделать в комментарии.

во первых в компьютерном зрении, " большинство часто мы просто пробуем подход оператора " просто тратит время и дает плохие результаты по сравнению с тем, что могло бы быть достигнуто. (Тем не менее, я тоже люблю экспериментировать.)

это правда, что хороший повод использовать [-1 0 1] это центры производная смета на пиксель. Но другая веская причина в том, что это центральный разницу формула, и вы можете доказать математически, что он дает ниже ошибка в его оценить истинного дериват чем [-1 1].

[1 2 1] используется для фильтрации шума, как mbrenon, сказал. Почему именно эти цифры хорошо работают, что их приближение Гаусса, который является только фильтр, который не вводит артефакты (хотя из статьи Собеля это кажется совпадением). Теперь, если вы хотите уменьшить шум, и вы находите горизонтальную производную, которую вы хотите фильтровать в вертикальном направлении, чтобы наименее повлиять на оценку деривата. Свертки transpose([1 2 1]) С [-1 0 1] мы получаем оператор Sobel. т. е.:

[1]            [-1 0 1]
[2]*[-1 0 1] = [-2 0 2]
[1]            [-1 0 1]

для 2D изображения вам нужна маска. Скажем, эта маска:

[ a11 a12 a13; 
  a21 a22 a23;
  a31 a32 a33 ]

Df_x (градиент вдоль x) должен быть получен из Df_y (градиент вдоль y) вращением 90o, т. е. маска должна быть:

[ a11 a12 a11; 
  a21 a22 a21;
  a31 a32 a31 ]

теперь, если мы хотим вычесть сигнал перед средним пикселом (вот что такое дифференцирование в дискретном вычитании) , мы хотим выделить одинаковые веса для обеих сторон вычитания, т. е. наша маска становится:

[  a11 a12 a11; 
   a21 a22 a21;
  -a11 -a12 -a11 ]

далее, сумма веса должно быть ноль, потому что когда у нас есть гладкое изображение (например, все 255s), мы хотим иметь нулевой ответ, т. е. мы получаем:

[  a11 a12 a11; 
   a21 -2a21 a21;
  -a31 -a12 -a31 ]

в случае гладкого изображения мы ожидаем, что дифференцирование вдоль оси X приведет к нулю, т. е.:

[  a11 a12 a11; 
   0 0 0;
  -a31 -a12 -a31 ]

наконец, если мы нормализуем мы получаем:

[  1 A 1; 
   0 0 0;
  -1 -A -1 ]

и вы можете установить A на все, что хотите экспериментально. Коэффициент 2 дает оригинальный фильтр Собеля.