关于色彩还原能力的计算

色彩还原是指某设备(手机、相机)对于色彩的还原能力,拍出来的图片越接近真实颜色,表示还原能力越好。
根据这个指标,我们可以对设备在色彩方面的能力得到一个评判标准;同时,我们也可以相机或者显示器上面进行色偏的检验和校准(目前就有相机是实用24色卡进行颜色校准的)。
在这里插入图片描述

下面先介绍下色彩还原的计算公式:
ΔC = ( (a -a*)2+ (b - b*)2 )1/2
ΔE = ( (L -L*)2+ (a -a*)2+ (b - b*)2 )1/2
Saturation = 100% ×((a 2 + b 2)1/2 ) / ((a2 + b2)1/2 )
其中L、a、b为经过拍照系统处理后的值,L*、a*、b为Color Checker的理想值;
L
、a*、b*的标准为:
本文只计算接近肤色的8块:
[(37.986,13.555,14.059),(65.711,18.13,17.81),(62.661,36.067,57.096),(71.941,19.363,67.857),(96.539,-0.425,1.186),(81.257,-0.683,-0.335),(66.766,-0.734,-0.504),(50.867,-0.153,-0.25)]

在这里插入图片描述

具体步骤:
1.在标准环境下拍摄24色色卡;
2.把整张色卡裁剪成24个色块;
3.对每一张图片的相关色块进行计算,得到ΔC、ΔE、S的值。

代码1:把色卡裁剪成方块

import colorsys
from PIL import Image
import os


for n in range(1,25):
    #创建新文件夹,一张原图创建一个文件夹
    def mkdir(path):
        folder=os.path.exists(path)
        if not folder:
          os.makedirs(path)
          print("new folder")
        else:
          print("ok")

    folders='cl/face/img'+str(n)
    mkdir(folders)

path='color/face/'
files=os.listdir(path)
for n in range(24):
    file=files[n]
    im = Image.open(path+file)
    # 图片的宽度和高度
    img_size = im.size
    print(file)

    #图片需要分割成4行,6列
    #则每张图片的宽x为:总宽度/6,高y为:总高度/4
    xx = 6
    yy = 4
    x = img_size[0] // xx
    y = img_size[1] // yy

    #横向切割,先切第一行6块,再切第26块······
    for j in range(yy):
        for i in range(xx):
            left = i*x
            up = y*j
            right = left + x
            low = up + y
            region = im.crop((left+100,up+120,right-150,low-100))
            # print("坐标为:",(left,up,right,low))

    # #保存切割好的图片,并且按j-i(第几行,第几列)的方式来命名
            temp = str(j+1)+'-'+str(i+1)
            region.save('cl/face/img'+str(n+1)+'/'+temp+".jpg")
            cc='img'+str(n+1)+'/'+temp+".jpg"
            print("文件名为:",cc)

运行之后,将得到24个小方块,对应的24色色卡的颜色

代码2:计算各个方块与理想值的ΔC、ΔE、S
由于图片不能直接转换成lab值,因此需要经过计算来转换

import colorsys
from PIL import Image
import numpy
import os
#此函数为设计公式,用于计算CE、Sat的值
def result(L,a,b):
    #把标准的Lab值单独提取出来
    L1=Lab_value[file_num-1][0]
    # L1="%.2LF"%L1
    a1=Lab_value[file_num-1][1]
    b1=Lab_value[file_num-1][2]



    #按公式计算CES的值,得出结果
    x=numpy.square(a-a1)   #(a -a*)2
    y=numpy.square(b-b1)   #(b - b*)2
    z=numpy.square(L-L1)   #(L -L*)2
    c=numpy.sqrt(x+y)C =( (a -a*)2+ (b - b*)2 )1/2
    print('C的值为:',"%.2f"%c)

    e=numpy.sqrt(x+y+z)E = ( (L -L*)2+ (a -a*)2+ (b - b*)2 )1/2
    print('E的值为:',"%.2f"%e)

    #Saturation = 100% ×((a 2 + b 2)1/2 ) / ((a*2 + b*2)1/2 )
    x1=numpy.sqrt(numpy.square(a)+numpy.square(b))   #(a 2 + b 2)1/2 
    x2=numpy.sqrt(numpy.square(a1)+numpy.square(b1))
    S=(x1/x2)
    # print('S的值为:',"%.4f"%S)
    print('S的百分比为:',"%.2f%%"%(S*100))  #输出百分比
    print("%.2f"%c,"%.2f"%e,"%.2f%%"%(S*100))
    # print("第"+str(n)+"个文件夹计算结束")
    print('---------------------------------')
    line="%.2f"%c,"%.2f"%e,"%.2f%%"%(S*100)
    # print(line)
    f1.write(line[0]+'  '+line[1]+'  '+line[2]+'\n')


#此函数用于把RGB转换为Lab值
def rgb2lab(R,G,B):
    Xn = 0.950456
    Yn = 1.0
    Zn = 1.088754

    R=R/255.0
    G=G/255.0
    B=B/255.0

    if (R > 0.04045):
        R=pow((R + 0.055) / 1.055, 2.4)
    else:
        R=R / 12.92
    if (G > 0.04045):
        G=pow((G + 0.055) / 1.055, 2.4)
    else:
        G=G / 12.92
    if (B > 0.04045):
        B=pow((B + 0.055) / 1.055, 2.4)
    else:
        B=B / 12.92

    X = 0.412453 * R + 0.357580 * G + 0.180423 * B
    Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
    Z = 0.019334 * R + 0.119193 * G + 0.950227 * B
     
    x = X / Xn
    y = Y / Yn
    z = Z / Zn

    if (y > 0.008856):
        fY = pow(y, 1.0/3.0)
    else:
        fY = 7.787 * y + 16.0/116.0

    if (x > 0.008856):
        fX = pow(x, 1.0/3.0)
    else:
        fX = 7.787*x + 16.0/116.0

    if (z > 0.008856):
        fZ = pow(z, 1.0/3.0)
    else:
        fZ = 7.787*z + 16.0/116.0
        
    L = 116.0 * fY - 16.0
    a = (500.0*(fX - fY))
    b = (200.0*(fY - fZ))

    L=float("%.3f"%L)
    a=float("%.3f"%a)
    b=float("%.3f"%b)

    # print("Lab的值为:",(L,a,b))
    result(L,a,b)

def avg(list1):
    avg = float(sum(list1))/len(list1)
    return avg

#预先输入24张图片的L1,a1,b1的值,即标准的Lab值
Lab_value=[(37.986,13.555,14.059),(65.711,18.13,17.81),(62.661,36.067,57.096),(71.941,19.363,67.857),(96.539,-0.425,1.186),(81.257,-0.683,-0.335),(66.766,-0.734,-0.504),(50.867,-0.153,-0.25)]
f1=open('D:/work/1.工作任务/5.色彩还原--4环境+人脸肤色/face/data.txt','w+')
#用n循环第1-2个文件夹,取第yy行,xx列的图片做计算
path='D:/work/1.工作任务/5.色彩还原--4环境+人脸肤色/color/face/'
files=os.listdir(path)
n=0
for file in files:
    n=n+1
    im = Image.open(path+file)

    #取图片的中心区域坐标,获取该区域的平均RGB
    img_size = im.size
    w = img_size[0] // 2-50
    h = img_size[1] // 2-50
    pix = im.load()
    r=[]
    g=[]
    b=[]
    for x in range(101):
        RGB = pix[w+x, h+x]
        r.append(RGB[0])
        g.append(RGB[1])
        b.append(RGB[2])
    R=avg(r)
    G=avg(g)
    B=avg(b)
    for i in range(8):
        file_num = i + 1
        print("第" + str(n) + "张,第" + str(file_num) + "次计算")
        rgb2lab(R,G,B)

结果如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

备注:
ΔC、ΔE的值,在正常范围内不标色,超出范围标“红色”
ΔC,ΔE表示色彩正确度误差,一般而言值越小表示越接近真实颜色SRGB,也表示摄像模组的颜色误差越小,颜色越好

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值