查询数据库中的色彩空间
我正在使用 Django 并有一个填充任意 RGB 颜色的 MySQL 数据库。 RGB 值存储为整数。
| Name | R | G | B |
+-------+---+---+---+
| Green | 0 |255| 0 |
| Cyan | 0 |255|255|
| ... | . | . | . |
| Foo |123| 45| 2 |
| ... | . | . | . |
给定任意 RGB 值 (a,b,c)
我想计算数据库中哪些颜色“接近”(a,b,c)
。我将在查询中预定义“接近”的含义,但现在我们将其称为 x
。
您可以将 RGB 颜色空间视为三维空间,其中颜色作为该空间中的点。因此,(a,b,c)
和 x
在该空间中定义了一个球体,其中心点为 (a,b,c)
和半径x
。
Pythagorus 告诉我们,以下内容对于该领域内的所有点都是正确的:
(R-a)**2 + (G-b)**2 + (B-c)**2 <= x**2
我想将其转换为有效的 Django 查询。如果做不到这一点,则需要进行 MySQL 查询。
我不是 MySQL 专家,但我怀疑 Django 查询语法在这种情况下可能非常有限。编写原始 SQL 查询是解决这个问题的方法吗?代码会更清晰吗?它实际上可以更快/更高效吗?
Django 颜色模型如下所示:
class Color(models.Model):
name = models.CharField(max_length=32)
r = models.IntegerField()
g = models.IntegerField()
b = models.IntegerField()
示例查询:
c = (234, 23, 45)
x = 25
nearby_colors = Color.objects.filter(....) # Awesome-sauce
I'm using Django and have a MySQL database filled with arbitrary RGB colors. The RGB values are stored as Integers.
| Name | R | G | B |
+-------+---+---+---+
| Green | 0 |255| 0 |
| Cyan | 0 |255|255|
| ... | . | . | . |
| Foo |123| 45| 2 |
| ... | . | . | . |
Given an arbitrary RGB value (a,b,c)
I want to calculate what colors in the database are "close to" (a,b,c)
. I'll predefine what "close to" means in my query but for now let's call it x
.
You can think of the RGB color space as a three dimensional space with colors as points in that space. So (a,b,c)
and x
define a sphere in that space with a center point (a,b,c)
and radius x
.
Pythagorus tells us that the following is true for all of the points within this sphere:
(R-a)**2 + (G-b)**2 + (B-c)**2 <= x**2
I would like to translate this into a valid Django Query. And, failing that, a MySQL query.
I'm no MySQL expert but I have some suspicions that the Django Query syntax may be very limiting in this context. Would writing a raw SQL query be the way to go here? Would it be better because the code would be more clear? Could it actually be faster/more efficient?
Django Color Model looks like:
class Color(models.Model):
name = models.CharField(max_length=32)
r = models.IntegerField()
g = models.IntegerField()
b = models.IntegerField()
An example query:
c = (234, 23, 45)
x = 25
nearby_colors = Color.objects.filter(....) # Awesome-sauce
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
创建此查询的 django ORM 方法将类似于:
如果您使用变量 R=50, G=50, B=50, x=3 (即 str(result.query))打印生成的查询,您生成:
请注意,POWER() 函数是特定于 mysql 的,因此这与数据库无关。
The django ORM way to create this query would be would be something like:
Which if you print the generated query with variables R=50, G=50, B=50, x=3 (ie. str(result.query)) you'd generate:
Note that the POWER() function is mysql-specific though, so this is not database agnostic.
简单地说,
其中 R、G、B 是列,您将提供要替换的值,a,b,c,x
示例数据
一些用于测试查询的
,来自 (50,50,50) 的 50 个单位输出
Simply,
where R,G,B are the columns, and you will supply values to replace, a,b,c,x
Some sample data to test
A query, 50 units from (50,50,50)
The output
感谢每个提供意见的人,但我认为我的解决方案与建议我应该创建自己的答案的建议足够不同。
Thanks to everyone who provided input, but I thought my solution was different enough from what was suggested that I should create my own answer.
我的大脑现在很混乱,所以确切的语法有点不对劲,但是,假设您在 R、G 和 B 上有一个索引,请执行三个查询,每个索引一个,然后将它们连接在一起。
您需要确保连接类型不允许空值。我忘记这是否有效。
但是有比我更好的 sql 经验和更多睡眠的人可以在此基础上建立:-)
My brain is fried right now, so the exact syntax is a little off, but, assuming you have an index on R, G, and B, do three queries, one for each index, and join them together.
You need to make sure you the type of join that doesn't allow null values. I forget if that works or not.
But someone with better sql experience and more sleep than I can build upon this :-)