如何计算当前RGB颜色与目标颜色的相似度百分比?
基于Pygame的选色游戏优化方案
当然可行,你当前的核心问题是颜色相似度的计算公式错误,以下是具体的修正方案、完整代码和评分系统实现:
一、正确的颜色相似度百分比计算
你之前的公式未考虑颜色通道的差异逻辑,完全无法反映颜色接近程度。正确的思路是:计算每个RGB通道与目标值的差异,将差异转换为相似度后取平均值,再转换成百分比。
基础计算方案
示例公式(目标颜色为(target_r, target_g, target_b)):
# 计算每个通道的绝对差异 diff_r = abs(current_r - target_r) diff_g = abs(current_g - target_g) diff_b = abs(current_b - target_b) # 转换为通道相似度(差异越小,相似度越高),再取平均得到整体百分比 percent = ((255 - diff_r)/255 + (255 - diff_g)/255 + (255 - diff_b)/255) / 3 * 100 percent = round(percent, 2)
- 当目标为
(50,50,50)、当前为(51,51,51)时,计算得相似度约99.6%(与你预期的98%接近,可通过调整公式权重进一步贴合需求)。 - 当目标为
(50,50,50)、当前为(255,255,255)时,计算得相似度约19.6%。
接近10%的自定义方案
若需要上述场景相似度更接近10%,可改用RGB空间欧氏距离归一化的方式:
# 基于欧氏距离的相似度计算 max_distance = (255**2 + 255**2 + 255**2)**0.5 current_distance = (diff_r**2 + diff_g**2 + diff_b**2)**0.5 percent = (1 - current_distance/max_distance) * 100 percent = round(percent, 2)
此方式下上述场景的相似度约20%,若要更低可自定义距离权重。
二、修改后的完整代码
整合了正确的相似度计算、实时百分比显示、时间+准确度评分系统,同时修复了原代码的卡顿问题:
import pygame, sys, time, random pygame.init() pygame.font.init() # 初始化游戏参数 playerx = 0 playery = 0 sizex = 500 sizey = 200 r, g, b = 255, 0, 0 color = (r, g, b) speed = 1 clock = pygame.time.Clock() # 用时钟控制帧率,替代sleep # 随机生成目标颜色 target_r = random.randint(0, 255) target_g = random.randint(0, 255) target_b = random.randint(0, 255) # 初始化窗口和字体 win = pygame.display.set_mode((500, 500)) pygame.display.set_caption("选色游戏") font = pygame.font.SysFont(None, 40) start_time = time.time() # 记录游戏开始时间 while True: win.fill((0, 0, 0)) # 每次循环清空窗口,避免残留绘制 # 事件处理 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_RETURN: # 计算评分:结合相似度和耗时,分数=相似度*(1/(1+耗时/10)),满分100 elapsed_time = time.time() - start_time score = percent * (1 / (1 + elapsed_time/10)) score = round(score, 2) print(f"相似度: {percent}% | 耗时: {round(elapsed_time,2)}秒 | 评分: {score}") # 重置游戏 target_r = random.randint(0, 255) target_g = random.randint(0, 255) target_b = random.randint(0, 255) r, g, b = 255, 0, 0 color = (r, g, b) start_time = time.time() # 绘制目标颜色和当前颜色区域 pygame.draw.rect(win, color, pygame.Rect(playerx, playery, sizex, sizey)) pygame.draw.rect(win, (target_r, target_g, target_b), pygame.Rect(0, 300, sizex, sizey)) # 按键控制RGB值 keys = pygame.key.get_pressed() if keys[pygame.K_a] and r + speed <= 255: r += speed color = (r, g, b) if keys[pygame.K_s] and g + speed <= 255: g += speed color = (r, g, b) if keys[pygame.K_d] and b + speed <= 255: b += speed color = (r, g, b) if keys[pygame.K_j] and r - speed >= 0: r -= speed color = (r, g, b) if keys[pygame.K_k] and g - speed >= 0: g -= speed color = (r, g, b) if keys[pygame.K_l] and b - speed >= 0: b -= speed color = (r, g, b) # 计算并显示相似度百分比 diff_r = abs(r - target_r) diff_g = abs(g - target_g) diff_b = abs(b - target_b) # 用通道平均相似度计算 percent = ((255 - diff_r)/255 + (255 - diff_g)/255 + (255 - diff_b)/255) / 3 * 100 percent = round(percent, 2) # 渲染文字 text = font.render(f"相似度: {percent}%", True, (255, 255, 255)) win.blit(text, (10, 250)) pygame.display.update() clock.tick(60) # 控制帧率为60FPS
三、关键优化说明
- 移除
time.sleep:改用pygame.time.Clock()控制帧率,避免游戏卡顿和按键响应延迟。 - 实时显示相似度:通过Pygame字体渲染,在窗口上方实时展示当前颜色与目标颜色的接近程度。
- 评分系统:按下回车后计算评分,结合相似度(越高越好)和耗时(越短越好),公式可根据需求自定义调整。
- 游戏重置:每次按下回车后自动生成新的目标颜色,重置当前颜色和计时,实现循环游戏。
内容的提问来源于stack exchange,提问作者ImBadAtMath
相关产品推荐
相关产品推荐

