人脸姿态对比---挑出最接近的照片

2023-11-02 03:59

本文主要是介绍人脸姿态对比---挑出最接近的照片,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言:

        我们在拍照时,距离镜头的远近、侧脸程度、俯仰姿态以及环境光照等因素都不尽相同;假如我们刚拍了一张照片,那么,如何在历史照片中,挑选出一张与当前照片最相似的呢?

用途:

本文目的在于挑选出与选定照片最相似的一张照片。、

至于用途,针对不同项目有不同效果,比如:

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,则选用第五套评分参数

这篇关于人脸姿态对比---挑出最接近的照片的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/327957

相关文章

锐捷和腾达哪个好? 两个品牌路由器对比分析

《锐捷和腾达哪个好?两个品牌路由器对比分析》在选择路由器时,Tenda和锐捷都是备受关注的品牌,各自有独特的产品特点和市场定位,选择哪个品牌的路由器更合适,实际上取决于你的具体需求和使用场景,我们从... 在选购路由器时,锐捷和腾达都是市场上备受关注的品牌,但它们的定位和特点却有所不同。锐捷更偏向企业级和专

什么是 Ubuntu LTS?Ubuntu LTS和普通版本区别对比

《什么是UbuntuLTS?UbuntuLTS和普通版本区别对比》UbuntuLTS是Ubuntu操作系统的一个特殊版本,旨在提供更长时间的支持和稳定性,与常规的Ubuntu版本相比,LTS版... 如果你正打算安装 Ubuntu 系统,可能会被「LTS 版本」和「普通版本」给搞得一头雾水吧?尤其是对于刚入

TP-LINK/水星和hasivo交换机怎么选? 三款网管交换机系统功能对比

《TP-LINK/水星和hasivo交换机怎么选?三款网管交换机系统功能对比》今天选了三款都是”8+1″的2.5G网管交换机,分别是TP-LINK水星和hasivo交换机,该怎么选呢?这些交换机功... TP-LINK、水星和hasivo这三台交换机都是”8+1″的2.5G网管交换机,我手里的China编程has

免费也能高质量!2024年免费录屏软件深度对比评测

我公司因为客户覆盖面广的原因经常会开远程会议,有时候说的内容比较广需要引用多份的数据,我记录起来有一定难度,所以一般都用录屏工具来记录会议内容。这次我们来一起探索有什么免费录屏工具可以提高我们的工作效率吧。 1.福晰录屏大师 链接直达:https://www.foxitsoftware.cn/REC/  录屏软件录屏功能就是本职,这款录屏工具在录屏模式上提供了多种选项,可以选择屏幕录制、窗口

类的load方法和initialize方法对比

1. load方法在main()之前被调用,而initialize方法在main()之后调用 load方法实际是在load_images过程中被调用的。load_images会将当前应用依赖的所有镜像(动态库)加载到内存,在在加载中首先是对镜像进行扫描,将所有包含 load 方法的类加入列表 loadable_classes ,然后从这个列表中逐一调用其所包含的 load 方法。 +[XXCl

JavaScript正则表达式六大利器:`test`、`exec`、`match`、`matchAll`、`search`与`replace`详解及对比

在JavaScript中,正则表达式(Regular Expression)是一种用于文本搜索、替换、匹配和验证的强大工具。本文将深入解析与正则表达式相关的几个主要执行方法:test、exec、match、matchAll、search和replace,并对它们进行对比,帮助开发者更好地理解这些方法的使用场景和差异。 正则表达式基础 在深入解析方法之前,先简要回顾一下正则表达式的基础知识。正则

【HarmonyOS】-TaskPool和Worker的对比实践

ArkTS提供了TaskPool与Worker两种多线程并发方案,下面我们将从其工作原理、使用效果对比两种方案的差异,进而选择适用于ArkTS图片编辑场景的并发方案。 TaskPool与Worker工作原理 TaskPool与Worker两种多线程并发能力均是基于 Actor并发模型实现的。Worker主、子线程通过收发消息进行通信;TaskPool基于Worker做了更多场景化的功能封装,例

一些数学经验总结——关于将原一元二次函数增加一些限制条件后最优结果的对比(主要针对公平关切相关的建模)

1.没有分段的情况 原函数为一元二次凹函数(开口向下),如下: 因为要使得其存在正解,必须满足,那么。 上述函数的最优结果为:,。 对应的mathematica代码如下: Clear["Global`*"]f0[x_, a_, b_, c_, d_] := (a*x - b)*(d - c*x);(*(b c+a d)/(2 a c)*)Maximize[{f0[x, a, b,

Windows11电脑上自带的画图软件修改照片大小(不裁剪尺寸的情况下)

针对一张图片,有时候上传的图片有大小限制,那么在这种情况下如何修改其大小呢,在不裁剪尺寸的情况下 步骤如下: 1.选定一张图片,右击->打开方式->画图,如下: 第二步:打开图片后,我们可以看到图片的大小为82.1kb,点击上面工具栏的“重设大小和倾斜”进行调整,如下: 第三步:修改水平和垂直的数字,此处我修改为分别都修改为50,然后保存,可以看到大小变成63.5kb,如下:

想要从OPPO手机恢复数据?免费OPPO照片视频恢复软件

此实用程序可帮助那些寻找以下内容的用户: 在OPPO手机中格式化存储卡后可以恢复图片吗?我删除了 OPPO上的视频和图片,我感觉很糟糕,因为里面有我在拉斯维加斯拍摄的视频和照片 免费OPPO照片视频恢复软件 您能恢复OPPO上已删除的照片吗?我不小心格式化了OPPO SD 卡,有希望恢复已删除的照片吗? 救命!我在清理时删除了我的照片,我的问题是是否有任何免费软件可以从OPPO中恢复已