检测图像问题

Detect Image Problems

真不知道叫什么(失真什么的) 但我想通过使用 emgucv(或 opencv)检测某些不同类型图像的镜头相机问题

任何关于使用哪种算法的想法都将不胜感激

第二张图好像有高噪点,请问有什么方法可以通过opencv理解高噪点吗?

如果没有参考数据或同质性样本,这通常很难实现。但是,我提出了一个分析图像平均信噪比 (Signal to Noise) 比率的建议。该算法根据指定的内核大小将输入图像划分为指定数量的“子图像”,以便独立评估每个子图像的局部 SNR。然后对每个子图像计算的 SNR 进行平均,以提供 图像全局信噪比指标

您将需要详尽地测试此方法,但它在以下三张图片上显示出前景,生成 AvgSNR

图像 #1 - 平均 SNR = 0.9

图像 #2 - 平均 SNR = 7.0

图像 #3 - 平均 SNR = 0.6

注意: 查看 "clean" 控制图像如何产生 更高 AvgSNR.

唯一要考虑的变量是内核大小。我建议将其保持在能够支持最小的潜在输入图像的大小。 30 像素正方形应该适合许多图像。

我用注释附上我的测试代码:

class Program
{
    static void Main(string[] args)
    {
        // List of file names to load.
        List<string> fileNames = new List<string>()
        {
            "IifXZ.png",
            "o1z7p.jpg",
            "NdQtj.jpg"
        };

        // For each image
        foreach (string fileName in fileNames)
        {
            // Determine local file path
            string path = Path.Combine(Environment.CurrentDirectory, @"TestImages\", fileName);
            // Load the image
            Image<Bgr, byte> inputImage = new Image<Bgr, byte>(path);

            // Compute the AvgSNR with a kernel of 30x30
            Console.WriteLine(ComputeAverageSNR(30, inputImage.Convert<Gray, byte>()));

            // Display the image
            CvInvoke.NamedWindow("Test");
            CvInvoke.Imshow("Test", inputImage);
            while (CvInvoke.WaitKey() != 27) { }
        }

        // Pause for evaluation
        Console.ReadKey();
    }

    static double ComputeAverageSNR(int kernelSize, Image<Gray, byte> image)
    {
        // Calculate the number of sub-divisions given the kernel size
        int widthSubDivisions, heightSubDivisions;
        widthSubDivisions = (int)Math.Floor((double)image.Width / kernelSize);
        heightSubDivisions = (int)Math.Floor((double)image.Height / kernelSize);
        int totalNumberSubDivisions = widthSubDivisions * widthSubDivisions;
        Rectangle ROI = new Rectangle(0, 0, kernelSize, kernelSize);

        double avgSNR = 0;
        // Foreach sub-divions, calculate the SNR and sum to the avgSNR
        for (int v = 0; v < heightSubDivisions; v++)
        {
            for (int u = 0; u < widthSubDivisions; u++)
            {
                // Iterate the sub-division position
                ROI.Location = new Point(u * kernelSize, v * kernelSize);
                // Calculate the SNR of this sub-division
                avgSNR += ComputeSNR(image.GetSubRect(ROI));
            }
        }

        avgSNR /= totalNumberSubDivisions;

        return avgSNR;
    }

    static double ComputeSNR(Image<Gray, byte> image)
    {
        // Local varibles
        double mean, sigma, snr;

        // Calculate the mean pixel value for the sub-division
        int population = image.Width * image.Height;
        mean = CvInvoke.Sum(image).V0 / population;

        // Calculate the Sigma of the sub-division population
        double sumDeltaSqu = 0;
        for (int v = 0; v < image.Height; v++)
        {
            for (int u = 0; u < image.Width; u++)
            {
                sumDeltaSqu += Math.Pow(image.Data[v, u, 0] - mean, 2);
            }
        }
        sumDeltaSqu /= population;
        sigma = Math.Pow(sumDeltaSqu, 0.5);

        // Calculate and return the SNR value
        snr = sigma == 0 ? mean : mean / sigma;
        return snr;
    }
}

注意: 没有引用,无法区分自然 variance/fidelity 和 "noise"。例如,一个高度纹理化的背景,或者一个几乎没有同质区域的场景会产生很高的 AvgSNR。当评估的场景主要由普通的单色表面(例如服务器机房或店面)组成时,此方法的效果最佳。例如,草会包含大量纹理,因此 "noise"。

另一种方法是考虑在傅立叶变换后的频域中评估图像。原则上,您提供的噪声示例是包含不需要的高频内容的图像。执行 FFT 并评估违反高频阈值的图像。在这里,您将从 Emgu 的 FFT 示例中获得:FFT with Emgu