2015-10-29 2 views
2

Чтобы упростить, у меня есть набор снимков, снятых с камеры. Эта камера была за акриловым куполом, и на этом куполе есть царапины. На снимках очень заметны царапины. С opencv, я пытаюсь обнаружить и удалить эти царапины. Мой первый подход состоит в том, чтобы размножить подмножество изображений для создания маски, чем применить маску inpaint. Я на правильном пути? Есть ли способ лечения, который я могу сделать на изображениях перед их умножением?Обнаружение (и удаление) царапин из набора фотографий

enter image description here enter image description here enter image description here enter image description here

EDIT: Вот изображение подсветки царапины enter image description here

+1

Не могли бы вы привести несколько примеров изображений? – Miki

+0

@Miki Изображения добавлены! – Goldorak84

+0

Средний фильтр может быть эффективным на тонких царапинах. – ChronoTrigger

ответ

2

После нескольких тестов я пришел с надежным способом устранения повторяющихся царапин и пыли пятна на набор изображений. Сначала я возьму подмножество от 10 до 15 изображений, откройте их и примените sobel derivatives, чтобы извлечь контуры.

 private Image<Gray, byte> GetImageContours(String strImage) 
     { 
      Image<Gray, Byte> img = new Image<Gray, byte>(strImage); 
      Image<Gray, float> gradx = img.Sobel(1, 0, 5); 
      Image<Gray, Byte> gradxconv = gradx.ConvertScale<Byte>(1, 0); 
      Image<Gray, float> grady = img.Sobel(0, 1, 5); 
      Image<Gray, Byte> gradyconv = grady.ConvertScale<Byte>(1, 0); 
      Image<Gray, Byte> imgContours = gradxconv.AddWeighted(gradyconv, 0.5, 0.5, 0); 

      img.Dispose(); 
      gradx.Dispose(); 
      grady.Dispose(); 
      gradxconv.Dispose(); 
      gradyconv.Dispose(); 

      return imgContours; 
     } 

Затем я преобразую изображения обратно в глубину 16 бит, а затем умножаю их все. Это должно дать мне изображение только царапин. Чтобы создать маску скрестов, я разоблачаю это изображение один раз, а затем расширяю его 10 раз. После этого я преобразую его в черно-белый, запустив TresholdBinary с значением treshold 40.

Последним шагом является использование функции Inpaint на всех наборах изображений с помощью маски с нуля.

  Image<Gray, float> _img1 = img1.Convert<Gray, float>(); 
      Image<Gray, float> _img2 = img2.Convert<Gray, float>(); 
      Image<Gray, float> _img3 = img3.Convert<Gray, float>(); 
      Image<Gray, float> _img4 = img4.Convert<Gray, float>(); 
      Image<Gray, float> _img5 = img5.Convert<Gray, float>(); 
      Image<Gray, float> _img6 = img6.Convert<Gray, float>(); 
      Image<Gray, float> _img7 = img7.Convert<Gray, float>(); 
      Image<Gray, float> _img8 = img8.Convert<Gray, float>(); 
      Image<Gray, float> _img9 = img9.Convert<Gray, float>(); 
      Image<Gray, float> _img10 = img10.Convert<Gray, float>(); 
      Image<Gray, float> _img11 = img11.Convert<Gray, float>(); 
      Image<Gray, float> _img12 = img12.Convert<Gray, float>(); 
      Image<Gray, float> imgMask = _img1.Mul(_img2).Mul(_img3).Mul(_img4).Mul(_img5).Mul(_img6).Mul(_img7).Mul(_img8).Mul(_img9).Mul(_img10).Mul(_img11).Mul(_img12).Erode(1); 
      Image<Gray, Byte> imgMask2 = imgMask.Convert<Gray, Byte>(); 
      Image<Gray, Byte> imgMask3 = imgMask2.Dilate(10).ThresholdBinary(new Gray(40), new Gray(255)); 

      //img is one of the original images to remove scratches on 
      ImageViewer viewer3 = new ImageViewer(img.InPaint(imgMask3, 3), "image3"); 
      viewer3.Show(); 

Здесь приведены примеры снимков, сделанных на каждом шаге:

оригинальное изображение enter image description here

контуры этого изображения enter image description here

все контуры умноженной enter image description here

М запроси эрозии и расширенные enter image description here

конечный результат enter image description here

Смежные вопросы