【发布时间】:2012-08-01 08:14:16
【问题描述】:
我有下表存储有关图像的数据:
images
- id (int)
- sample_1_1 (int)
- sample_1_2 (int)
- sample_1_3 (int)
- sample_2_1 (int)
- sample_2_2 (int)
- sample_2_3 (int)
- ... # Up until sample_25_3
任务是计算收集到的数据之间的距离。目前,我正在使用一个 75 维(没错,3 * 25 = 75)欧几里德距离计算作为存储过程编程到数据库中:
CREATE DEFINER=`root`@`localhost`
FUNCTION `distanceBetween`(compareId INT, toId INT) RETURNS double
READS SQL DATA
DETERMINISTIC
BEGIN
DECLARE distance DOUBLE;
SELECT euclidDistance(
i1.sample_1_1, i1.sample_1_2, i1.sample_1_3,
i2.sample_1_1, i2.sample_1_2, i2.sample_1_3,
...
) INTO distance
FROM images i1, (SELECT * FROM images WHERE id = toId) i2
WHERE i1.id = compareId;
RETURN distance;
END
用另一个子程序计算 2 75-dim 之间的实际距离。向量:
CREATE DEFINER=`root`@`localhost`
FUNCTION `euclidDistance`(
img1_sample1_1 INT, img1_sample1_2 INT, img1_sample1_3 INT,
img2_sample1_1 INT, img2_sample1_2 INT, img2_sample1_3 INT,
...
) RETURNS double
RETURN SQRT(
quadDiff(img1_sample1_1, img2_sample1_1)
+ quadDiff(img1_sample1_2, img2_sample1_2)
+ quadDiff(img1_sample1_3, img2_sample1_3)
+ ...
)
还有一个计算两个值平方差的子程序:
CREATE DEFINER=`root`@`localhost`
FUNCTION `quadDiff`(var1 INT, var2 INT) RETURNS int(11)
RETURN POW(var1 - var2, 2)
函数本身非常好,并且返回的确定性结果在数学和逻辑上都是正确的。
当我想获得 与给定图像“最接近”的图像时,问题就来了 - 这意味着与任何给定图像距离最短的图像。为此,我使用了另一个程序:
CREATE DEFINER=`root`@`localhost`
PROCEDURE `getSimilarImages`(imageId INT, `limit` INT)
BEGIN
SELECT i2.id, i2.filename, distanceBetween(i1.id, i2.id) distance
FROM images i1, (SELECT * FROM images WHERE id != imageId AND duplicateImageId IS NULL) i2
WHERE i1.id = imageId
ORDER BY distance
LIMIT 10;
END
该数据库目前包含大约 30.000 张图像。这意味着 CALL getSimilarImages(123, 10); 大约需要 12 秒才能完成。这对于任何应用程序来说都太长了,无论是基于 Web 的还是基于应用程序的。
所以,我想加快速度。我有哪些选择?您是否看到任何优化图像比较或计算距离的过程的潜力?
我想过缓存过程的结果,但我不知道该怎么做。我还可以在添加新图像后立即将每张图像与其他图像进行比较,但这会使添加图像的过程非常漫长,这也是不可接受的。
如果有帮助,我可以提供有关系统设置的更多信息,但我感谢您提供的任何指点。目前情况不太好,我真的需要做点什么,因为图像数据库只会随着系统启动的每一个小时而增长。
【问题讨论】:
-
我不会再写这个了,但也许这个相关的问题对你有帮助。在这里阅读我关于加快速度的答案:stackoverflow.com/questions/9453652/…
-
请详细说明您的用例。我不明白你为什么需要疯狂的 75 维欧几里得距离。你在那里做什么?这与纬度/经度地理定位无关,对吧?
-
不,这是关于图像之间的抽象“距离”。这意味着可以通过比较两个图像的多个采样及其颜色值(1 - 红色,2 - 绿色,3 - 蓝色)来确定两个图像之间的相似性。当两幅图像非常相似时,它们将在存储在数据库中的 25 个样本中具有非常相似的颜色值。
标签: mysql database-design query-optimization database-optimization