首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >检测图像问题

检测图像问题
EN

Stack Overflow用户
提问于 2020-05-25 13:52:51
回答 2查看 281关注 0票数 2

我真的不知道它是什么(失真或其他东西),但我想通过使用emgucv (或opencv)来检测一些不同类型的图像的镜头照相机问题。

请提供任何关于使用哪种算法的意见。

第二个图像似乎有很高的噪音,但是有什么方法可以通过opencv来理解高噪音吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-05-31 12:55:27

如果没有参考数据或同质样本,这是很难实现的。但是,我提出了一种分析图像平均信噪比(信号到噪声比)的建议。该算法根据指定的核大小将输入图像划分为一定数目的“子图像”,以独立地评估每个子图像的局部信噪比,然后对每个子图像的计算信噪比进行平均处理,得到图像全局信噪比的指示

您将需要对此方法进行详尽的测试,但是它在以下三个映像上显示了希望,即生成AvgSNR

图像#1 - AvgSNR = 0.9

图像#2 - AvgSNR = 7.0

图像#3 - AvgSNR = 0.6

注意:查看“干净”控件映像是如何生成一个更高的 AvgSNR的。

唯一要考虑的变量是内核大小。我建议保持在一个大小,将支持甚至最小的潜在输入图像。对于许多图像来说,30像素的方格可能是合适的。

我随信附上我的测试代码和注释:

代码语言:javascript
运行
复制
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 * heightSubDivisions;
        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;
    }
}

注意:没有参考,就不可能区分自然方差/保真度和“噪声”。例如,一个高纹理背景,或者一个几乎没有均匀区域的场景将产生一个高AvgSNR。当评估场景主要由普通的、单色的表面(如服务器室或商店前)组成时,这种方法效果最好。例如,草会包含大量的纹理,因此“噪音”。

票数 2
EN

Stack Overflow用户

发布于 2020-05-31 13:16:09

另一种方法是考虑在傅里叶变换后的频域中对图像进行评估。您提供的噪声示例主要是包含不想要的、高频内容的图像。对违反高频阈值的图像进行FFT和评估。在这里,您将从一个使用Emgu:带Emgu的FFT的快速傅立叶变换示例中学习。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62003846

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档