Après quelques tests, je suis venu avec un moyen fiable pour éliminer les rayures récurrentes et les taches de poussière sur une ensemble d'images. Tout d'abord, je prends un sous-ensemble de 10 à 15 images, les ouvre, et applique sobel derivatives pour extraire les contours.
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;
}
Ensuite, je convertis les images à une profondeur de 16 bits, puis je les multiplie toutes. Cela devrait me donner une image des rayures seulement. Pour créer un masque des rayures, j'érode cette image une fois, puis je la dilate 10 fois. Après cela, je le convertis en noir et blanc en exécutant un TresholdBinary avec une valeur de seuil de 40.
La dernière étape consiste à utiliser la fonction Inpaint sur tout l'ensemble d'images avec le masque de travail.
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();
Voici des échantillons d'images prises à chaque étape:
image originale
contours de cette image
tous les contours multipliés
la m ask érodé et dilatée
le résultat final
Pouvez-vous fournir quelques images par exemple? – Miki
@Miki Images ajoutées! – Goldorak84
Un filtre médian peut être efficace sur les rayures minces. – ChronoTrigger