예제 #1
0
def skin_detect(img):
    """img: in BGR mode"""
    # initialized all-white mask
    skinMask = np.zeros(img.shape[0:2], img.dtype)
    img_LAB = cv2.cvtColor(img, cv2.COLOR_BGR2LAB).astype('float')
    img_HSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV).astype('float')

    # ellipse and HSV_test
    skinMask[ ellipse_test(img_LAB[...,1], img_LAB[...,2], bound=1.0, prob=0.6)
              & HSV_threshold(img_HSV[...,0], img_HSV[...,1]) ] \
        = 255
    # relaxed ellipse test, guarenteed by skin neighborhood
    skinMask[ (skinMask ==0)
              & ellipse_test(img_LAB[...,1], img_LAB[...,2]
                             , bound=1.25, prob=0.6)
              & check_neighbor(skinMask)] = 255
    # filling holes:image closing on skinMask
    # http://stackoverflow.com/a/10317883/2729100
    _h,_w = img.shape[0:2]
    _kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(_h/16,_w/16))
    skinMask_closed = cv2.morphologyEx(skinMask,cv2.MORPH_CLOSE,_kernel)
    # skinMask_closed = skinMask
    cape_util.display(np.hstack([skinMask, skinMask_closed]), name='skin mask closing before after', mode='gray')
    # initialization, can't remove, otherwise mask==0 area will be random
    skin = 255*np.ones(img.shape, img.dtype)
    skin = cv2.bitwise_and(img, img, mask=skinMask_closed)
    return skin, (skinMask_closed/255).astype(bool)
예제 #2
0
def exposure_correction(I_L, I_out, I_out_side_crr, skin_masks, faces_xywh,
                        _eacp_lambda_):
    I_out_255 = cape_util.mag(I_out, 'float')
    A = np.ones(I_out_side_crr.shape)
    I_out_expo_crr = I_out_side_crr.copy()
    for i in range(len(faces_xywh)):
        x, y, w, h = faces_xywh[i]
        face = I_out_side_crr[y:y + h, x:x + w]
        # each sidelit crted face(L channel)
        skin_face = cape_util.mask_skin(face, skin_masks[i][1])  # SKIN on that face
        cumsum = cv2.calcHist([cape_util.mag(skin_face, 'trim')]  # cumsumed hist of SKIN
                              , [0], None, [255], [1, 256]).T.ravel().cumsum()
        # visualize cumsum of hist
        plt.plot(cumsum)
        plt.xlim([1, 256])
        plt.show()

        p = np.searchsorted(cumsum, cumsum[-1] * 0.75)
        if p < 120:
            print 'face skin is underexposed!'
            f = (120 + p) / ((2 * p) + 1e-6)
            A[y:y + h, x:x + w][face > 0] = f
            # >0 means every pixel *\in S*
            A_after = EACP(A, I_out_255, lambda_=_eacp_lambda_)
            # to visualize A before/after EACP
            cape_util.display(np.hstack([A, A_after]), mode='rainbow')
            I_out_expo_crr = A_after * I_out_side_crr

    # to visualize exposure corrected face
    cape_util.display(cape_util.mag(I_out_expo_crr, 'trim'),
                      name='exposure corrected L',
                      mode='gray')
    return I_out_expo_crr
예제 #3
0
def skin_detect(img):
    """img: in BGR mode"""
    # initialized all-white mask
    skinMask = np.zeros(img.shape[0:2], img.dtype)
    img_LAB = cv2.cvtColor(img, cv2.COLOR_BGR2LAB).astype('float')
    img_HSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV).astype('float')

    # ellipse and HSV_test
    skinMask[ ellipse_test(img_LAB[...,1], img_LAB[...,2], bound=1.0, prob=0.6)
              & HSV_threshold(img_HSV[...,0], img_HSV[...,1]) ] \
        = 255
    # relaxed ellipse test, guarenteed by skin neighborhood
    skinMask[
        (skinMask == 0)
        & ellipse_test(img_LAB[..., 1], img_LAB[..., 2], bound=1.25, prob=0.6)
        & check_neighbor(skinMask)] = 255
    # filling holes:image closing on skinMask
    # http://stackoverflow.com/a/10317883/2729100
    _h, _w = img.shape[0:2]
    _kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (_h / 16, _w / 16))
    skinMask_closed = cv2.morphologyEx(skinMask, cv2.MORPH_CLOSE, _kernel)
    # skinMask_closed = skinMask
    cape_util.display(np.hstack([skinMask, skinMask_closed]),
                      name='skin mask closing before after',
                      mode='gray')
    # initialization, can't remove, otherwise mask==0 area will be random
    skin = 255 * np.ones(img.shape, img.dtype)
    skin = cv2.bitwise_and(img, img, mask=skinMask_closed)
    return skin, (skinMask_closed / 255).astype(bool)
예제 #4
0
def face_enhancement(I_origin, _eacp_lambda_=0.2):
    """
    Keyword Arguments:
    I             -- np.uint8, (m,n,3), BGR
    _eacp_lambda_ -- float, scala
    """
    _I_LAB = cv2.cvtColor(I_origin, cv2.COLOR_BGR2LAB)
    I = _I_LAB[..., 0]
    Base, Detail = wls_filter.wlsfilter(I)
    I_out = Base  # float [0,1]

    I_aindane = aindane.aindane(I_origin)
    faces_xywh = vj_face.face_detect(I_aindane)
    faces = [I_origin[y:y + h, x:x + w] for (x, y, w, h) in faces_xywh]
    skin_masks = [apa_skin.skin_detect(face) for face in faces]
    _any_skin = False
    for _mask in skin_masks:
        _any_skin |= ((_mask[1]).any())
    if (faces_xywh == []) or (not _any_skin):  # face not detected
        print 'face or skin not detected!'
        return I_origin
    _I_out_faces = [I_out[y:y + h, x:x + w]
                    for (x, y, w, h) in faces_xywh]  #float[0,1]
    S = [ cape_util.mask_skin(_I_out_faces[i], skin_masks[i][1]) \
          for i in range(len(_I_out_faces)) ]  # float [0,1]

    # to visualize detected skin and it's (unsmoothed) hist
    for idx, s in enumerate(S):
        cape_util.display(cape_util.mag(s),
                          name='detected skin of L channel',
                          mode='gray')
        # plot original hist(rectangles form, of S). don't include 0(masked)
        plt.hist(cape_util.mag(s).ravel(), 255, [1, 256])
        plt.xlim([1, 256])
        plt.show()
        ## save image data for R silverman analysis
        import os
        DATA_DIR = os.path.expanduser('~/Dropbox/dropcode/r/')
        # save skin pixels (value neq 0.0)
        np.savetxt(DATA_DIR + str(idx) + '.csv',
                   s[s != 0.0].ravel(),
                   delimiter=',')

    H = [cape_util.get_smoothed_hist(cape_util.mag(s)) for s in S]
    # visualize smoothed hist
    for h in H:
        plt.plot(h)
        plt.xlim([1, 256])
        plt.show()

    I_out_side_crr = sidelight_correction(_I_LAB[..., 0], I_out, H, S,
                                          faces_xywh, _eacp_lambda_)
    I_out_expo_crr = exposure_correction(_I_LAB[..., 0], I_out, I_out_side_crr,
                                         skin_masks, faces_xywh, _eacp_lambda_)

    _I_LAB[..., 0] = cape_util.mag((I_out_expo_crr + 255.0 * Detail), 'trim')
    I_res = cv2.cvtColor(_I_LAB, cv2.COLOR_LAB2BGR)
    return I_res
예제 #5
0
def face_enhancement(I_origin, _eacp_lambda_=0.2):
    """
    Keyword Arguments:
    I             -- np.uint8, (m,n,3), BGR
    _eacp_lambda_ -- float, scala
    """
    _I_LAB = cv2.cvtColor(I_origin, cv2.COLOR_BGR2LAB)
    I = _I_LAB[..., 0]
    Base, Detail = wls_filter.wlsfilter(I)
    I_out = Base  # float [0,1]

    I_aindane = aindane.aindane(I_origin)
    faces_xywh = vj_face.face_detect(I_aindane)
    faces = [I_origin[y:y + h, x:x + w] for (x, y, w, h) in faces_xywh]
    skin_masks = [apa_skin.skin_detect(face) for face in faces]
    _any_skin = False
    for _mask in skin_masks:
        _any_skin |= ((_mask[1]).any())
    if (faces_xywh == []) or (not _any_skin):  # face not detected
        print 'face or skin not detected!'
        return I_origin
    _I_out_faces = [I_out[y:y + h, x:x + w] for (x, y, w, h) in faces_xywh]  #float[0,1]
    S = [ cape_util.mask_skin(_I_out_faces[i], skin_masks[i][1]) \
          for i in range(len(_I_out_faces)) ]  # float [0,1]

    # to visualize detected skin and it's (unsmoothed) hist
    for idx, s in enumerate(S):
        cape_util.display(cape_util.mag(s),
                          name='detected skin of L channel',
                          mode='gray')
        # plot original hist(rectangles form, of S). don't include 0(masked)
        plt.hist(cape_util.mag(s).ravel(), 255, [1, 256])
        plt.xlim([1, 256])
        plt.show()
        ## save image data for R silverman analysis
        import os
        DATA_DIR = os.path.expanduser('~/Dropbox/dropcode/r/')
        # save skin pixels (value neq 0.0)
        np.savetxt(DATA_DIR+str(idx)+'.csv', s[s!=0.0].ravel(), delimiter=',')

    H = [cape_util.get_smoothed_hist(cape_util.mag(s)) for s in S]
    # visualize smoothed hist
    for h in H:
        plt.plot(h)
        plt.xlim([1, 256])
        plt.show()

    I_out_side_crr = sidelight_correction(_I_LAB[..., 0], I_out, H, S,
                                          faces_xywh, _eacp_lambda_)
    I_out_expo_crr = exposure_correction(_I_LAB[..., 0], I_out, I_out_side_crr,
                                         skin_masks, faces_xywh, _eacp_lambda_)

    _I_LAB[..., 0] = cape_util.mag((I_out_expo_crr + 255.0 * Detail), 'trim')
    I_res = cv2.cvtColor(_I_LAB, cv2.COLOR_LAB2BGR)
    return I_res
예제 #6
0
def exposure_correction(I_L, I_out, I_out_side_crr, skin_masks, faces_xywh,
                        _eacp_lambda_):
    I_out_255 = cape_util.mag(I_out, 'float')
    A = np.ones(I_out_side_crr.shape)
    I_out_expo_crr = I_out_side_crr.copy()
    for i in range(len(faces_xywh)):
        x, y, w, h = faces_xywh[i]
        face = I_out_side_crr[y:y + h, x:x + w]
        # each sidelit crted face(L channel)
        skin_face = cape_util.mask_skin(face,
                                        skin_masks[i][1])  # SKIN on that face
        cumsum = cv2.calcHist(
            [cape_util.mag(skin_face, 'trim')]  # cumsumed hist of SKIN
            ,
            [0],
            None,
            [255],
            [1, 256]).T.ravel().cumsum()
        # visualize cumsum of hist
        plt.plot(cumsum)
        plt.xlim([1, 256])
        plt.show()

        p = np.searchsorted(cumsum, cumsum[-1] * 0.75)
        if p < 120:
            print 'face skin is underexposed!'
            f = (120 + p) / ((2 * p) + 1e-6)
            A[y:y + h, x:x + w][face > 0] = f
            # >0 means every pixel *\in S*
            A_after = EACP(A, I_out_255, lambda_=_eacp_lambda_)
            # to visualize A before/after EACP
            cape_util.display(np.hstack([A, A_after]), mode='rainbow')
            I_out_expo_crr = A_after * I_out_side_crr

    # to visualize exposure corrected face
    cape_util.display(cape_util.mag(I_out_expo_crr, 'trim'),
                      name='exposure corrected L',
                      mode='gray')
    return I_out_expo_crr
예제 #7
0
def sky_enhance(X, P, Sbgr
                ,I_origin, sky_prob_map):
    """
    ARGs:
    -----
    X: Alpha = x[0]; C = x[1]; S=x[2]
    P: sky_porb_map
    Sbgr: np.array([[[Sb, Sg, Sr]]]), mean of the sky color in current image

    NOTE: computing some color-like array (e.g. beta_old) will actually exceed 255,
          use 'float' instead of 'uint8'
    """
    Alpha = X[0]; C = X[1]; S=X[2]

    f_sky_bgr = np.array([[[255,210,160]]], dtype='uint8')
    f_sky = cv2.cvtColor(f_sky_bgr, cv2.COLOR_BGR2LAB) # preferred color, in CIELab
    Slab = cv2.cvtColor(Sbgr, cv2.COLOR_BGR2LAB)
    f_lab = 1.0*f_sky / Slab # (f_l, f_a, f_b), correction ratio
    print 'f_lab: ', f_lab
    beta_old = cv2.cvtColor( cape_util.safe_convert(_2to3(S) * Sbgr, np.uint8), cv2.COLOR_BGR2LAB )
    kai_old = cv2.cvtColor( cape_util.safe_convert(_2to3(C), np.uint8), cv2.COLOR_BGR2LAB )
    W = np.array([[[100, 0, 0]]])
    # W = np.array([[[255, 128, 128]]]) # (255,255,255) in RGB

    P_3 = _2to3(P)
    beta_new = cv2.add(P_3*(f_lab*beta_old), (1-P_3)*beta_old)
    kai_new = cv2.add(P_3*((W+kai_old)/2.0), (1-P_3)*kai_old)
    _fst = _2to3(1-Alpha)*cv2.cvtColor(beta_new.astype('uint8'), cv2.COLOR_LAB2BGR)
    _lst = _2to3(Alpha)*cv2.cvtColor(kai_new.astype('uint8'), cv2.COLOR_LAB2BGR)
    res = cv2.add( _fst, _lst ) # use cv2.add() to avoid overflow e.g. 150+125=255, not 20
    # visualize _fst, _lst for debugging
    _first = I_origin.copy(); _last = I_origin.copy()
    _first[ sky_prob_to_01(sky_prob_map, thresh=0.0) ] = _fst[0]
    _last[ sky_prob_to_01(sky_prob_map, thresh=0.0) ] = _lst[0]
    cape_util.display( np.hstack([_first, _last] ) )

    return res
예제 #8
0
def sidelight_correction(I_L, I_out, H, S, faces_xywh, _eacp_lambda_):
    I_out_255 = cape_util.mag(I_out, 'float')
    bimodal_Fs, D, M, B = cape_util.detect_bimodal(H)
    A = np.ones(I_out_255.shape)
    W = np.zeros(I_out_255.shape)
    for i in range(len(bimodal_Fs)):
        if bimodal_Fs[i] == True:
            b = B[i]
            d = D[i]
            m = M[i]
            f = (b - d) / (m - d)
            print str(i) + 'th face: d, m, b, f', d, m, b, f
            x, y, w, h = faces_xywh[i]
            A[y:y + h,
              x:x + w][(cape_util.mag(S[i], 'float') < m)
                       & (cape_util.mag(S[i], 'float') > 0)] = f  #<m and \in S
            global W
            miu = (I_out_255[A == f]).mean()
            sig = 255 * 3  # manually set, 3*sig = 120 close to 255/2
            W = np.exp(-(I_out_255 - miu)**2 / sig**2)
            # W[A==f] = 1.
            W[...] = 1 - W[...]
            # W[A!=f] =1.
            W[...] = 1.
            # face_i_crr = EACP(I_out_255[y:y+h,x:x+w]*A, I_out_255[y:y+h,x:x+w], lambda_=_eacp_lambda_)
            # I_out_255[y:y+h, x:x+w] = face_i_crr
        else:
            print '? bimodal not detected on', i, 'th face'
    # W[...] = 1.
    cape_util.display(W, mode='rainbow')
    A_after = A.copy()
    if (A == 1).all():
        print 'A == 1 everywhere!'
    else:
        A_after = EACP(A, I_L, W, lambda_=_eacp_lambda_)
    I_out_side_crr = A_after * I_out_255
    # to visualize A before/after EACP
    cape_util.display(np.hstack([A, A_after]), mode='rainbow')
    # to visualize sidelight corrected result
    cape_util.display(cape_util.mag(I_out_side_crr, 'trim'),
                      name='sidelight corrected, L',
                      mode='gray')
    return I_out_side_crr  # float [0.0,255.0]
예제 #9
0
def sidelight_correction(I_L, I_out, H, S, faces_xywh, _eacp_lambda_):
    I_out_255 = cape_util.mag(I_out, 'float')
    bimodal_Fs, D, M, B = cape_util.detect_bimodal(H)
    A = np.ones(I_out_255.shape)
    W = np.zeros(I_out_255.shape)
    for i in range(len(bimodal_Fs)):
        if bimodal_Fs[i] == True:
            b = B[i]
            d = D[i]
            m = M[i]
            f = (b - d) / (m - d)
            print str(i) + 'th face: d, m, b, f', d, m, b, f
            x, y, w, h = faces_xywh[i]
            A[y:y + h, x:x + w][(cape_util.mag(S[i], 'float') < m) &
                                (cape_util.mag(S[i], 'float') > 0)] = f  #<m and \in S
            global W
            miu = (I_out_255[A == f]).mean()
            sig = 255 * 3  # manually set, 3*sig = 120 close to 255/2
            W = np.exp(-(I_out_255 - miu) ** 2 / sig ** 2)
            # W[A==f] = 1.
            W[...] = 1 - W[...]
            # W[A!=f] =1.
            W[...] = 1.
            # face_i_crr = EACP(I_out_255[y:y+h,x:x+w]*A, I_out_255[y:y+h,x:x+w], lambda_=_eacp_lambda_)
            # I_out_255[y:y+h, x:x+w] = face_i_crr
        else:
            print '? bimodal not detected on', i, 'th face'
    # W[...] = 1.
    cape_util.display(W, mode='rainbow')
    A_after = A.copy()
    if (A == 1).all():
        print 'A == 1 everywhere!'
    else:
        A_after = EACP(A, I_L, W, lambda_=_eacp_lambda_)
    I_out_side_crr = A_after * I_out_255
    # to visualize A before/after EACP
    cape_util.display(np.hstack([A, A_after]), mode='rainbow')
    # to visualize sidelight corrected result
    cape_util.display(cape_util.mag(I_out_side_crr, 'trim'),
                      name='sidelight corrected, L',
                      mode='gray')
    return I_out_side_crr  # float [0.0,255.0]
예제 #10
0
def main():
    I_origin = cv2.imread(IMG_DIR + 'input_teaser.png')
    lambda_ = 120
    I_res = face_enhancement(I_origin, lambda_)
    cape_util.display(np.hstack([I_origin, I_res]))
    return 0
예제 #11
0
def main():
    I_origin = cv2.imread(IMG_DIR+'pic23.jpg')
    res_disp,_ = sky_enhancement(I_origin)
    cape_util.display(np.hstack([I_origin, res_disp]))
    return 0
예제 #12
0
def _test():
    I_bgr = cv2.imread(IMG_DIR + 'pic36.jpg')
    I_res_bgr = ss_enhance(I_bgr)
    cape_util.display(np.hstack([I_bgr, I_res_bgr]))
    return
예제 #13
0
def main():
    img_name = 'pic23.jpg'
    I_org = cv2.imread(IMG_DIR+ img_name)
    skin_prob_map = apa_skin.skin_prob_map(I_org)
    lambda_ = 120
    res_skin = I_org
    res_skin = face_enhancement.face_enhancement(I_org, lambda_)
    cape_util.display( np.hstack([I_org,res_skin]), name='res_skin' )
    res_sky, sky_prob_map = sky_enhancement.sky_enhancement(res_skin)
    cape_util.display( np.hstack([I_org,res_sky]), name='res_sky' )
    # res_ge = global_enhace(res_sky, skin_prob_map ,sky_prob_map)
    res_ge = global_enhace(res_skin, skin_prob_map ,sky_prob_map)
    cape_util.display( np.hstack([I_org,res_ge]), name='res_ge' )
    res_ss = ss_enhance.ss_enhance(res_ge)
    cape_util.display( np.hstack([I_org,res_ss]), name='res_ss' )
    res_de = detail_enhace(res_ss, skin_prob_map, sky_prob_map)
    cape_util.display( np.hstack([I_org,res_de]), name='res_de' )
    # res_de = res_ss
    cape_util.display( np.hstack([I_org,res_de]), name='lambda_='+str(lambda_) )
    DIR = './resources/results/'
    cv2.imwrite( DIR+str.split(img_name, '.')[0]+'_res.png', np.hstack([I_org, res_de]) )
    return 0
예제 #14
0
파일: ss_enhance.py 프로젝트: shiruilu/CAPE
def _test():
    I_bgr = cv2.imread(IMG_DIR+'pic36.jpg')
    I_res_bgr = ss_enhance(I_bgr)
    cape_util.display(np.hstack([I_bgr, I_res_bgr]))
    return
예제 #15
0
def main():
    I_origin = cv2.imread(IMG_DIR + 'input_teaser.png')
    lambda_ = 120
    I_res = face_enhancement(I_origin, lambda_)
    cape_util.display(np.hstack([I_origin, I_res]))
    return 0