我真的不知道它是什么(失真或其他东西),但我想通过使用emgucv (或opencv)来检测一些不同类型的图像的镜头照相机问题。
请提供任何关于使用哪种算法的意见。

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

发布于 2020-05-31 12:55:27
如果没有参考数据或同质样本,这是很难实现的。但是,我提出了一种分析图像平均信噪比(信号到噪声比)的建议。该算法根据指定的核大小将输入图像划分为一定数目的“子图像”,以独立地评估每个子图像的局部信噪比,然后对每个子图像的计算信噪比进行平均处理,得到图像全局信噪比的指示。
您将需要对此方法进行详尽的测试,但是它在以下三个映像上显示了希望,即生成AvgSNR;
图像#1 - AvgSNR = 0.9

图像#2 - AvgSNR = 7.0

图像#3 - AvgSNR = 0.6

注意:查看“干净”控件映像是如何生成一个更高的 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 * 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。当评估场景主要由普通的、单色的表面(如服务器室或商店前)组成时,这种方法效果最好。例如,草会包含大量的纹理,因此“噪音”。
发布于 2020-05-31 13:16:09
另一种方法是考虑在傅里叶变换后的频域中对图像进行评估。您提供的噪声示例主要是包含不想要的、高频内容的图像。对违反高频阈值的图像进行FFT和评估。在这里,您将从一个使用Emgu:带Emgu的FFT的快速傅立叶变换示例中学习。
https://stackoverflow.com/questions/62003846
复制相似问题