溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么用python將紅底證件照轉(zhuǎn)成藍(lán)底

發(fā)布時(shí)間:2022-08-31 13:50:49 來源:億速云 閱讀:148 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要講解了“怎么用python將紅底證件照轉(zhuǎn)成藍(lán)底”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“怎么用python將紅底證件照轉(zhuǎn)成藍(lán)底”吧!

    方法一: lableme

    lableme標(biāo)注完后。得到一個(gè)json文件,然后將這種json文件轉(zhuǎn)成掩碼圖.

    # 代碼來自 https://blog.csdn.net/hello_dear_you/article/details/120130155
    import json
    import numpy as np
    import cv2
    # read json file
    with open("origin_json/mypic.json", "r") as f:
        data = f.read()
     
    # convert str to json objs
    data = json.loads(data)
     
    # get the points 
    points = data["shapes"][0]["points"]
    points = np.array(points, dtype=np.int32)   # tips: points location must be int32
     
    # read image to get shape
    image = cv2.imread("origin_png/person.jpg")
     
    # create a blank image
    mask = np.zeros_like(image, dtype=np.uint8)
     
    # fill the contour with 255
    cv2.fillPoly(mask, [points], (255, 255, 255))
     
    # save the mask 
    cv2.imwrite("mask/person_mask.png", mask)

    大概是這樣:

    怎么用python將紅底證件照轉(zhuǎn)成藍(lán)底

    然后利用這個(gè)mask生成圖片

    # 參考自: https://www.jianshu.com/p/1961aa0c02ee
    import cv2
    import numpy as np
    origin_png = 'origin_png/person.jpg'
    # maskPath = 'mask/person_mask.png'
    maskPath = 'mask/bmv2.png'
    result_png = 'result_png/result_png.png'
    maskImg = cv2.imread(maskPath)
    img = cv2.imread(origin_png)
    assert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'
    
    h, w = img.shape[0], img.shape[1]
    print('圖片寬度: {}, 高度: {}'.format(h, w))
    
    rgb = (19,122,171)
    bgr = (rgb[2], rgb[1], rgb[0])
    # (B, G, R)
    for i in range(h):
        for j in range(w):
            if (maskImg[i, j] == 0).all():
                img[i, j] = bgr
    cv2.imwrite(result_png, img)
    print('圖片寫入 {} 成功'.format(result_png))

    由于人長得一般,就不放圖了…

    缺點(diǎn):
    lableme標(biāo)注時(shí)挺費(fèi)力,并且難以避免人與背景邊緣會(huì)有殘留紅色像素的情況。

    方法二: 閾值

    該方法通過比較像素的RGB與背景的RGB來區(qū)分是否為圖像背景。

    Opencv

    import cv2
    import numpy as np
    def mean_square_loss(a_np, b_np):
        sl = np.square(a_np - b_np)
        return np.mean(sl)
    def change_red2blue(origin_png, result_png):
        img = cv2.imread(origin_png)
        h, w = img.shape[0], img.shape[1]
        print('圖片寬度: {}, 高度: {}'.format(h, w))
        origin_rgb = (168,36,32)  # 可以用瀏覽器啥的控制臺(tái)工具提取出背景的rgb值
        origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
        target_rgb = (19,122,171) # 藍(lán)底R(shí)BG
        target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])
        for i in range(h):
            for j in range(w):
                # (B, G, R)
                if mean_square_loss(img[i, j], origin_bgr) < 50:
                    img[i, j] = target_bgr 
        cv2.imwrite(result_png, img)
        print('圖片寫入 {} 成功'.format(result_png))
    if __name__ == '__main__':
        # origin_png = 'result_png/result_png.png'
        origin_png = 'origin_png/person.jpg'
        result_png = 'result_png/result_refine.png'
        change_red2blue(origin_png, result_png)

    結(jié)果人與背景邊緣仍會(huì)存在紅色像素殘留

    PIL

    from torchvision.transforms.functional import to_tensor, to_pil_image
    from PIL import Image
    import torch
    import time
    def mean_square_loss(a_ts, b_ts):
        # print(a_ts.shape)
        # print(b_ts)
        sl = (a_ts - b_ts) ** 2
        return sl.sum()
    def change_red2blue(origin_png, result_png):
        src = Image.open(origin_png)
        src = to_tensor(src)
        # print(src.shape)  # torch.Size([3, 800, 600])
        # channel: (R, G, B) / 255
        h, w = src.shape[1], src.shape[2]
    
        pha = torch.ones(h, w, 3)
    
        bg = torch.tensor([168,36,32]) / 255
        target_bg = torch.tensor([19,122,171]) / 255
    
        # C, H, W -> H, W, C
        src = src.permute(1, 2, 0)
        for i in range(h):
            for j in range(w):
                if mean_square_loss(src[i][j], bg) < 0.025: # 0.025是閾值,超參數(shù)
                    pha[i][j] = torch.tensor([0.0, 0.0, 0.0])
    
        # H, W, C -> C, H, W
        src = src.permute(2, 0, 1)
        pha = pha.permute(2, 0, 1)
        com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)
        to_pil_image(com).save(result_png)
    if __name__ == '__main__':
        origin_png = 'origin_png/person.jpg'
        result_png = 'result_png/com.png'
        start_time = time.time()
        change_red2blue(origin_png, result_png)
        spend_time = round(time.time() - start_time, 2)
        print('生成成功,共花了 {} 秒'.format(spend_time))

    方法三: Background MattingV2

    Real-Time High-Resolution Background Matting
    CVPR 2021 oral

    論文:https://arxiv.org/abs/2012.07810
    代碼:https://github.com/PeterL1n/BackgroundMattingV2

    github的readme.md有inference的colab鏈接,可以用那個(gè)跑

    由于這篇論文是需要輸入一張圖片(例如有人存在的草地上)和背景圖片的(如果草地啥的), 然后模型會(huì)把人摳出來。

    于是這里我需要生成一個(gè)背景圖片。
    首先我先借助firefox的顏色拾取器(或者微信截圖,或者一些在線工具,例如菜鳥工具),得到十六進(jìn)制,再用在線轉(zhuǎn)換工具轉(zhuǎn)成rgb。

    然后生成一個(gè)背景圖片。

    import cv2
    import numpy as np
    image = cv2.imread("origin_png/person.jpg")
    origin_rgb = (168,36,32)  # 可以用瀏覽器啥的控制臺(tái)工具提取出背景的rgb值
    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    image[:, :] = origin_bgr
    cv2.imwrite("mask/bg.png", image)

    怎么用python將紅底證件照轉(zhuǎn)成藍(lán)底

    需要上傳人的照片和背景照片, 如果名字和路徑不一樣則需要修改一下代碼

    src = Image.open('src.png')
    bgr = Image.open('bgr.png')

    另外原論文是邊綠底,要變藍(lán)底,白底,紅底則可以修改RGB值,舉個(gè)例子,原來是這樣的(綠底, RGB120, 255, 155)

    com = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)

    那么加入我要換白底(255, 255, 255),就是

    com = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)

    假如像我換藍(lán)底(19,122,171)具體深淺可以調(diào)節(jié)一下RGB,就是

    com = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)

    總結(jié): 其實(shí)這種方法從 任何顏色的照片 都可以 換成任何顏色的底。只要換下RGB.

    感謝各位的閱讀,以上就是“怎么用python將紅底證件照轉(zhuǎn)成藍(lán)底”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對怎么用python將紅底證件照轉(zhuǎn)成藍(lán)底這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI