检测图像问题
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
真不知道叫什么(失真什么的) 但我想通过使用 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