首页 > 解决方案 > 如何从 python 中的特定列创建列表等

问题描述

我有一个我设计的 CompSci 项目,我想制作一个程序,它可以告诉我光标下的像素信息,将其与 CSV 文件中的 RGB 值列表匹配,找到最接近的颜色并显示它。

这是我的 CSV 文件

Color,Red,Green,Blue
Black,0,0,0
White,255,255,255
Red,255,0,0
Lime,0,255,0
Blue,0,0,255
Yellow,255,255,0
Cyan,0,255,255
Magenta,255,0,255
Silver,192,192,192
Gray,128,128,128
Maroon,128,0,0
Olive,128,128,0
Green,0,128,0
Purple,128,0,128
Teal,0,128,128
Navy,0,0,128

我的目标是使用 min 函数在光标下的 RGB 值中找到最接近的红色值。然后,检查匹配的红色的相应绿色值。然后,检查匹配的红色和绿色最接近的蓝色值。然后,我可以提取颜色值,我会知道所选像素是什么颜色。我的问题是我不知道是否应该将我的 CSV 数据转换为列表、创建字典或什么。我已经尝试了一切并且一直卡住。根据我所说的我想做的事情,有人可以帮助我,或者指出我正确的方向吗?

from image import *
from PIL import *
from pynput.mouse import Listener
import PIL.ImageGrab

#Create an imagewindow based on image dimensions; display the image
def printImage(imageFile):
    myImage = FileImage(imageFile)
    _width = myImage.getWidth()
    _height = myImage.getHeight()
    myWindow = ImageWin(_height, _width, "window")
    myImage.draw(myWindow)

printImage("mickey.png")

#Color finding function
def getColor(_x, _y):
    return PIL.ImageGrab.grab().load()[_x, _y]

#Uses mouse position for x and y value of color finding function
def on_move(x, y):
    global _color
    _x = x
    _y = y
    _color = getColor(_x, _y)
    print(_color)

def on_click(x, y, button, pressed):
    print('done')
    if not pressed:
        return False
#allows on move to be updated every time it occurs
with Listener(on_move=on_move, on_click=on_click) as listener:
    listener.join()

colorRed = _color[0]
colorGreen = _color[1]
colorBlue = _color[2]


#Take pixel information and match it to a color in the text file
from csv import *
with open("Color Collection.csv") as myFile:
    myReader = reader(myFile)
    for line in myReader:
        print(line[1])

标签: python

解决方案


将这些颜色视为三维空间中的点。你想从这些已经存在的点中找到离你最近的点。幸运的是,有一个既定的公式可以做到这一点。让我们从您的代码示例开始

from csv import *

首先,我们需要一些数学函数,所以让我们导入我们需要的:

from math import sqrt, pow

让我们添加一个变量来跟踪当前最接近的颜色。这将是一个 2 元素数组:文件中颜色的名称以及与请求点的距离。

closestColor = []

声明后myReader = reader(myFile),让我们跳过标题(想法取自https://stackoverflow.com/a/3428633/4462517

next(reader, None)

现在,在您定义的循环内,让我们计算文件中的点与您已经收集的点之间的距离:

lineRed = line[1]
lineGreen = line[2]
lineBlue = line[3]

distance = sqrt(pow(colorRed - lineRed, 2) + pow(colorGreen - lineGreen, 2) + pow (colorBlue - lineBlue, 2))

现在,让我们确定当前最接近的颜色是否比我们刚刚计算的颜色更近或更远

if distance < closestColor[1]:
    closestColor = [line[0], distance]

可是等等!if 语句可能(并且将)第一次抛出错误,因为没有closestColor[1]. 让我们把 if 块改成这样:

if (len(closestColor) < 2) or (distance < closestColor[1]):
    closestColor = [line[0], distance]

现在,在列表之外,您可以做您需要做的事情!所以,你的代码片段的结尾应该是这样的(我假设你之前捕获颜色的代码已经过测试并且是正确的):

#Take pixel information and match it to a color in the text file
from csv import *
from math import sqrt, pow

closestColor = []
with open("Color Collection.csv") as myFile:
    myReader = reader(myFile)
    next(reader, None)
    for line in myReader:
        lineRed = line[1]
        lineGreen = line[2]
        lineBlue = line[3]

        distance = sqrt(pow(colorRed - lineRed, 2) + \
                        pow(colorGreen - lineGreen, 2) + \
                        pow(colorBlue - lineBlue, 2))

        if (len(closestColor) < 2) or (distance < closestColor[1]):
            closestColor = [line[0], distance]

# This style works on Python3.6+
print(f'The closest color to the point clicked is {closestColor[0]}')

# If you have to use <3.5, I'm sorry, but you can do this instead
# print('The closest color to the point clicked is %s', %(closestColor[0]))

试一试,希望对您有所帮助!


推荐阅读