int'对象没有'__getitem__'属性

1 投票
2 回答
1604 浏览
提问于 2025-04-17 22:39

我刚开始学习Python,想要通过对比一张测试图片和一个包含多张图片的数据库,来找出图片之间的相似性。我已经从一个文件夹里提取了图片,并使用SIFT特征进行比较。

from PIL import Image
from PIL import ImageStat
from PIL import ImageFilter
import os

def get_imlist(path):
    """    Returns a list of filenames for 
        all jpg images in a directory. """

    return [os.path.join(f) for f in os.listdir(path) if f.endswith('.png')]

def fe(file_name):
    im = Image.open(file_name)
    im = im.convert('L')
    w, h = 300, 300
    im = im.resize((w, h))
    imst = ImageStat.Stat(im)
    sr = imst.mean[0]
    def foo(t):
        if t < sr * 2 / 3: return 0
        if t <= sr: return 1
        if t < sr * 4 / 3: return 2
        return 3
    im = im.point(foo)
    res = [[0] * 4 for i in range(10)]
    for y in range(h):
        for x in range(w):
            k = im.getpixel((x, y))
            res[y / 60][k] += 1
            res[x / 60 + 5][k] += 1
    return res

def ff(file_name):
    im = Image.open(file_name)
    im = im.convert('L')
    w, h = 300, 300
    im = im.resize((w, h))
    im = im.filter(ImageFilter.FIND_EDGES)
    sr = ImageStat.Stat(im).mean[0]
    res = 0
    for i in range(h):
        for j in range(w):
            if im.getpixel((j, i)) > sr:
                res += 1
    #im.show()
    return res

test_pic = '128.png' #testing this pic against all pics in our db;
path='D:/ex'
imlist=[]
db=[]
imlist=get_imlist(path)
for file in imlist:
    x = [0, file]
    db.append(x)  
z = [fe(db[i][1]) for i in range(len(db))]
test_z = fe(test_pic)
for k in range(len(db)):
    for i in range(10):
        for j in range(4):
            db[k][0] += abs(z[k][i][j] - test_z[i][j])
db.sort()

print
print '1st-line sifting [by fe()]'
print '--------------------'
print test_pic
print '--------------------'
for k in range(len(db)):
    if db[k][0] < 20 * 3600:
        print '%12s %7.2f' % (db[k][1], db[k][0] / 3600.0,)
    else:
        break
print '--------------------'
print
print
print '2nd-line sifting [by ff()]'
print '--------------------'
print test_pic
print '--------------------'
test_t = ff(test_pic)
for k in range(len(db)):
    if db[k][0] < 5 * 3600:
        print '%12s' % (db[k][1],)
    elif db[k][0] < 20 * 3600:
        t = ff(db[k][1])
        if abs(t - test_t) * 200.0 / (t + test_t) < 20:
            print '%12s' % (db[k][1],)
    else:
        break
print '--------------------'

raw_input('\nPress...\n')

2 个回答

0
def get_imlist(path):
    """    Returns a list of filenames for 
        all jpg images in a directory. """

    return [[0, 0 ,os.path.join(path, f)] for f in os.listdir(path) if f.endswith('.png')]

如果你把你的 get_imlist 函数简单地改成这样,它会返回一个和你在评论中提到的代码类似的结构。这样你就可以直接使用那段代码,而不需要再做其他修改。

2

根据我的猜测:

db = [0,file]
i = 0
z = [fe(db[i][1]) for i in range(len(db))]
      # ^ here

i == 0 时,db[i] == 0。这时候你试图访问一个整数 - 0[1] - 其实在背后是调用 0.__getitem__(1)。整数并没有实现 __getitem__ 这个功能,所以就会出现你看到的错误。


你的代码修改看起来有点奇怪,为什么要这样做:

for file in imlist:
    db = [[0,file]]   
    z = [fe(db[i][1]) for i in range(len(db))]

而不是简单地:

for file in imlist:
    z = [fe(file)]

不过,如果没有完整的错误追踪信息,很难准确找出你的错误所在。

撰写回答