[英]python django search image by dominant color
我正在使用 django(3.0) python(3.8) 构建一个包含一堆图片的网站。 我正在尝试制作一个过滤器,其中用户 select 一种颜色并返回主色是用户请求的颜色的图像。 要做到这一点,
def RgbToInt(rgb):
red = rgb[0]
green = rgb[1]
blue = rgb[2]
RGBint = (red << 16) + (green << 8) + blue
return RGBint
class Design(models.Model):
...fields...
image = ImageField(upload_to=upload_image_path)
dominant_color = models.CharField(max_length=80, blank=True)
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
img = Image.open(self.image.path).resize((180, 180))
colors = colorgram.extract(img, 3)
white = 210
color = [f'{RgbToInt(c.rgb)},{int(round(c.proportion * 100, 0))}' for c in colors
if not (c.rgb[0] > white and c.rgb[1] > white and c.rgb[2] > white)]
if len(color) > 3: color = color[:2]
self.dominant_color = color
super(Design, self).save(force_insert=False, force_update=False, using=None,
update_fields=None)
-- Colorgram 给出如下结果:
[<colorgram.py Color: Rgb(r=252, g=251, b=249), 72.43592003666748%>,
<colorgram.py Color: Rgb(r=196, g=170, b=103), 18.46067059196841%>,
<colorgram.py Color: Rgb(r=194, g=150, b=37), 9.103409371364101%>]
-- 我在设计 model 中将其保存为字符串,如下所示:
['12888679,18', '12752421,9']
... view...
def get_queryset(self):
qs = super().get_queryset()
color = self.request.GET.get('color')
if color:
...GOTTA FIND IMAGES WITH DOMINANT COLOR SIMILAR TO REQUESTED COLOR...
return qs
- 我一直在寻找 deltaE,但据我了解,它是比较两个图像而不是两个颜色值。 感谢阅读和帮助..
扩展我的评论:
如果您将 RGB 值存储为单个打包的 integer,那么您将很难比较它们。
我建议添加一个单独的 model:
class Image:
# ...
class ImageColor(models.Model):
image = models.ForeignKey(Image, related_name='colors')
proportion = models.FloatField()
rank = models.PositiveIntegerField()
r = models.PositiveIntegerField()
g = models.PositiveIntegerField()
b = models.PositiveIntegerField()
hue = models.FloatField()
sat = models.FloatField()
val = models.FloatField()
class Meta:
unique_together = (('image', 'rank'),)
在哪里
proportion
将是计算的比例值rank
将是最主要的 colors 中的颜色索引(1 表示最主要,2 表示第二等)r
/ g
/ b
是颜色的原始 RGB 值hue
/ sat
/ val
是颜色的 HSV 值( import colorsys
等); 这些可能会派上用场(您可以选择在其他对您的用例有意义的颜色系统中添加 colors。)
然后,如果用户发布一种颜色,则查询其最主要颜色接近该颜色的图像会变成类似(干编码,可能有问题或不起作用)
from django.db.models.functions import Abs, Sqrt
images = Image.objects.annotate(
r_distance = Abs(F('colors__r') - user_r),
g_distance = Abs(F('colors__g') - user_g),
b_distance = Abs(F('colors__b') - user_b),
).filter(
colors__rank=1,
r_distance__lt=30,
g_distance__lt=30,
b_distance__lt=30,
).annotate(
color_distance=F('r_distance') + F('g_distance') + F('b_distance')
).order_by('color_distance')
(您可以选择在 RGB 空间上选择曼哈顿距离以外的其他指标。)
查询可能不会很轻量或优化,但我敢肯定,对于初学者来说是可以的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.