本文主要是介绍人脸姿态对比---挑出最接近的照片,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前言:
我们在拍照时,距离镜头的远近、侧脸程度、俯仰姿态以及环境光照等因素都不尽相同;假如我们刚拍了一张照片,那么,如何在历史照片中,挑选出一张与当前照片最相似的呢?
用途:
本文目的在于挑选出与选定照片最相似的一张照片。、
至于用途,针对不同项目有不同效果,比如:
1.在测肤软件上,可以找出一张历史照片和当前作对比,可以跟踪肌肤的变化情况。
2.应用到拍照上,连续拍n张照片(不宜过多,避免影响分析速度),若是第一张模糊了,则找一张姿态最接近的照片顶替,由此获得较好的用户体验。
基本思想:
既然我们判断人脸姿态的入手点为:距离镜头的远近、侧脸程度、俯仰姿态以及环境光照几个因素,那我们就得想办法去提取这些特征值;本文通过人脸的特征点来计算出前三个特征值,光照则通过手机自带的光强传感器获取。
上面是一个人脸的71点特征点图,想要获取71点的坐标很简单,opencv就有自带的库可以检测特征点,这里不做详细介绍。
def get_distance(files, line, arr):lens = len(line)# 眉角:3-9,左右:12-24 24-18,鼻尖26brow = arr[9][0] - arr[3][0] # 眉角距离left = arr[24][0] - arr[12][0]right = arr[18][0] - arr[24][0]left_right = float('%.2f' %(left/right)) # 左右侧脸距离pitch = float(line[lens - 6]) # 鼻尖俯仰值light = float(line[lens-5]) # 光强值fm = float(line[lens-4]) # fm值
获得了特征点就开始计算特征值了,上面这段代码是用来计算特征值的:
1.眉间距越大,证明离镜头越近,反之越远-------(3-9点的水平距离);
2.左右侧脸的距离,左右内眼角到中间的距离之比------(24-12)/(18-24);
3.鼻尖俯仰值(这里直接给出来了,也可以自己计算,大概就是26-29的比例)
4.光强(通过传感器获得)
5.fm值(也叫清晰度,可以自己找段程序计算)
计算步骤:
首先,有n张图片和n个txt(保存着图片对应的特征点),如下图:
txt格式:
代码1:
import glob
from PIL import Image
import os
import numpy as np
import xlrd
import xlutils.copy
import cv2
import functiondef avg(list1):avg = float(sum(list1)) / len(list1)return avgdef get_light(value, files, point1, point2):im = Image.open(files)pix = im.load()w1 = point1[0]h1 = point1[1]w2 = point2[0]h2 = point2[1]w = int(w2 - w1)h = int(h2 - h1)gray = []new_gray=[]for i in range(w):for j in range(h):RGB = pix[int(w1 + i), int(h1 + j)]gray_value = RGB[0] * 0.3 + RGB[1] * 0.59 + RGB[2] * 0.11gray.append(gray_value)#把最小的20%去掉lens=int(len(gray)*0.8)gray.sort()gray.reverse()for i in range(lens):new_gray.append(gray[lens])light = avg(gray)light = '%.2f' % lightreturn lightdef get_top_bottom_light(arr,files):# 确定光照区域的范围,左上角和右下角的点top_point1_x = (arr[24][0]-(arr[24][0]-arr[62][0])/2)top_point1_y = (arr[24][1]-(arr[62][1]-arr[24][1])/4)top_point2_x = (arr[24][0]+(arr[24][0]-arr[62][0])/2)top_point2_y = (arr[24][1]+(arr[62][1]-arr[24][1])/4)top_point1=(top_point1_x,top_point1_y)top_point2=(top_point2_x,top_point2_y)bottom_point1_x = (arr[25][0]-(arr[24][0]-arr[62][0])/2)bottom_point1_y = (arr[25][1]-(arr[62][1]-arr[24][1])/4)bottom_point2_x = (arr[25][0]+(arr[24][0]-arr[62][0])/2)bottom_point2_y = (arr[25][1]+(arr[62][1]-arr[24][1])/4)bottom_point1=(bottom_point1_x,bottom_point1_y)bottom_point2=(bottom_point2_x,bottom_point2_y)top_light = get_light('top', files, top_point1, top_point2)bottom_light = get_light('bottom', files, bottom_point1, bottom_point2)lights = abs(float(bottom_light) - float(top_light))lights = '%.2f' % lightstable2.write(n, 5, float(lights)) # 左右脸颊光均匀性对比print("上下亮度对比为:", lights)return top_light,bottom_light,top_point1,top_point2,bottom_point1,bottom_point2def get_left_right_light(arr,files):# 确定光照区域的范围,左上角和右下角的点left_point1 = (arr[15][0], arr[60][1])left_point2 = (arr[32][0], arr[64][1])right_point1 = (arr[67][0], arr[65][1])right_point2 = (arr[9][0], arr[67][1])left_light = get_light('left', files, left_point1, left_point2)right_light = get_light('right', files, right_point1, right_point2)lights = abs(float(right_light) - float(left_light))lights = '%.2f' % lightstable2.write(n, 4, float(lights)) # 左右脸颊光均匀性对比print("左右亮度对比为:", lights)return left_light,right_light,left_point1,left_point2,right_point1,right_point2def get_distance(files, line, arr):lens = len(line)# 眉角:3-9,左右:12-24 24-18,鼻尖26brow = arr[9][0] - arr[3][0] # 眉角距离left = arr[24][0] - arr[12][0]right = arr[18][0] - arr[24][0]left_right = float('%.2f' %(left/right)) # 左右侧脸距离pitch = float(line[lens - 6]) # 鼻尖俯仰值light = float(line[lens-5]) # 光强值fm = float(line[lens-4]) # fm值#检查参数,固定在范围内if brow<1000:brow=1000elif brow>1600:brow=1600if pitch<0.7:pitch=0.7elif pitch>1.3:pitch=1.3if light>300:light=300if left_right<0.7:left_right=0.7elif left_right>1.3:left_right=1.3return brow, left_right, pitch, light, fm, left, rightdef get_arr(line):lens = len(line)list2 = []for i in range(lens - 77, lens - 6):line[i] = line[i].strip()line[i] = line[i].strip('[]')line[i] = line[i].split(",")list2.append(line[i])arr = np.array(list2)arr = arr.astype(int)return arr# 打开表格,选中表sheet1
path = 'data2/img/a1.xls'
data = xlrd.open_workbook(path)
ws = xlutils.copy.copy(data)
table2 = ws.get_sheet(0)
n = 0
point_list = []
path_txt = 'data2/img/1/txt/'
files = os.listdir(path_txt)
for file in files:if file.endswith('txt'):n = n + 1f1 = open(path_txt + file, 'r')line = f1.readlines()# txt文件名即为照片名lens = len(line)img = line[lens - 1].strip()files = 'data2/img/1/' + imgarr = get_arr(line) # 把文本特征点坐标,转化为arr,留待后用distance = get_distance(files, line, arr) # 把特征点坐标取出来,计算前后左右俯仰table2.write(n,0,float(distance[0]))table2.write(n,1,float(distance[1]))table2.write(n,2,float(distance[2]))table2.write(n,3,float(distance[3]))table2.write(n,6,float(distance[4]))print("眉角间距离为:",distance[0])print("侧脸值为:",distance[1])print("俯仰值为:",distance[2])print("光强为:",distance[3])print("FM值为:",distance[4])light1=get_left_right_light(arr,files)light2=get_top_bottom_light(arr,files)print("第" + str(n) + "次------计算完毕")# #把计算区域画出来# save_light1='data/rect/light1/'# save_light2='data/rect/light2/'# save2='data/rect/left_right/'# save3='data/rect/71/'# function.draw_face(save_light1,files,light1[0],'left',light1[2],light1[3]) #把左右光亮度区域标记出来# function.draw_face(save_light1,files,light1[1],'right',light1[4],light1[5])# function.draw_face(save_light2,files,light1[0],'top',light2[2],light2[3]) #把光亮度区域标记出来# function.draw_face(save_light2,files,light1[1],'bottom',light2[4],light2[5])# function.draw_eye(save2,files,arr,distance[5],distance[6]) #把眼间距标记出来# function.draw_point(save3,files,line,arr) #把71点标记出来ws.save(path)
计算每张图片的特征值
把计算结果存在一个表格中
代码2:
把每一张照片的特征值,和当前的照片作对比(或者选取中位数),并建立罚分制度,挑出罚分最小的一张,即是最接近当前照片。
import xlrd
import xlutils.copy
import os
import numpy as npdef avg(num):average = float(sum(num)) / len(num)return averagedef get_max(a, b):if a > b:return aelse:return bdef get_proportion1(row3,proportion1,x,y):old_list = []list_score = []for j in range(1, row3-1): # row3-1是为了把最后一次的数据排除在外score = table3.cell_value(j, 6)old_list.append(float(score))list_score.append(float(score))list_score.sort()print(old_list)for i in range(x):a = list_score[i]n = old_list.index(a) + 1print("第" + str(n) + "张照片的占比为:" + proportion1[y][i+1])last_value=table3.cell_value(row3-1,6)print('当前照片总罚分为:',last_value,'得分占比为:',proportion1[y][0])def get_proportion2(row3,proportion2,x,y):#1.遍历数据,填入数列,排序old_list = []list_score = []for j in range(1, row3 - 1): # row3-1是为了把最后一次的数据排除在外score = table3.cell_value(j, 7)old_list.append(float(score))list_score.append(float(score))list_score.sort()#2.选出前五,放入数列list1=[]indexs=[]for i in range(x):a = list_score[i] #遍历前五个数index1 = old_list.index(a) + 1 #找出前五个数在原数列中的位置list1.append(a)indexs.append(index1)#3.把最后一位数放入前五的数列,得到index2,选定第几套方案last_value=float(table3.cell_value(row3-1,7))list1.append(last_value)list1.sort()index2=list1.index(last_value) #最后一张照片放进前五个数之后的位置plan=proportion2[y][index2] #选定第n套方案print(list1,last_value)print('选用第'+str(y+1)+'组,第'+str(index2+1)+'套方案:',plan)print('当前照片占比为:',plan[0])for j in range(x):print('第'+str(indexs[j])+'张照片占比为:',plan[j+1])def choose_plan1(row3,proportion1):if (row3-2)>=5:get_proportion1(row3,proportion1,5,0)elif (row3-2)==4:get_proportion1(row3,proportion1,4,1)elif (row3-2)==3:get_proportion1(row3,proportion1,3,2)elif (row3-2)==2:get_proportion1(row3,proportion1,2,3)elif (row3-2)==1:get_proportion1(row3,proportion1,1,4)elif (row3-2)==0:get_proportion1(row3,proportion1,0,5)def choose_plan2(row3,proportion1):if (row3-2)>=5:get_proportion2(row3,proportion2,5,0)elif (row3-2)==4:get_proportion2(row3,proportion2,4,1)elif (row3-2)==3:get_proportion2(row3,proportion2,3,2)elif (row3-2)==2:get_proportion2(row3,proportion2,2,3)elif (row3-2)==1:get_proportion2(row3,proportion2,1,4)elif (row3-2)==0:get_proportion2(row3,proportion2,0,5)# 计算sheet3的和,得到总分
def get_sum(row1, n):for i in range(1, row1):sums = 0for j in range(7):temp4 = float(table3.cell_value(i, j))sums += temp4makeup_code=table3.cell_value(i, 8) #检查是否化妆,化妆则扣100分if makeup_code==1:sums=100table3_w.write(i, n, "%.2LF" % sums)print("第" + str(i) + "张图片,综合差异为:", sums)def get_fm(row1, n, min, max, weight):for j in range(1, row1):fm = table1.cell_value(j, 6)if fm >= max:score = 0else:score = weight * (1 - (fm / max))score = "%.2LF" % scoretable3_w.write(j, n, score)# print(fm)# 计算得分
def get_score(row1, n, min, max, weight):median = float(table2.cell_value(n + 1, 7))a = median - minb = max - medianmax_num = float("%.2LF" % get_max(a, b))for j in range(1, row1):temp1 = float(table1.cell_value(j, n))temp3 = abs(temp1 - median)if temp3 >= max_num:score = weightelse:score = (temp3 / max_num) * weightscore = "%.2LF" % scoretable3_w.write(j, n, score)print(score)# 计算sheet1中6列指标的中位数
def get_median(row1):for i in range(7):lists = []for j in range(1, row1):col_value = table1.cell_value(j, i)lists.append(col_value)lists.sort()median="%.2LF" %(np.median(lists))table2_w.write(i + 1, 7, float(median))# print(median)# 打开表格,选中表sheet1
path = 'data2/img/a1.xls'
data = xlrd.open_workbook(path)
ws = xlutils.copy.copy(data)
table1_w = ws.get_sheet(0)
table2_w = ws.get_sheet(1)
table3_w = ws.get_sheet(2)
table1 = data.sheets()[0]
table2 = data.sheets()[1]
table3 = data.sheets()[2]
row1 = table1.nrows
row2 = table2.nrows
row3 = table3.nrows
proportion1 = [['30%','18%','16%','14%','12%','10%'],['30%','25%','20%','15%','10%'],
['40%','30%','20%','10%'],['40%','35%','25%'],['50%','50%'],['100%']]proportion2=[
[['70%','10%','8%','6%','4%','2%'],['60%','12%','10%','8%','6%','4%'],['50%','14%','12%','10%','8%','6%'],
['40%','16%','14%','12%','10%','8%'],['30%','18%','16%','14%','12%','10%'],['20%','20%','18%','16%','14%','12%']],[['70%','10%','8%','7%','5%'],['60%','13%','11%','9%','7%'],['50%','15%','13%','12%','10%'],
['40%','18%','16%','14%','12%'],['32%','20%','18%','16%','14%']],[['60%','16%','14%','10%'],['50%','22%','17%','11%'],['40%','25%','22%','13%'],['30%','30%','25%','15%']],[['60%','25%','15%'],['50%','30%','20%'],['40%','35%','25%']],[['60%','40%'],['40%','60%']],[['100%']]
]# get_median(row1) #计算sheet1每一列指标的均值
# get_score(row1,0,1000,1600,20) #1.远近距离得分
# get_score(row1,1,0.7,1.3,10) #2.侧脸得分
# get_score(row1,2,0.7,1.3,20) #3.俯仰得分
# get_score(row1,3,0,300,10) #4.光强得分
# get_score(row1,4,0,100,15) #5.左右亮度差得分
# get_score(row1,5,0,20,5) #6.上下亮度差得分
# get_fm(row1,6,0,80,20) #7.清晰度得分
# get_sum(row1,7) #求得分总和,得到综合差异
# choose_plan2(row3,proportion2) #选用评分占比方案ws.save(path)# getget_score(总行数,第几列,min,max,分值权重)
# 1.远近 min:1000 max:1600,与均值最大偏差:min-avg or max-avg
# 2.侧脸 min:0.7 max:120,与均值最大偏差:min-avg or max-avg
# 3.俯仰 min:0.7 max:1.3,与均值最大偏差:min-avg or max-avg
# 4.光强 min:10 max:300,与均值最大偏差:min-avg or max-avg
# 5.左右亮度差 min:0 max:100,与均值最大偏差:min-avg or max-avg
# 6.清晰度80以上算满分#评分方案2:
#用了6套评分参数,根据当前照片的综合分数排名,来选定用第几套评分参数;
#例如:当前分数排在第5,则选用第五套评分参数
代码3:存放函数的文件—function.py
import glob
from PIL import Image
import os
import numpy as np
import xlrd
import xlutils.copy
import cv2
import math
import time#计算数据
def avg(num):average = float(sum(num)) / len(num)return averagedef get_max(a, b):if a > b:return aelse:return bdef get_finally_score(old_data,proportion,now_score,x):finally_score=[]for i in range(9):sums=0for j in range(x):index=proportion[0][j] #每张照片的排名pro=proportion[1][j] #每张照片所占的比例score=old_data[index][1] #取得index行的一行分数new_score=[(num*pro)/100 for num in score] #经过比例相乘后的分数a=new_score[i]sums+=asums = float("%.2LF" % sums) #历史照片分数score=float("%.2LF" %((now_score[i]*proportion[1][x])/100)) #当前照片分数score_sum=round(sums+score) #四舍五入取整法# score_sum=float("%.2LF" %(sums+score)) #保留两位小数finally_score.append(score_sum)return finally_scoredef get_proportion1(score_sum,rows,proportion1,x,y):new_list = []for i in range(rows):new_list.append(score_sum[i])new_list.sort()proportion=[[],[]]for i in range(x):a = new_list[i]n = score_sum.index(a)proportion[0].append(n) #最低5次罚分,在历史中的位置proportion[1].append(proportion1[y][i+1]) #5张照片分别对应的占比proportion[1].append(proportion1[y][0]) #当次照片所占比例return proportion,xdef choose_plan1(score_sum,rows,proportion1):if (rows)>=5:proportion=get_proportion1(score_sum,rows,proportion1,5,0)elif (rows)==4:proportion=get_proportion1(score_sum,rows,proportion1,4,1)elif (rows)==3:proportion=get_proportion1(score_sum,rows,proportion1,3,2)elif (rows)==2:proportion=get_proportion1(score_sum,rows,proportion1,2,3)elif (rows)==1:proportion=get_proportion1(score_sum,rows,proportion1,1,4)elif (rows)==0:proportion=get_proportion1(score_sum,rows,proportion1,0,5)return proportion[0],proportion[1]# 计算sheet3的和,得到总分
def get_sum(score_all,rows,n):score_sum=[]for i in range(rows):sums = 0for j in range(n):temp = score_all[j][i]sums += tempsums = float("%.2LF" % sums)score_sum.append(sums)return score_sumdef get_fm(old_data,rows, n, min, max, weight):scores=[]for i in range(rows):fm=old_data[i][0][n] #历史数据中,i行n列的值if fm >= max:score = 0else:score = weight * (1 - (fm / max))score = float("%.2LF" % score)scores.append(score)return scores# 计算得分
def get_score(old_data,rows,median_list,n,min,max,weight):median=median_list[n]a = median - minb = max - medianmax_num = float("%.2LF" % get_max(a, b))scores=[]for i in range(rows):col_value=old_data[i][0][n] #历史数据中,i行n列的值result = abs(col_value - median)if result >= max_num:score = weightelse:score = (result / max_num) * weightscore = float("%.2LF" % score)scores.append(score)return scores# 计算sheet1中6列指标的中位数
def get_median(old_data,rows):median_list=[]for i in range(7):lists = []for j in range(rows):col_value = old_data[j][0][i]lists.append(col_value)lists.sort()median=float("%.2LF" %(np.median(lists)))median_list.append(median)return median_listdef get_light(files, point1, point2):im = Image.open(files)pix = im.load()w1 = point1[0]h1 = point1[1]w2 = point2[0]h2 = point2[1]w = int(w2 - w1)h = int(h2 - h1)gray = []new_gray=[]for i in range(w):for j in range(h):RGB = pix[int(w1 + i), int(h1 + j)]gray_value = RGB[0] * 0.3 + RGB[1] * 0.59 + RGB[2] * 0.11gray.append(gray_value)#把最小的20%去掉lens=int(len(gray)*0.8)gray.sort()gray.reverse()for i in range(lens):new_gray.append(gray[lens])light = avg(gray)light = float('%.2f' % light)return lightdef get_top_bottom_light(point,files):# 确定光照区域的范围,左上角和右下角的点top_point1_x = (point[24][0]-(point[24][0]-point[62][0])/2)top_point1_y = (point[24][1]-(point[62][1]-point[24][1])/4)-100top_point2_x = (point[24][0]+(point[24][0]-point[62][0])/2)top_point2_y = (point[24][1]+(point[62][1]-point[24][1])/4)-100top_point1=(top_point1_x,top_point1_y)top_point2=(top_point2_x,top_point2_y)bottom_point1_x = (point[25][0]-(point[24][0]-point[62][0])/2)bottom_point1_y = (point[25][1]-(point[62][1]-point[24][1])/4)bottom_point2_x = (point[25][0]+(point[24][0]-point[62][0])/2)bottom_point2_y = (point[25][1]+(point[62][1]-point[24][1])/4)bottom_point1=(bottom_point1_x,bottom_point1_y)bottom_point2=(bottom_point2_x,bottom_point2_y)top_light = get_light(files, top_point1, top_point2)bottom_light = get_light(files, bottom_point1, bottom_point2)lights = abs(float(bottom_light) - float(top_light))lights = float('%.2f' % lights)return lights,top_light,bottom_light,top_point1,top_point2,bottom_point1,bottom_point2def get_left_right_light(point,files):# 确定光照区域的范围,左上角和右下角的点left_point1 = (point[15][0], point[60][1])left_point2 = (point[32][0], point[64][1])right_point1 = (point[67][0], point[65][1])right_point2 = (point[9][0], point[67][1])left_light = get_light(files, left_point1, left_point2) #计算左脸亮度right_light = get_light(files, right_point1, right_point2) #计算右脸亮度lights = abs(float(right_light) - float(left_light))lights = float('%.2f' % lights)return lights,left_light,right_light,left_point1,left_point2,right_point1,right_point2def get_distance(point,data1):# 眉角:3-9,左右:12-24 24-18,鼻尖26brow = point[9][0] - point[3][0] # 眉角距离left = point[24][0] - point[12][0]right = point[18][0] - point[24][0]left_right = float('%.2f' %(left/right)) # 左右侧脸距离light = float(data1[1]) # 光强pitch = float(data1[2]) # 鼻尖俯仰值fm = float(data1[3]) # fm值#检查参数,固定在范围内if brow<1000:brow=1000elif brow>1600:brow=1600if pitch<0.7:pitch=0.7elif pitch>1.3:pitch=1.3if light>300:light=300if left_right<0.7:left_right=0.7elif left_right>1.3:left_right=1.3return brow, left_right, pitch, light, fm, left, rightdef get_old_data(now_makeup_code, now_mode, history_data):data1 = []for data in history_data:old_makeup_code = data[2] # 历史数据化妆状态old_mode=data[4]old_time = data[3] # 历史数据时间now_time = int(time.time()) # 当前时间times = now_time - old_time # 时间间隔if old_makeup_code == now_makeup_code and times <= 15768000 and old_mode==now_mode:data1.append(data)old_data = []lens = len(data1)# 若是历史数据超过100,则挑出最后100条数据if lens > 100:for i in range(lens - 100, lens):old_data.append(data1[i])else:old_data = data1return old_datadef get_data():#now_data=[[71点],[文件名,光强,俯仰值,清晰度,是否化妆],[单项+总得分]]point=[[1267,1443], [1085,1386],[895,1383], [727,1452], [873,1289], [1102,1295], [1570,1380], [1722,1237], [1948,1198], [2149,1364], [1953,1292], [1769,1325], [1234,1691], [1104,1702], [989,1705], [862,1680], [989,1609], [1124,1617], [1694,1642], [1791,1551], [1926,1521], [2063,1573], [1939,1617], [1818,1634], [1457,1592], [1465,1835], [1476,2080], [1730,2251], [1628,2209], [1493,2278], [1350,2220], [1262,2276], [1198,2623], [1278,2537], [1394,2480], [1482,2507], [1573,2471], [1730,2518], [1865,2595], [1785,2705],[1658,2796], [1512,2829], [1380,2807], [1270,2730], [1352,2626], [1507,2648], [1686,2615], [2347,1521], [2358,1799], [2333,2066], [2278,2347], [2174,2595], [2033,2816], [1840,3031], [1589,3127], [1333,3066], [1129,2879], [958,2672], [829,2444], [730,2168], [669,1909], [642,1628], [1284,1953],[1212,2096], [1223,2254], [1705,1934], [1793,2072], [1804,2229], [1493,2551], [1636,2595], [1375,2609]]now_Torch=['1550545615850__Torch_0_fm490.75.jpg',43.8,0.89,490.75,0,'Torch',[84,82,86,92,88,80,80,26,86]]now_Flash=['1550545635453__Flash_0_fm395.55.jpg',43.8,0.89,490.75,0,'Flash',[84,82,86,92,88,80,80,26,87]]data1=[point,now_Torch,now_Flash]#old_data=[眉间距,左右侧脸,俯仰值,清晰度fm,光强,左右亮度,上下亮度,[单项+总得分]]data2=[[[1422,0.94,0.89,43.8,4.06,2.67,223.45],[86,83,86,90,87,80,81,25,88],1,1550733026,'Torch'],[[1353,0.99,0.88,43.4,12.9,1.12,172.08],[85,92,86,82,82,84,83,25,87],0,1536753026,'Flash'],[[1304,0.97,0.81,42.6,2.83,4.38,206.11],[83,82,86,90,87,80,82,26,85],1,1529733326,'Flash'],[[1284,1.12,0.83,42.9,4.81,6.10,182.05],[84,82,86,92,88,80,80,26,86],0,1537733029,'Torch'],[[1395,0.79,0.85,43.8,0.18,2.10,235.35],[83,82,76,92,88,90,80,26,86],0,1538723026,'Torch'],[[1259,0.79,0.91,42.6,6.80,5.29,228.56],[88,82,86,92,83,80,80,26,87],0,1539753026,'Torch'],[[1171,0.96,0.91,42.7,1.86,6.72,242.07],[83,82,82,82,88,80,80,26,83],0,1539833056,'Torch'],[[1373,0.78,1.30,49.6,9.07,7.19,131.54],[84,82,81,82,88,84,80,26,84],0,1541733026,'Torch'],[[1328,0.86,0.82,49.9,7.12,5.70,171.93],[84,85,85,92,88,80,82,26,86],0,1545733026,'Torch'],[[1353,1.14,0.82,51.6,25.5,8.11,203.08],[86,82,86,90,88,80,83,26,87],0,1541733026,'Torch']]proportion1 = [[30,18,16,14,12,10],[30,25,20,15,10],[40,30,20,10],[40,35,25],[50,50],[100]]return data1,data2,proportion1#1.把关键点画出来-------------------------------
def draw_point(save,files,point):#画出点的位置img = cv2.imread(files)for i in range(70): cv2.circle(img,(point[i][0],point[i][1]),5,(0,255,0),-1)#保存图片file_name=os.path.split(files)[1]cv2.imwrite(save+file_name, img)def draw_eye(save,files,point,left,right):#画出眼间距 点的位置img = cv2.imread(files)cv2.circle(img,(point[3][0],point[3][1]),5,(0,255,0),-1)cv2.circle(img,(point[9][0],point[9][1]),5,(0,255,0),-1)cv2.circle(img,(point[12][0],point[12][1]),5,(0,255,0),-1)cv2.circle(img,(point[18][0],point[18][1]),5,(0,255,0),-1)cv2.circle(img,(point[24][0],point[24][1]),5,(0,255,0),-1)#画线、标距离数值cv2.line(img,(point[12][0],point[12][1]),(point[24][0],point[24][1]),(255,255,255),3)cv2.line(img,(point[18][0],point[18][1]),(point[24][0],point[24][1]),(255,255,255),3)font=cv2.FONT_HERSHEY_SIMPLEXcv2.putText(img,str(left),(point[12][0],point[12][1]), font, 2,(255,252,255),2)cv2.putText(img,str(right),(point[18][0],point[18][1]), font, 2,(255,252,255),2)#保存图片file_name=os.path.split(files)[1]cv2.imwrite(save+file_name, img)def draw_light_roi(save_path,files,light1,light2,point1,point2,point3,point4):w1=point1[0]h1=point1[1]w2=point2[0]h2=point2[1]w3=point3[0]h3=point3[1]w4=point4[0]h4=point4[1]#画出光照区域的框img=cv2.imread(files)cv2.rectangle(img,(int(w1),int(h1)),(int(w2),int(h2)),(255,0,0),3)cv2.rectangle(img,(int(w3),int(h3)),(int(w4),int(h4)),(255,0,0),3)dst = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#把亮度数值标上去font=cv2.FONT_HERSHEY_SIMPLEXcv2.putText(img,light1,(int(w1+10),int(h1+10)), font, 2,(255,252,255),3)cv2.putText(img,light2,(int(w3+10),int(h3+10)), font, 2,(255,252,255),3)#保存图片file_name=os.path.split(files)[1]cv2.imwrite(save_path+file_name+'.jpg', img)
总结:
1.代码1是用来计算每张照片的特征值的,并放入表格存放起来;
2.代码2是把表格中的特征值拿出来进行比较,并建立了罚分制度(差别越大,罚分越多),最后挑出罚分最小的一张,获得最接近的照片。
3.代码3是前面两个的函数存放文件。
ps:代码2中的比较对象,可以选当前拍照那张(得到当前对比),也可以选所有照片罚分的中位数(得到拍照习惯),根据需要而定。
留尾:
这个文件是当时用来做评分测试的,忘记用法了,也一并先放上来吧
import xlrd
import xlutils.copy
import os
import sys
import numpy as np
import mathdef get_avg(num):average = float(sum(num)) / len(num)return averagedef get_max(a, b):if a > b:return aelse:return bdef get_proportion1(row3,proportion1,x,y):old_list = []list_score = []for j in range(1, row3-1): # row3-1是为了把最后一次的数据排除在外score = table3.cell_value(j, 7)old_list.append(float(score))list_score.append(float(score))list_score.sort()# print(old_list)score1=0for i in range(x):a = list_score[i]n = old_list.index(a) + 1# print("第" + str(n) + "张照片的占比为:" + str(proportion1[y][i+1]))s=table3.cell_value(n,8)*((proportion1[y][i+1])/100)score1=score1+slast_value=table3.cell_value(row3-1,7)# print('当前照片总罚分为:',last_value,',得分占比为:',proportion1[y][0])score2=table3.cell_value(row3-1,8)*(proportion1[y][0]/100)scores="%.2LF" %(score1+score2)return scores,proportion1[y][0]def get_proportion2(row3,proportion2,x,y):#1.遍历数据,填入数列,排序old_list = []list_score = []for j in range(1, row3 - 1): # row3-1是为了把最后一次的数据排除在外score = table3.cell_value(j, 7)old_list.append(float(score))list_score.append(float(score))list_score.sort()#2.选出前五,放入数列list1=[]indexs=[]for i in range(x):a = list_score[i] #遍历前五个数index1 = old_list.index(a) + 1 #找出前五个数在原数列中的位置list1.append(a)indexs.append(index1)#3.把最后一位数放入前五的数列,得到index2,选定第几套方案last_value=float(table3.cell_value(row3-1,7))list1.append(last_value)list1.sort()index2=list1.index(last_value) #最后一张照片放进前五个数之后的位置plan=proportion2[y][index2] #选定第n套方案score1=0# print(list1,last_value)# print('选用第'+str(y+1)+'组,第'+str(index2+1)+'套方案:',plan)# print('当前照片占比为:',str(plan[0])+'%')for j in range(x):# print('第'+str(indexs[j])+'张照片占比为:',str(plan[j+1])+'%')a=table3.cell_value(indexs[j]+1,8)*float((plan[j+1])/100)score1=score1+ascore2=table3.cell_value(row3-1,8)*float((plan[0])/100)scores="%.2LF" %(score1+score2)return scores,plan[0]def choose_plan1(row3,proportion1):if (row3-2)>=5:a=get_proportion1(row3,proportion1,5,0)elif (row3-2)==4:a=get_proportion1(row3,proportion1,4,1)elif (row3-2)==3:a=get_proportion1(row3,proportion1,3,2)elif (row3-2)==2:a=get_proportion1(row3,proportion1,2,3)elif (row3-2)==1:a=get_proportion1(row3,proportion1,1,4)elif (row3-2)==0:a=get_proportion1(row3,proportion1,0,5)return adef choose_plan2(row3,proportion1):if (row3-2)>=5:a=get_proportion2(row3,proportion2,5,0)elif (row3-2)==4:a=get_proportion2(row3,proportion2,4,1)elif (row3-2)==3:a=get_proportion2(row3,proportion2,3,2)elif (row3-2)==2:a=get_proportion2(row3,proportion2,2,3)elif (row3-2)==1:a=get_proportion2(row3,proportion2,1,4)elif (row3-2)==0:a=get_proportion2(row3,proportion2,0,5)return adef var(lst):var1=0avg=get_avg(lst)for i in lst:var1+=float((i-avg)**2*1.0)var2=(math.sqrt(var1/(len(lst)-1)*1.0))return var2# 计算sheet3的和,得到总分
def get_sum(row3, n):a=[]for i in range(1, row3):sums = 0for j in range(6):temp4 = float(table3.cell_value(i, j))sums += temp4table3_w.write(i, n, "%.2LF" % sums)print("第" + str(i) + "张图片,综合差异为:", sums)# a.append(sums)# vars=var(a)# print('方差为:',vars)def get_fm(row1, n, min, max, weight):for j in range(1, row1):fm = table1.cell_value(j, 6)if fm >= max:score = 0else:score = weight * (1 - (fm / max))score = "%.2LF" % scoretable3_w.write(j, n, score)# print(fm)# 计算得分
def get_score(row1, n, min, max, weight):median = float(table2.cell_value(n + 1, 7))a = median - minb = max - medianmax_num = float("%.2LF" % get_max(a, b))for j in range(1, row1):temp1 = float(table1.cell_value(j, n))temp3 = abs(temp1 - median)if temp3 >= max_num:score = weightelse:score = (temp3 / max_num) * weightscore = "%.2LF" % scoretable3_w.write(j, n, score)# print(score)# 计算sheet1中6列指标的中位数
def get_median(row1):for i in range(7):lists = []for j in range(1, row1):col_value = table1.cell_value(j, i)lists.append(col_value)lists.sort()median="%.2LF" %(np.median(lists))table2_w.write(i + 1, 7, float(median))# print(median)# 打开表格,选中表sheet1
path = 'data/score_test/a1.xls'
data = xlrd.open_workbook(path)
ws = xlutils.copy.copy(data)
table1_w = ws.get_sheet(0)
table2_w = ws.get_sheet(1)
table3_w = ws.get_sheet(2)
table1 = data.sheets()[0]
table2 = data.sheets()[1]
table3 = data.sheets()[2]
row1 = table1.nrows
row2 = table2.nrows
row3 = table3.nrows
proportion1 = [[30,18,16,14,12,10],[30,25,20,15,10],
[40,30,20,10],[40,35,25],[50,50],[100]]proportion2=[
[[70,10,8,6,4,2],[60,12,10,8,6,4],[50,14,12,10,8,6],
[40,16,14,12,10,8],[30,18,16,14,12,10],[20,20,18,16,14,12]],[[70,10,8,7,5],[60,13,11,9,7],[50,15,13,12,10],
[40,18,16,14,12],[32,20,18,16,14]],[[60,16,14,10],[50,22,17,11],[40,25,22,13],[30,30,25,15]],[[60,25,15],[50,30,20],[40,35,25]],[[60,40],[40,60]],[[100]]
]# get_median(row1) #计算sheet1每一列指标的均值
# get_score(row1,0,1000,1600,20) #1.远近距离得分
# get_score(row1,1,0.7,1.3,10) #2.侧脸得分
# get_score(row1,2,0.7,1.3,20) #3.俯仰得分
# get_score(row1,3,0,300,10) #4.光强得分
# get_score(row1,4,0,100,10) #5.左右亮度差得分
# get_score(row1,5,0,20,10) #6.上下亮度差得分
# get_fm(row1,6,0,80,20) #7.清晰度得分
# get_sum(row3,7) #求得分总和,得到综合差异# for i in range(10):
# gg=choose_plan1(row3-i,proportion1) #选用评分占比方案
# print(str(gg[1])+' '+str(gg[0]))ws.save(path)# getget_score(总行数,第几列,min,max,分值权重)
# 1.远近 min:1000 max:1600,与均值最大偏差:min-avg or max-avg
# 2.侧脸 min:0 max:120,与均值最大偏差:min-avg or max-avg
# 3.俯仰 min:0.8 max:1.3,与均值最大偏差:min-avg or max-avg
# 4.光强 min:10 max:300,与均值最大偏差:min-avg or max-avg
# 5.左右亮度差 min:0 max:100,与均值最大偏差:min-avg or max-avg
# 6.清晰度80以上算满分#评分方案2:
#用了6套评分参数,根据当前照片的综合分数排名,来选定用第几套评分参数;
#例如:当前分数排在第5,则选用第五套评分参数
这篇关于人脸姿态对比---挑出最接近的照片的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!