本教程展示了如何使用各种图像处理命令来比较两个图像,以确定它们在使用LEADTOOLS SDK的c# Windows控制台应用程序中的相似程度。
概述 | |
---|---|
总结 | 本教程介绍如何在c# Windows控制台应用程序中使用各种图像处理命令来比较图像。 |
完成时间 | 45分钟 |
Visual Studio项目 | 下载教程项目(5kb) |
平台 | c# Windows控制台应用程序 |
IDE | Visual Studio 2017, 2019 |
开发许可 | 下载LEADTOOLS |
用另一种语言试试 |
|
步骤熟悉创建项目的基本步骤添加引用和设置License教程,在工作之前比较图像数据的相似性-控制台c#教程。
中创建的项目的副本开始添加引用和设置License教程。如果您没有该项目,请按照该教程中的步骤创建它。
所需要的参考资料取决于项目的目的。引用可以通过以下两种方法中的一种添加(但不能同时添加)。
如果使用NuGet引用,本教程需要以下NuGet包:
Leadtools.Image.Processing
如果使用本地DLL引用,则需要以下DLL。
dll位于< INSTALL_DIR > \ LEADTOOLS22 \ Bin \ Dotnet4 \ x64
:
Leadtools.dll
Leadtools.Codecs.dll
Leadtools.Codecs.Cmp.dll
Leadtools.Codecs.Png.dll
Leadtools.ImageProcessing.Color.dll
Leadtools.ImageProcessing.Core.dll
Leadtools.ImageProcessing.Effects.dll
有关应用程序需要哪些DLL文件的完整列表,请参阅在你的申请中包含的文件.
许可证解锁项目所需的特性。它必须在调用任何工具箱函数之前设置。有关详细信息,包括针对不同平台的教程,请参阅设置运行时License.
有两种类型的运行时许可证:
请注意
中详细介绍了添加LEADTOOLS NuGet和本地引用以及设置许可添加引用和设置License教程。
随着项目的创建、引用的添加和许可的设置,编码就可以开始了。
方法后,通过计算黑色像素的比例来比较两幅图像CombineCommand
与OperationXor
标志的所有像素的平均强度StatisticsInformationCommand
的平均色相和饱和度值ColorSeparateCommand
,各色频幅值之差与的平均值FastFourierTransformCommand
.
在解决方案资源管理器,打开Program.cs
.将以下语句添加到顶部的using块中Program.cs
:
使用系统;
使用先;
使用Leadtools;
使用Leadtools.Codecs;
使用Leadtools.ImageProcessing;
使用Leadtools.ImageProcessing.Color;
使用Leadtools.ImageProcessing.Core;
使用Leadtools.ImageProcessing.Effects;
在主要
方法添加两个新的字符串变量,并将它们设置为两个单独的图像文件路径,如下所示。为了本教程的目的,您可以下载测试图像在这里.例如,比较1 stred.png
与2 ndred.png
.
静态无效主要(字符串[]参数)
{
字符串image1Filename =@" filepath to first image ";
字符串image2Filename =@" filepath to second image ";
SetLicense ();
// RasterImages是IDisposable的,所以如果以后没有调用.Dispose(),它们必须在使用block中
使用(RasterImage image1 = LoadImage(image1Filename))
使用(RasterImage image2 = LoadImage(image2Filename))
{
控制台。WriteLine ($"图像1:{image1Filename}");
控制台。WriteLine ($"Image 2: {image2Filename}\n");
CompareXOR (image1 image2);
CompareIntensities (image1 image2);
CompareHSV (image1 image2);
CompareFourier (image1 image2);
}
控制台。WriteLine (“按任意键退出…”);
控制台。ReadKey (真正的);
}
控件中添加一个新方法程序
类命名LoadImage(字符串_filePath)
.在内部调用该方法两次使用
的声明主要
方法调用SetLicense
方法,如上所示。将下面的代码添加到LoadImage
方法将给定文件加载为RasterImage
对象。
静态RasterImage LoadImage (字符串文件名)
{
使用(RasterCodecs codecs =新RasterCodecs ())
返回codecs.Load(文件名);
}
属性中添加四个新方法程序
类命名比较xor (RasterImage image1, RasterImage image2)
,比较强度(RasterImage image1, RasterImage image2)
,比较hsv (RasterImage image1, RasterImage image2)
,比较傅立叶(RasterImage image1, RasterImage image2)
.方法调用下面的所有四个方法LoadImage
方法,在使用
语句,如上所示。
添加下面的代码CompareXOR
方法。在这种方法中,我们将使用CombineCommand
.这将一个图像放在另一个图像上,在一个特定的位置和特定的矩形内。底层图像的像素受覆盖图像影响的方式取决于我们使用的标志。在本例中,我们将使用aLeadRect
这是与底部图像相同的大小来使用整个图像。我们将使用OperationXor
标志,该标志将对每个图像的上下像素集执行逐位异或操作。这将创建黑色像素,其中两个像素在两个图像的同一位置是相同的,其他地方都是白色的。为了计算两幅图像之间有多少相同,我们将只从黑色像素中创建一个区域,并将其与所有像素的总和进行比较。
私人静态无效比较xor (RasterImage image1, RasterImage image2)
{
使用(RasterImage image2Copy = image2.Clone())
{
//将图像进行异或合并
新CombineCommand ()
{
DestinationRectangle =新LeadRect(0,0, image1.)宽度,image1.Height),
Flags =组合mandflags。OperationXor,
SourceImage = image1,
SourcePoint =新LeadPoint (0, 0)
} .Run (image2Copy);
//计算黑色像素的百分比(其中XOR相同)
image2Copy.AddColorToRegion (RasterColor。黑色,RasterRegionCombineMode.Set);
双比率= (双)image2Copy. calculateregionarea () / (image2Copy. calculateregionarea。宽度* image2Copy.Height);
控制台。WriteLine ($“单个像素:{100.0 *比例:0.00}%匹配”);
}
}
添加下面的代码CompareIntensities
方法创建StatisticsInformationCommand
,它允许您只在统计种群中包含某个范围或颜色的像素。我们将使用主通道中0-255的所有像素。我们将收集图像的平均值并将两者进行比较,将其缩放为0-1.00而不是0-255。这将给我们平均强度或亮度的差异。
我们还可以使用这个命令通过异或来获得这些图像的差异强度CombineCommand
像以前一样。这将通过相同像素值与不同像素值的比值来计算。
私人静态无效比较强度(RasterImage image1, RasterImage image2)
{
使用(RasterImage image1Gray = image1.Clone())
使用(RasterImage image2Gray = image1.Clone())
{
//将两个图像转换为灰度
GrayscaleCommand grayscale =新GrayscaleCommand ()
{
BitsPerPixel = 8
};
grayscale.Run (image1Gray);
grayscale.Run (image2Gray);
//比较总体平均强度
statisticinformationcommand statistics =新StatisticsInformationCommand ()
{
Channel = RasterColorChannel。主人,
End = 255,
Start = 0
};
statistics.Run (image1Gray);
双leftIntensity = statistics.Mean;
statistics.Run (image2Gray);
双rightIntensity = statistics.Mean;
双相似度= 1.0 -(数学。Abs(leftIntensity - rightIntensity) / 255.0);
控制台。WriteLine ($“整体图像强度:{100.0 *相似度:0.00}%匹配”);
//检查差异的强度
新CombineCommand ()
{
DestinationRectangle =新LeadRect(0,0, image1Gray。宽度,image1Gray.Height),
Flags =组合mandflags。OperationXor,
SourceImage = image1Gray,
SourcePoint =新LeadPoint (0, 0)
} .Run (image2Gray);
statistics.Run (image2Gray);
相似度= 1.0 -(统计。Mean / 255.0);
控制台。WriteLine ($“图像差异强度:{100.0 *相似度:0.00}%匹配”);
}
}
添加下面的代码CompareHSV
方法将图像分离为色相,饱和度和值通道,而不是红色,绿色和蓝色。这将创建一个DestinationImage
对象,其中有三个页面,每个频道一个页面。然后我们可以使用StatisticsInformationCommand
通过在分离图像的每一页上运行它,再次找到两张图像的平均色相和饱和度。平均值本质上是图像的亮度,这不是很有用。然后我们可以比较平均色相和饱和度的差异,再次将其从0-255缩放到0-100。
私人静态无效比较hsv (RasterImage image1, RasterImage image2)
{
colorseparatcommand colorSeparate =新ColorSeparateCommand ()
{
类型= ColorSeparateCommandType。Hsv
};
statisticinformationcommand statistics =新StatisticsInformationCommand ()
{
Channel = RasterColorChannel。主人,
End = 255,
Start = 0
};
//分离第一个图像,计算平均值
colorSeparate.Run (image1);
双image1Hue image1Saturation;
使用(RasterImage image1Separated = colorSeparate.DestinationImage)
{
image1Separated。Page = 1;
statistics.Run (image1Separated);
image1Hue = statistics.Mean;
image1Separated。Page = 2;
statistics.Run (image1Separated);
image1Saturation = statistics.Mean;
}
//分离第二张图像,计算平均值
colorSeparate.Run (image2);
双image2Hue image2Saturation;
使用(RasterImage image2Separated = colorSeparate.DestinationImage)
{
image2Separated。Page = 1;
statistics.Run (image2Separated);
image2Hue = statistics.Mean;
image2Separated。Page = 2;
statistics.Run (image2Separated);
image2Saturation = statistics.Mean;
}
//计算色相差
//注意:0在255后面,所以需要进行补偿
双hueDiff =数学。Abs(image1Hue - image2Hue);
如果(hueDiff > 127)
hueDiff =数学。Abs(hueDiff - 255);
//记录色调相似度
双相似度= 1.0 - (hueDiff / 255.0);
控制台。WriteLine ($"平均色相值:{100.0 *相似度:0.00}%匹配");
//记录饱和度相似度
相似度= 1.0 -(数学。Abs(image1Saturation - image2Saturation) / 255);
控制台。WriteLine ($平均饱和度值:{100.0 *相似度:0.00}%匹配);
}
最后,添加下面的代码CompareHSV
方法比较两幅图像的频率分布FastFourierTransformCommand
.快速傅里叶变换(FFT)的工作原理是将图像从空间域转换到频域,这对于滤除噪声等事情很有用。我们将用它来比较每个频率的幅度。运行命令之后,就可以使用info对象的命令了数据
属性来获取复杂的
与每个频率相关的数字,计算每个频率的幅度,并计算两个平均值之间的差值。
私人静态无效比较傅立叶(RasterImage image1, RasterImage image2)
{
使用(RasterImage image1Copy = image1.Clone())
使用(RasterImage image2Copy = image2.Clone())
{
//确保图像大小相同
如果(image1Copy。宽度!= image2Copy。宽度|| image1Copy。= image2Copy.Height)
{
//可以使用最小大小,但我们将它设置为固定的256 * 256
size =新SizeCommand ()
{
Flags = RasterSizeFlags。双三次的,
高度= 256,
宽度= 256
};
size.Run (image1Copy);
size.Run (image2Copy);
}
//设置快速傅里叶变换数据
//注意:我们需要padding标志,这样就可以处理非幂的大小
FastFourierTransformCommandFlags = FastFourierTransformCommandFlags。FastFourierTransform
| FastFourierTransformCommandFlags。灰色| FastFourierTransformCommandFlags.PadOptimally;
FourierTransformInformation image1Info =新FourierTransformInformation (image1Copy fftFlags);
FourierTransformInformation image2Info =新FourierTransformInformation (image2Copy fftFlags);
//对两个图像应用FFT
FastFourierTransformCommand fft =新FastFourierTransformCommand ()
{
Flags = fftFlags,
FourierTransformInformation = image1Info
};
fft.Run (image1Copy);
fft。FourierTransformInformation = image2Info;
fft.Run (image2Copy);
//根据每个分量的大小计算频率的相似度
双magnitudeTotal = 0;
双magnitudeTotalDiff = 0;
intlength = image1Info.Data.Length;
Complex[] image1Data = image1Info.Data;
Complex[] image2Data = image2Info.Data;
为(intI = 0;I < length;我+ +)
{
//计算每个条目的大小
复杂image1Entry = image1Data[i];
双image1Magnitude = Math.Sqrt(image1Entry. sqrt)R * image1Entry。R + image1Entry。I * image1entry I);
复杂image2Entry = image2Data[i];
双image2Magnitude = Math.Sqrt(image2Entry. sqrt)R * image2Entry。R + image2Entry。I * image2entry I);
//加上总数
magnitudeTotal += image1大小+ image2大小;
magnitudeTotalDiff +=数学。Abs(image1Magnitude - image2Magnitude);
}
//确保不除以零
如果(magnitudeTotal == 0)
magnitudeTotal = 1;
//记录结果
双similarity = (magnitudeTotal - magnitudeTotalDiff) / magnitudeTotal;
控制台。WriteLine ($频率比较:{100.0 *相似度:0.00}%匹配);
}
}
使用MemoryStream
使用本教程,替换Main ()
方法如下:
静态无效主要(字符串[]参数)
{
字符串image1Filename =@" filepath to first image ";
字符串image2Filename =@" filepath to second image ";
试一试
{
SetLicense ();
Console.WriteLine ();
//使用内存流
使用(RasterCodecs =新RasterCodecs ())
{
// RasterImages是IDisposable的,所以如果以后没有调用.Dispose(),它们必须在使用block中
字节[] bytes1 = File.ReadAllBytes(image1Filename);
字节[] bytes2 = File.ReadAllBytes(image2Filename);
memoryStream1 =新MemoryStream (bytes1);
memoryStream2 =新MemoryStream (bytes2);
使用(RasterImage image1 = rasterCodecs.Load(memoryStream1))
使用(RasterImage image2 = rasterCodecs.Load(memoryStream2))
{
控制台。WriteLine ($"图像1:{image1}");
控制台。WriteLine ($"图片2:{image2}");
Console.WriteLine ();
CompareXOR (image1 image2);
CompareIntensities (image1 image2);
CompareHSV (image1 image2);
CompareFourier (image1 image2);
}
}
}
抓(异常交货)
{
Console.WriteLine (ex.Message);
Console.WriteLine (ex.StackTrace);
}
Console.WriteLine ();
控制台。WriteLine (“按任意键退出…”);
控制台。ReadKey (真正的);
}
按下运行项目F5,或选择Debug ->开始调试.
如果正确地执行了这些步骤,应用程序将运行并对两个图像执行多个计算,并将相似性统计信息输出到控制台。
本教程展示了如何使用各种图像处理命令,包括CombineCommand
,GrayscaleCommand
,StatisticsInformationCommand
,ColorSeparateCommand
,SizeCommand
,FastFourierTransformCommand
,得到两幅图像的相似度统计量。