#-*- coding: UTF-8 -*-
from PIL import Image
import MySQLdb
import sys , os , time , colorsys , json , operator
import config as cf
class ImageColorIdentify:
filename = None # 需要识别的图片地址
Wimg = 0 # 自定义裁剪宽默认
Himg = 0 # 自定义裁剪高默认
rgb_float_int = 300 # 定义颜色误差浮动范围 < 300 , 该值越大查找次数越多
is_cutting = True # 是否裁剪指定区域后再识别
SavefileName = None # 保存新文件的名字,不带后缀
SavefilePath = None # 保存新文件的全地址
def __init__( self , filename ):
if not os.path.exists(filename): # 先判断文件是否存在IO忽略
print('文件不存在~~')
return None
else:
self.filename = filename;
def CuttingImageCenter( self , cuttingList = [] ):
try:
if self.filename is not None:
img_info = Image.open( self.filename );
except IOError:
print("Error: 没有找到文件或读取文件失败")
return False
else:
self.SavefileName = str( int( time.time() ) ) # 转str类型下面有拼接
imgsize = img_info.size;
width = imgsize[0]
heigth = imgsize[1]
if len( cuttingList ) > 0:
if cuttingList[0] < 0 or cuttingList[1] < 0:
print('输入的要裁剪的宽高不能小于零')
return False
else:
self.Wimg = cuttingList[0]
self.Himg = cuttingList[1]
else:
# 默认按照比例 4:3 来计算
self.Wimg = width * 3 / 4
self.Himg = heigth * 3 / 4
if width and self.Wimg:
_left = abs(width-self.Wimg)/2
if heigth and self.Himg:
_top = abs(heigth-self.Himg)/2
crop_info = ( _left , _top , _left+self.Wimg , _top+self.Himg )
new_img = img_info.crop( crop_info )
if img_info.format is 'JPEG':
fileExt = 'jpg'
else:
fileExt = img_info.format.lower()
fileSave = self.SavefileName + '.' + fileExt
new_img.save(fileSave)
self.SavefilePath = fileSave
def getBseriesPicColorList( self , bseries_id = 0):
_config = cf.config()
if len(_config) <= 0 or bseries_id <= 0:
return False
# 打开数据库连接
db = MySQLdb.connect(_config['host'], _config['user'], _config['pwd'], _config['dbname'], charset=_config['charset'] )
try:
# 使用cursor()方法获取操作游标
cursor = db.cursor()
except InternalError:
print("Error 游标创建有误!")
return False
# 使用execute方法执行SQL语句
getListSQL = "SELECT %s FROM `%s` WHERE id >= %d LIMIT 1" % ( 'sys_count_color' , 'prd_categorysubclass' , bseries_id )
try:
cursor.execute(getListSQL)
except ProgrammingError as err:
print("SQL执行错误:",err)
return False
# 使用 fetchone() 方法获取一条数据
data = cursor.fetchone()
if len(data) <= 0:
return False
new_data = list( data )[0].strip('|').split('|')
color_data = []
for i , j in enumerate(new_data):
param_color = j.split(':')[2]
color_data.append(param_color)
del data , new_data
# 关闭数据库连接
db.close()
return color_data
def ExtractImagesColor( self , bseries_id , option = [] ):
filePath = None
if self.is_cutting:
self.CuttingImageCenter( option ) # 如果裁剪, 调用裁剪图像
if self.SavefilePath is not None:
filePath = self.SavefilePath
else:
filePath = self.filename
else:
filePath = self.filename
try:
image = Image.open(filePath).convert('RGBA')
except IOError as err:
print( "识别颜色图片打开有误!" , err )
return False
#生成缩略图
image.thumbnail((400, 300))
# 车系颜色代码
bseries_color = self.getBseriesPicColorList( bseries_id )
count_color_dict = {} # 定义一个临时字典, 主要是存放识别的颜色信息
qita_dict = {}
max_score = 0
min_count = 0
for count, (r, g, b, a) in image.getcolors(image.size[0] * image.size[1]):
saturation = colorsys.rgb_to_hsv(r/255.0, g/255.0, b/255.0)[1]
y = min(abs(r*2104+g*4130+b*802+4096+131072)>>13,235) # 不清楚啥意思, 网上粘的
y = (y-16.0)/(235-16)
# 忽略高亮色
if y > 0.9:
continue
# 忽略纯黑色
# if a == 0:
# continue
qita_dict[(r,g,b)] = count
score = (saturation+0.1)*count
if score > max_score:
max_score = score
# 处理车系的颜色代码 跟 图片颜色进行对比
if bseries_color:
bseries_color = ['#C3694B','#000000','#544540']; # 測試數據
for bi , bj in enumerate( bseries_color ):
br = int( bj[1:3] , 16 )
bg = int( bj[3:5] , 16 )
bb = int( bj[5:7] , 16 )
if r == br and bg == g and bb == b: # 是否有命中的颜色
count_color_dict[bj] = (r,g,b)
break
elif abs(br-r) < self.rgb_float_int and abs(bg-g) < self.rgb_float_int and abs(bb-b) < self.rgb_float_int:
if count_color_dict.has_key(bj):
if min_count > abs(br-r):
count_color_dict[bj] = (r,g,b)
min_count = abs(br-r)
else:
min_count = abs(br-r)
count_color_dict[bj] = (r,g,b)
break
else:
count_color_dict[bj] = ()
continue
qita_dict = sorted(qita_dict.iteritems(), key=operator.itemgetter(1),reverse=True)
count_color_dict['program'] = qita_dict[0][0]
del qita_dict
return count_color_dict
def __del__( self ):
if os.path.exists(self.SavefilePath): #删除临时文件
os.remove(self.SavefilePath)
else:
pass
ImageObj = ImageColorIdentify('333.jpg'); # 图片原地址
a =ImageObj.ExtractImagesColor(3133);
print(a)