Image 从一组图片中检测(并删除)划痕

Image 从一组图片中检测(并删除)划痕,image,opencv,computer-vision,Image,Opencv,Computer Vision,为了简单起见,我有一组用相机拍摄的照片。这架相机在一个丙烯酸圆顶后面,圆顶上有划痕。这些划痕在照片上很明显。 使用opencv,我试图检测并删除这些划痕。 我的第一种方法是将图片的子集相乘以创建一个遮罩,而不是应用修复遮罩。我走对了吗?在相乘之前,我可以对图像进行处理吗 编辑: 这是一张突出显示划痕的图像经过几次测试,我找到了一种可靠的方法来消除一组图像上反复出现的划痕和灰尘斑点。首先,我拍摄10到15张图片的子集,打开它们,然后应用提取轮廓 private Image<

为了简单起见,我有一组用相机拍摄的照片。这架相机在一个丙烯酸圆顶后面,圆顶上有划痕。这些划痕在照片上很明显。 使用opencv,我试图检测并删除这些划痕。 我的第一种方法是将图片的子集相乘以创建一个遮罩,而不是应用修复遮罩。我走对了吗?在相乘之前,我可以对图像进行处理吗

编辑:
这是一张突出显示划痕的图像

经过几次测试,我找到了一种可靠的方法来消除一组图像上反复出现的划痕和灰尘斑点。首先,我拍摄10到15张图片的子集,打开它们,然后应用提取轮廓

        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;
        }
私有图像GetImageContours(字符串strImage)
{
图像img=新图像(strImage);
图像梯度x=img.Sobel(1,0,5);
图像gradxconv=gradx.ConvertScale(1,0);
图像梯度=img.Sobel(0,1,5);
图像灰度conv=grady.ConvertScale(1,0);
图像imgContours=gradxconv.AddWeighted(gradyconv,0.5,0);
img.Dispose();
gradx.Dispose();
grady.Dispose();
gradxconv.Dispose();
gradyconv.Dispose();
返回imgContours;
}
然后,我将图像转换回16位深度,然后将所有图像相乘。这应该只给我一个划痕的图像。 为了创造一个划痕的遮罩,我将这张图片腐蚀一次,然后放大10倍。之后,我通过运行treshold值为40的treshold二进制文件将其转换为黑白

最后一步是对所有带有划痕遮罩的图像集使用修复功能

            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();
Image\u img1=img1.Convert();
Image_img2=img2.Convert();
图像_img3=img3.Convert();
Image_img4=img4.Convert();
Image_img5=img5.Convert();
Image_img6=img6.Convert();
Image_img7=img7.Convert();
Image_img8=img8.Convert();
Image_img9=img9.Convert();
图像_img10=img10.Convert();
Image_img11=img11.Convert();
Image_img12=img12.Convert();
图像imgMask=\u img1.Mul(\u img2).Mul(\u img3).Mul(\u img4).Mul(\u img5).Mul(\u img6).Mul(\u img7).Mul(\u img8).Mul(\u img9).Mul(\u img10).Mul(\u img11).Mul(\u img12).侵蚀(1);
Image imgMask2=imgMask.Convert();
图像imgMask3=imgMask2.放大(10).阈值二进制(新灰度(40),新灰度(255));
//img是用于去除表面划痕的原始图像之一
ImageViewer viewer3=新的ImageViewer(img.InPaint(imgMask3,3),“image3”);
viewer3.Show();
以下是在每个步骤中拍摄的示例图像:

原始图像

这张照片的轮廓

所有的轮廓都增加了

面具被腐蚀和膨胀了

最终结果

您能提供一些示例图像吗?中值滤波器对薄划痕有效。您能在单独的图像中标记要去除的噪声/划痕吗?您的相机是否不可安装且划痕数量不变?我认为你应该通过从均匀的表面(即白纸或黑纸)拍摄一些帧来“校准”你的相机。正如前面提到的,在镜框上检测划痕比在管图像上容易得多。我同意Kornel的观点,如果可能的话,在玻璃顶部后面放一张白纸,那么检测划痕的位置就容易得多,你可以使用修复技术来移除它们。