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

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

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

Я не совсем понимаю 2 вещи об этом,

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

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

2. Почему центральный ряд в 2 раза больше других рядов?

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


person Alcott    schedule 13.06.2013    source источник


Ответы (3)


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

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

[-1 1]

Несмотря на свою простоту, у этого оператора есть первая проблема: при его использовании вы вычисляете градиент между двумя позициями, а не в одной позиции. Если вы примените его к 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]

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

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

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

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

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

person mbrenon    schedule 13.06.2013
comment
Только ваше воображение является пределом для создания новых, если оно соответствует вашим потребностям... - +1. - person rayryeng; 20.02.2015

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

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

Во-первых, в компьютерном зрении подход «Чаще всего мы просто пробуем оператора» просто тратит время и дает плохие результаты по сравнению с тем, что могло бы быть достигнуто. (Тем не менее, я тоже люблю экспериментировать.)

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

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

[1]            [-1 0 1]
[2]*[-1 0 1] = [-2 0 2]
[1]            [-1 0 1]
person Bull    schedule 13.06.2013

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

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

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

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

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

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

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

[  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 дает исходный фильтр Собеля.

person staonas    schedule 27.02.2014