Вычитать изображения с помощью OpenCV - PullRequest
3 голосов
/ 07 сентября 2010

Я хочу вычесть два изображения. Моя проблема в том, что функция cvSub () насыщает. Что я хочу сделать, это:

1) Преобразование исходных изображений в оттенки серого.

2) Возьмите изображения в градациях серого (значения от 0 до 255).

3) Вычитать изображения (значения от -255 до 255) -> проблема масштабирования с помощью cvSub ().

4) Измените масштаб путем умножения на 0,5 и добавления 128.

Я думал о том, чтобы изменить полутоновые изображения с 8-битных на 16-битные, но потом все стало хуже, стало много строк кода, и в конце концов это не сработало.

Ответы [ 2 ]

5 голосов
/ 07 сентября 2010

Используя openCV, вы можете сделать следующее:

  • масштабирует оба исходных изображения (1 и 2) с коэффициентом 0,5. Оба изображения теперь находятся в диапазоне [0..127]
  • смещение изображения 1 на 128. Теперь оно находится в диапазоне [128..255]
  • вычесть изображение 2 из изображения 1

Таким образом, преобразование диапазона не требуется, и результат полностью масштабируется до 8 бит. Используйте cvConvertScale для первых двух операций.

Примерно так:

//...
cvConvertScale(src1, tmp1, 0.5, 128);
cvConvertScale(src2, tmp2, 0.5, 0);
cvSub(tmp1, tmp2, dst);

EDIT:

На ваш комментарий о потере информации (точности) вы правы, но вы всегда делаете это при делении с использованием целочисленной математики. И масштабирование в вашем случае это просто так. Просто думайте об этом как о смещении всех битов вправо на одно место. Таким образом, последний бит информации теряется.

С другой стороны, порядок применяемых операций также важен. Делив на 2, вы вводите ошибку округления (или усечения) 0.5 для каждого пикселя. Если вы масштабируете оба входных изображения до их вычитания, ошибка округления в сумме составляет 1.0. Это проявляется в результирующем изображении, когда некоторые пиксели смещены на 1 по сравнению с результатом, который вы получите при использовании исходного подхода и подхода Александера. Но это компромисс для более простого решения без расширения изображения до 16-битной или с плавающей запятой.

См. Этот пример:

действительные числа:
(200 - 101) / 2 = 99/2 = 49,5

Решение Александера (целочисленная математика):
(200 - 101) / 2 = 99/2 = 49

мое решение (целочисленная математика):
(200/2) - (101/2) = 100 - 50 = 50

1 голос
/ 07 сентября 2010

Вам нужно конвертировать из 8 бит в 16 бит.Затем добавьте 255 к первому изображению, затем вычтите из него второе изображение.Затем разделите на два и конвертируйте обратно в 8 бит.

Скажите, как это происходит, оно должно работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...