使用NNO区域进行色偏检测

149 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

想做图像的色偏检测,网上的资料全是同一套代码,就是2013年那个计算等价圆,然后直接用D-r>9 and K>0.6) or K>1.5,判断的代码(相信大家都查到过了)

  但是色偏问题并不是这样简单的判断就可以的,还分为本质色偏和真实色偏,比如草地或天空的图像,本来就应该偏绿和偏蓝,那么就是本质色偏,不是真正的色偏。

然后我就找相关论文来看了,发现在这块的研究其实也不多,基本上就是重庆大学和武汉理工大学有硕士做相关研究,所以看了看他们的硕士论文,然后自己实现了2017年武汉理工那篇硕士论文。

第一次看到论文里写NNO区域我是懵逼的,查博客也没有相关的介绍,更别提怎么提取NNO的代码了,本着自利利他的原则,我还是开启下这里的空白吧!

NNO区域介绍

NNO全称near neutral objects,代表无色差表面,就是图像中本质色为白色或灰色的表面。

为什么要提取NNO区域做色偏检测呢,因为白色区域的表现色有效反应了图像的整体颜色,所以一般做法是根据原图像的等效圆参数与NNO区域的等效圆参数进行对比,利用变化趋势去判断图像是否偏色。

NNO区域提取步骤

1、此论文为了提高计算速率,首先将图像进行分块,可以大大缩短计算时间。

2、此论文提出一种自适应提取NNO区域的方法,按基于空间汇集策略的等效圆计算方法,完成分块、颜色空间转换、标记暗色块,计算得到等效圆圆心和半径

def NNO(h, w, image):
    m, n = 64, 64 # 划分为64*64的块
    h_new = h-(h%m)
    w_new = w-(w%n)
    image = image[0:h_new,0:w_new]
    block_h = h_new//m
    block_w = w_new//n
    averaged = block(block_h,block_w,image, m, n)
    lab = cv2.cvtColor(averaged,cv2.COLOR_BGR2LAB)
    l,a,b = cv2.split(lab)
    h, w = l.shape
    l1 = (l/255*100).astype(np.uint8) 
    L_area = np.zeros((h,w))
    L_area[np.where(l1>=20)and np.where(l1<=95)] = 1
    
    abvalue = np.zeros((m,n))
    for i in range(m):
        for j in range(n):
            aij = (a[i,j]-128)*(a[i,j]-128)
            bij = (b[i,j]-128)*(b[i,j]-128)
            abvalue[i,j] = math.sqrt(aij*aij+bij*bij)
    F = abvalue.sum()
    T = 0
    for i in range(m):
        for j in range(n):
            T += ((F-abvalue[i,j])/((m*n-1)*F))*abvalue[i,j]
    T = 1/2 * T
    mask = np.zeros((h,w))     
    mask[np.where(abvalue<T)] = 1    
    NNO = L_area * mask
    image_copy = copy.deepcopy(averaged)
    image_copy[np.where(NNO!=1)] = 0
    lab_nno = cv2.cvtColor(image_copy,cv2.COLOR_BGR2LAB)
    l_nno, a_nno,b_nno = cv2.split(lab_nno)
    u,D_sigma,sigma = DKr(a, b, m, n)

    u_nno,D_sigma_nno,sigma_nno = DKr(a_nno,b_nno, m, n)
    try:
        D_sigma_cr = (D_sigma - D_sigma_nno)/D_sigma
        u_cr = (u - u_nno)/u
        sigma_cr = (sigma - sigma_nno)/sigma
    except:
        if D_sigma == 0:
            D_sigma_cr = 0
        if u == 0:
            u_cr = 0
        if sigma == 0:
            sigma_cr = 0
    return D_sigma_cr, u_cr, sigma_cr,D_sigma_nno

全部代码

写在了我的github

github.com/jiafw/Color…

如果对你有帮助,可以给个star~~~

复现数据不能保证和原文一模一样,但是测试结果还是可以的。