您可以破解 Model.save/delete 方法将图像名称和校验和存储在数据库中,然后您可以使用一种方法来计算具有相同校验和的图像数量。
未经测试,只是为了让您朝着正确的方向开始:
class ImageAccounting(models.Model):
fk = models.IntegerField()
model_name = models.CharField(max_length=100)
md5 = models.CharField(max_length=32)
class SomeModel(models.Model)
...
image = models.ImageField(upload_to='somewhere')
...
def image_signature(self):
md5 = hashlib.md5(self.image.file.read()).hexdump()
model_name = self.__name__
return md5, model_name
def save(self, *args, *kwargs):
super(SomeModel, this).save(*args, **kwargs)
md5, model_name = self.image_signature()
try:
i = ImageAccounting.objects.get(fk=self.pk, md5=md5, model_name=model_name)
except ImageAccounting.DoesNotExist:
i = ImageAccounting(fk=self.pk, md5=md5, model_name=model_name)
i.save()
def delete(self, *args, **kwargs):
super(SomeModel, this).delete(*args, **kwargs)
md5, model_name = self.image_signature()
ImageAccounting.objects.filter(fk=self.pk, md5=md5, model_name=model_name)\
.delete()
def copies(self):
md5, _ = self.image_signature()
return ImageAccounting.objects.filter(md5=md5)
[更新]
并非所有图像都将被裁剪得完全相同,但我真的很喜欢我们要去的地方。就我而言,我有一个充满图像的数据库,这些图像可能彼此重复(但不是相同的扫描,因此它们的校验和会有所不同)。我需要一种方式来表达,“这张图片看起来和我几个小时前看到的那张真的很相似。我希望它们被链接起来,并包含一个原因的描述。” 它不一定是自动的,只是我说“我从前上传的这两张图片是相关的”的一种方式。多对多关系,如果你愿意的话,多个图像(类图像)。– mh00h
如果图像不是完全重复的,我们正在进入模糊数据库和计算机视觉领域。这些不是 CS 中较简单的主题,我担心完整的答案不适合这个空间,但它是可行的 - OpenCV有一个 Python 接口,它是一种受益于 Python 支持的快速原型设计的项目。
结果,我想要做的就是在我的数据库中标记两个图像,已经在数据库中,是彼此的重复。用户将手动将图像标记为彼此的副本。我只是不知道如何在我的模型中定义多对多关系。计算机不会发现重复项,用户会。– mh00h
如果人类将图像分类为重复图像,您只需要创建一个对称的递归关系。要创建递归关系(与自身具有多对一关系的对象),请使用models.ManyToManyField('self')
,不需要中间模型:
duplicates = models.ManyToManyField('self', null=True)