图像类,包含一个独特的颜色数组,以及用于按颜色排序和查找重复项的计数。





5.00/5 (2投票s)
图像类,包含一个独特的颜色数组,以及用于按颜色排序和查找重复项的计数。
引言
几年前,我创建了一个图片管理程序,可以用来将图像文件重命名到其目录下的组中。我希望能够对图像进行排序,以加快查找属于特定组的图像的速度。我想到,如果我提取颜色信息,我或许可以对图像进行排序比较。
我知道尝试提取整个图像的颜色会花费太长时间,所以我将它们缩小到缩略图大小。排序结果让我感到惊讶,但对排序结果不够完美感到有点失望。我一直在尝试不同的、更复杂的比较方法,但结果几乎相同。我尝试使用 XYZ 和 LAB 颜色,但结果仍然几乎相同,我坚持使用 RGB。我尝试分别提取图像边框的颜色信息,并将其比较作为 GUI 上的次要排序选项提供。
我尝试根据颜色使用情况对颜色数组进行排序,认为这会对排序结果产生影响。它产生了一些微小的差异,但似乎一张图像可能包含比另一张图像更多的特定品红色的色调并不重要。我从未真正逐个颜色地查看原始颜色数据,也无法得出关于某种复杂比较如何影响排序的任何结论。
最后,为了加快颜色提取过程,我尽可能减少了步骤。我提取了颜色,按照颜色出现的顺序填充数组,从左上角开始,检测单色图像,并保留图像边框的红色、绿色和蓝色值的平均值。最终,我将缩略图以 PNG 格式存储在数据库中,以及文件名、宽度和高度,以跳过每次打开原始图像并缩小它的操作。我没有尝试将颜色数组以单个组件的形式保存在数据库中,因为我知道这会非常慢,但我想这个数组可以以某种方式存储为 blob,以便实现非常快的加载时间。
使用代码
比较类实例与另一个图像,用于排序例程
public int CompareRGB(in ImageParser py)
{
int k, i, c;
if (Colors.Length <= py.Colors.Length)
c = Colors.Length;
else
c = py.Colors.Length;
for (i = 0;i<c;i++)
{
k = PicColor.CompareRGB(Colors[i], py.Colors[i]);
if (k != 0) return k;
if (Colors[i].Amount > py.Colors[i].Amount) return 1;
if (Colors[i].Amount < py.Colors[i].Amount) return -1;
}
return 0;
}
上面调用的 PicColor 类的 CompareRGB 例程
public static int CompareRGB(in PicColor p1, in PicColor p2)
{
if (p1.R > p2.R) return 1;
if (p1.R < p2.R) return -1;
if (p1.G > p2.G) return 1;
if (p1.G < p2.G) return -1;
if (p1.B > p2.B) return 1;
if (p1.B < p2.B) return -1;
return 0;
}
检查类实例与另一个图像,以测试是否有重复项
public bool Equal(in ImageParser py)
{
int i, c, k;
if (Width != py.Width) return false; // original image width and height here
if (Height != py.Height) return false;
if (Colors.Length != py.Colors.Length) return false;
c = Colors.Length;
for (i=0;i<c;i++)
{
k = PicColor.CompareRGB(Colors[i], py.Colors[i]); // k is -1, 0, or 1
if (k != 0) return false;
if (Colors[i].Amount != py.Colors[i].Amount) return false;
}
return true;
}
关注点
我一直在尝试寻找比较颜色信息数组的最佳方法,以获得完美的排序,将图片集神奇地分组在一起。结果总是有一些差异,但无论比较例程有多复杂,结果都永远不完美。我尝试过诸如在提取后按每个颜色的数量对数组进行排序之类的操作。我尝试将数组比较深度限制为可调整的颜色数量。
我认为排序结果不完美的主要原因是图像中颜色的色调差异很大。一组图像可能都包含青色,但单个青色色调在整个图像子组中可能稍微更暗或更亮。在拍摄过程中,云层经过可能会改变颜色色调。
是否有语言可以描述,鉴于我破译数据的能力,原始图像颜色数据有多么难以理解?我设置了断点,并试图在比较例程中查看颜色数据的趋势,但无济于事。我能做的最好的事情是让排序运行并查看缩略图在 ListView 中的结果顺序。
基于颜色提取的重复图像比较一直运行良好。我没有尝试试验缩略图的大小以查看它如何影响捕获重复项的机会,我想两个相似的图像可能会被缩小到 128 像素,并被程序认为是重复项,但我从未遇到过这种情况。
包含的 ImageParser 类包含对 PictureItem 类的引用,该类将图像数据存储到 SQL 中。可以安全地删除引用和任何使用它的代码。如果我包含 PictureItem 类,我最好上传整个项目,因为引用会迅速堆积起来。
Sorts.cs 文件还引用了我的各种类,这些类目前不会被包含。我将指出 LVItem 类是一个简单的 ListViewItem 包装器。
仔细想想,这里没有什么革命性的东西,从位图提取颜色并对其进行排序。但是当我把所有东西放在一起,图像被排序出来时,我很惊讶。我认为图像重复测试如果颜色数组可以在数据库中保存为 blob,则具有商业可行性。