Python 将图像与列表进行比较
我一直在与一个程序斗争,我已经阅读了许多关于在python中使用图像的信息,但我没有让我的程序工作 我正在做一个识别卡的程序。我有一个所有卡片的“数据库”,每个卡片都在不同的jpg文件中。因此,我们尝试将我们想要知道的卡片与所有可能的卡片进行比较。那么更相似的卡片就是我正在寻找的卡片。我尝试过几种不同的代码,但没有人能正确地完成他的工作Python 将图像与列表进行比较,python,image,Python,Image,我一直在与一个程序斗争,我已经阅读了许多关于在python中使用图像的信息,但我没有让我的程序工作 我正在做一个识别卡的程序。我有一个所有卡片的“数据库”,每个卡片都在不同的jpg文件中。因此,我们尝试将我们想要知道的卡片与所有可能的卡片进行比较。那么更相似的卡片就是我正在寻找的卡片。我尝试过几种不同的代码,但没有人能正确地完成他的工作 def get_card(image1path): from PIL import Image import math import o
def get_card(image1path):
from PIL import Image
import math
import os
import operator
__docstring__ = "compare two image files"
h1 = Image.open(image1path).resize((40,55)).histogram()
best=99999999
for root,dirs,files in os.walk("cards"):
for file in [f for f in files]:
list=(os.path.join(root, file))
h2 = Image.open(list).resize((40,55)).histogram()
rms = math.sqrt(reduce(operator.add, map(lambda a,b: (a-b)**2, h1, h2))/len(h1))
print "RMS = "+str(rms)+" and the picture is:"+list
if rms<best:
best=rms
card=(os.path.join(file)).split(".")[0]
return card
image1path="C:\\8d.jpg" #eight of diamonds.
card=get_card(image1path)
print card
def获取卡(image1path):
从PIL导入图像
输入数学
导入操作系统
进口经营者
__docstring=“比较两个图像文件”
h1=Image.open(image1path).resize((40,55)).histogram()
最佳=9999999
对于os.walk(“卡”)中的根目录、目录和文件:
对于文件中的文件[f对于文件中的文件]:
list=(os.path.join(根,文件))
h2=图像。打开(列表)。调整大小((40,55))。直方图()
rms=math.sqrt(reduce(operator.add,map(lambda,b:(a-b)**2,h1,h2))/len(h1))
打印“RMS=“+str(RMS)+”,图片为:“+list”
如果rms通过查看您正在比较的图像,那么实际上您不想使用诸如RMSE
和其他指标。原因是因为所有图像在“RMSE意义上”都是相似的,甚至对于更精细的度量,也不关心图像中存在的基本关系。以下是您自己给出的一些示例:
在您的案例中,基本关系是:颜色(也区分黑桃、红桃、钻石和梅花卡)和形状度量。因此,通过检测卡片的颜色,搜索空间就减少了,剩下的就是识别卡片顶部的数字。再加上连接组件的数量和euler编号,搜索受到进一步限制。现在剩下的是区分“9”和“6”、“4”、皇后或“A”;“J”、“2”、“5”或“7”中的“3”;“8”和“10”被解决,前者是由于euler编号,后者由于其连接的组件数(这都假设卡是唯一的,否则您继续并找到最相似的卡)。这里要做的最简单的事情是计算每个剩余形状之间的Hausdorff距离,如果您在问题中添加更多的考虑因素,这可能会失败
这里是一个简单的实现,它考虑了这些点,并适用于所有给定的输入。它需要一个映像和一个目录来查找要比较的映像。每一步都可以改进
import sys
import numpy
from scipy.ndimage import morphology, label, find_objects
from PIL import Image
COLORS = range(4)
RED, GREEN, BLUE, BLACK = COLORS
def card_color(img):
im = img.load()
width, height = img.size
black, blue, green, red = 0, 0, 0, 0
for x in xrange(width):
for y in xrange(height):
r, g, b = im[x, y]
if r > 200 and g > 200 and b > 200:
# "white", ignore
continue
if r > 200 and g < 100 and b < 100:
red += 1
elif r < 100 and g < 100 and b > 200:
blue += 1
elif r < 50 and g < 50 and b < 50:
black += 1
elif r < 100 and g > 120 and b < 50: # dark green
green += 1
return max(zip((black, blue, green, red), COLORS))
def euler_number(img, conn=4):
im = img.load()
width, height = img.size
c1, c2, c3 = 0, 0, 0
for x in xrange(width - 1):
for y in xrange(height - 1):
s = (im[x,y] + im[x+1,y] + im[x,y+1] + im[x+1,y+1]) / 255
if s == 1:
c1 += 1
elif s == 2:
if (im[x+1,y] and im[x,y+1]) or (im[x,y] and im[x+1,y+1]):
c3 += 1
elif s == 3:
c2 += 1
if conn == 4:
return (c1 - c2 + 2 * c3) / 4
else: # 8
return (c1 - c2 - 2 * c3) / 4
def carefully_binarize(img, color):
if color == BLACK:
img = img.convert('L')
else:
img = img.split()[color]
width, height = img.size
im = numpy.empty((height + 2, width + 2), dtype=numpy.uint8) # Padding
im.fill(255)
im[1:-1, 1:-1] = numpy.array(img)
threshold = im.mean() - im.std()
im[im <= threshold] = 1
im[im > threshold] = 0
# Discard small components.
lbl, ncc = label(im)
for i in xrange(1, ncc + 1):
py, px = numpy.nonzero(lbl == i)
if len(py) < 30:
im[lbl == i] = 0
return Image.fromarray(im * 255)
def discard_bottom(img, k=0.5):
width, height = img.size
im = numpy.array(img)
limit = height * k
lbl, ncc = label(im)
for i, oslice in enumerate(find_objects(lbl)):
srow, scol = oslice
if srow.stop > limit:
ncc -= 1
im[srow.start:srow.stop, scol.start:scol.stop] = 0
return Image.fromarray(im), ncc
def signature(img):
# Assumption: a single connected component is present now.
im = numpy.array(img)
im = morphology.binary_fill_holes(im)
im = morphology.binary_dilation(im) - im
py, px = numpy.nonzero(im)
return Image.fromarray(im.astype(numpy.uint8)*255), zip(py, px)
def hausdorff(a, b):
dist = 0
for ai in a:
mindist = float('inf')
for bi in b:
chess = max(abs(ai[0]-bi[0]), abs(ai[1]-bi[1]))
if chess < mindist:
mindist = chess
if mindist > dist:
dist = mindist
return dist
img1 = Image.open(sys.argv[1]).convert('RGB')
dirpath = sys.argv[2]
img1_color = card_color(img1)[1]
img1 = carefully_binarize(img1, img1_color)
img1_top, img1_top_ncc = discard_bottom(img1)
img1_top_en = euler_number(img1_top)
feature = [img1_color, img1_top_ncc, img1_top_en]
match = []
for fname in os.listdir(dirpath):
try:
img2 = Image.open(os.path.join(dirpath, fname)).convert('RGB')
except IOError:
print "Ignoring", fname
continue
if card_color(img2)[1] != feature[0]:
continue
img2 = carefully_binarize(img2, feature[0])
img2_top, ncc = discard_bottom(img2)
if ncc != feature[1]:
continue
en = euler_number(img2_top)
if en != feature[2]:
continue
match.append((img2_top, os.path.join(dirpath, fname)))
if len(match) == 1:
print "Here is your best match:", match[0][1]
else:
img1_sig, sig1 = signature(img1_top)
best_match = float('inf'), None
for img2, fname in match:
img2_sig, sig2 = signature(img2)
dist = hausdorff(sig1, sig2)
if dist < best_match[0]:
best_match = dist, fname
print "Best match:", best_match[1]
导入系统
进口numpy
从scipy.ndimage导入形态学、标签、查找对象
从PIL导入图像
颜色=范围(4)
红、绿、蓝、黑=颜色
def卡颜色(img):
im=img.load()
宽度、高度=img.size
黑色、蓝色、绿色、红色=0,0,0,0
对于x范围内的x(宽度):
对于X范围内的y(高度):
r、 g,b=im[x,y]
如果r>200,g>200,b>200:
#“白色”,忽略
持续
如果r>200且g<100且b<100:
红色+=1
如果r<100,g<100,b>200:
蓝色+=1
elif r<50、g<50和b<50:
黑色+=1
elif r<100,g>120,b<50:#深绿色
绿色+=1
返回最大值(拉链(黑色、蓝色、绿色、红色、彩色))
def euler_编号(img,conn=4):
im=img.load()
宽度、高度=img.size
c1,c2,c3=0,0,0
对于x范围内的x(宽度-1):
对于X范围内的y(高度-1):
s=(im[x,y]+im[x+1,y]+im[x,y+1]+im[x+1,y+1])/255
如果s==1:
c1+=1
elif s==2:
如果(im[x+1,y]和im[x,y+1])或(im[x,y]和im[x+1,y+1]):
c3+=1
elif s==3:
c2+=1
如果conn==4:
返回(c1-c2+2*c3)/4
其他:#8
返回(c1-c2-2*c3)/4
def仔细二值化(图像,颜色):
如果颜色==黑色:
img=img.convert('L')
其他:
img=img.split()[颜色]
宽度、高度=img.size
im=numpy.empty((高度+2,宽度+2),dtype=numpy.uint8)#填充
im.fill(255)
im[1:-1,1:-1]=numpy.array(img)
阈值=im.mean()-im.std()
im[im阈值]=0
#丢弃小部件。
lbl,ncc=标签(im)
对于X范围内的i(1,ncc+1):
py,px=numpy.非零(lbl==i)
如果len(py)<30:
im[lbl==i]=0
返回Image.fromarray(im*255)
def丢弃_底部(img,k=0.5):
宽度、高度=img.size
im=numpy.array(img)
极限=高度*k
lbl,ncc=标签(im)
对于i,枚举中的oslice(查找对象(lbl)):
srow,scol=oslice
如果srow.stop>limit:
ncc-=1
im[srow.start:srow.stop,scol.start:scol.stop]=0
返回Image.fromarray(im),ncc
def签名(img):
#假设:现在存在一个连接的组件。
im=numpy.array(img)
im=形态学。二元填充孔(im)
im=形态学。二元扩张(im)-im
py,px=numpy.非零(im)
返回Image.fromarray(im.astype(numpy.uint8)*255),zip(py,px)
戴夫·豪斯多夫(a,b):
距离=0
对于a中的ai:
mindist=float('inf')
对于b中的bi:
chess=max(abs(ai[0]-bi[0]),abs(ai[1]-bi[1]))
如果你是一个正念者:
正念者=国际象棋
如果mindist>dist:
心灵主义者
返回区
img1=Image.open(sys.argv[1]).convert('RGB'))
dirpath=sys.argv[2]
img1\u color=卡片颜色(img1)[1]
img1=仔细地二值化(img1,img1\u颜色)
img1\U顶部,img1\U顶部\U ncc=丢弃\U底部(img1)
img1\U top\U en=欧拉数(img1\U top)
功能=[img1\U颜色、img1\U顶部\U ncc、img1\U顶部\U en]
匹配=[]
对于os.listdir(dirpath)中的fname:
尝试:
img2=Image.open(os.path.join(dirpath,fname)).convert('RGB')
除IOError外:
打印“忽略”,fname
持续
如果卡片是彩色的