python将红底证件照转成蓝底的实现方法

目录
  • 前言
  • 方法一: lableme
  • 方法二: 阈值
    • Opencv
    • PIL
  • 方法三: Background MattingV2

前言

emmm…9月1日开学季,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。

方法一: lableme

lableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.

# 代码来自 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)

大概是这样:

然后利用这个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))

由于人长得一般,就不放图了…

缺点:
lableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。

方法二: 阈值

该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。

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)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    target_rgb = (19,122,171) # 蓝底RBG
    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)

结果人与背景边缘仍会存在红色像素残留

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是阈值,超参数
                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))

该方法质量较好,但一张图片大概需要12秒。

方法三: 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链接,可以用那个跑

由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。

于是这里我需要生成一个背景图片。
首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。

然后生成一个背景图片。

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

需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码

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

另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, 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)

假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是

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

总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.

然后就输出图片了。可以看到效果相当好。不愧是oral。

原论文可以实现发丝级效果

报错解决方案
can’t divided by 4 / can’t divided by 16
由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。
这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize

到此这篇关于python将红底证件照转成蓝底的文章就介绍到这了,更多相关python证件照转换内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 20行代码教你用python给证件照换底色的方法示例

    1.图片来源 该图片来源于百度图片,如果侵权,请联系我删除!图片仅用于知识交流. 2.读取图片并显示 imread():读取图片: imshow():展示图片: waitkey():设置窗口等待,如果不设置,窗口会一闪而过: import cv2 import numpy as np # 读取照片 img=cv2.imread('girl.jpg') # 显示图像 cv2.imshow('img',img) # 窗口等待的命令,0表示无限等待 cv2.waitKey(0) 效果如下: 3.图片缩

  • 基于OpenCV python3实现证件照换背景的方法

    简述 生活中经常要用到各种要求的证件照电子版,红底,蓝底,白底等,大部分情况我们只有其中一种,所以通过技术手段进行合成,用ps处理证件照,由于技术不到位,有瑕疵,所以想用python&openCV通过代码的方式实现背景颜色替换,加强一下对于openCV的学习,锻炼一下编码水平. 软件环境: python3.5 opencv2 windows 10 图像载入 导入opencv库,使用imread函数读取图片 import cv2 import numpy as np img=cv2.imread(

  • python opencv实现证件照换底功能

    本文实例为大家分享了python opencv实现证件照换底功能的具体代码,供大家参考,具体内容如下 思路:先转到HSV空间,利用颜色提取背景制作掩模版mask,然后通过按位操作提取人像和制作新背景,最后叠加背景和人像得到换底后照片 代码 #-*-coding:utf-8-*- import cv2 import numpy as np def cvtBackground(path,color): """ 功能:给证件照更换背景色(常用背景色红.白.蓝) 输入参数:path:

  • python实现抠图给证件照换背景源码

    本文实例为大家分享了python实现抠图给证件照换背景的具体代码,供大家参考,具体内容如下 import cv2 import numpy as np import matplotlib.pyplot as plt #建立显示图片的函数 def show(image): plt.imshow(image) plt.axis('off') plt.show() #导入前景图 img=cv2.imread('font.jpg') #图片导入 img = cv2.cvtColor(img,cv2.CO

  • python实现证件照换底功能

    本来是在找交通识别的程序,然后凑巧看见了证件照换底,于是学习了一下~一开始在网上找了一个很普遍写的程序,但是效果并不好,想要放弃了,然后看见了这个,参考:python opencv实现证件照换底功能 本人基于此做了一些改进,便于自己运行和调试,还加了中值滤波,本人觉得效果还不错~ 代码: import cv2 import numpy as np def cvtBackground(path,color): """ 功能:给证件照更换背景色(常用背景色红.白.蓝) 输入参数:

  • 使用python半分钟轻松完成证件照换底色

    导语 小伙伴们都知道,刚入职的时候都是要求新人入职带着自己的证件照的,这应该是几寸的来着,小编入职这么久都忘记了!!! 昨天下班之后跟之前的老朋友聚餐,其实一个兄弟的跟我说:"老表,你现在是编程的,又没得办法帮我一个忙?" 我这一听:"什么事儿?你说" "我老婆前几天刚入职新公司,但是入职之后才晓得照片是需要蓝底儿的,主要是那个照证件照的离家太远了,索性问下你有啥办法没?" 那当然,为了节省他们的时间,这小忙我义不容辞,也就几分钟的事儿.​ 正文

  • python将红底证件照转成蓝底的实现方法

    目录 前言 方法一: lableme 方法二: 阈值 Opencv PIL 方法三: Background MattingV2 前言 emmm…9月1日开学季,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢.懒得下ps了.自己撸起来吧. 方法一: lableme lableme标注完后.得到一个json文件,然后将这种json文件转成掩码图. # 代码来自 https://blog.csdn.net/hello_dear_you/article/details/120130155 impor

  • Python使用scrapy采集时伪装成HTTP/1.1的方法

    本文实例讲述了Python使用scrapy采集时伪装成HTTP/1.1的方法.分享给大家供大家参考.具体如下: 添加下面的代码到 settings.py 文件 复制代码 代码如下: DOWNLOADER_HTTPCLIENTFACTORY = 'myproject.downloader.HTTPClientFactory' 保存以下代码到单独的.py文件 复制代码 代码如下: from scrapy.core.downloader.webclient import ScrapyHTTPClien

  • Python OpenCV读取png图像转成jpg图像存储的方法

    如下所示: import os import cv2 import sys import numpy as np path = "F:\\ImageLib\\VRWorks_360_Video _SDK_1.1\\footage14\\" print(path) for filename in os.listdir(path): if os.path.splitext(filename)[1] == '.png': # print(filename) img = cv2.imread(

  • python pcm音频添加头转成Wav格式文件的方法

    如下所示: ''''' add Head Infomation for pcm file ''' import sys import struct import os __author__ = 'bob_hu, hewitt924@gmail.com' __date__ = 'Dec 19,2011' __update__ = 'Dec 19,2011' def geneHeadInfo(sampleRate,bits,sampleNum): ''''' 生成头信息,需要采样率,每个采样的位数,

  • python将.ppm格式图片转换成.jpg格式文件的方法

    将.ppm格式的图片转换成.jpg格式的图像,除了通过软件转换,还可以使用python脚本直接转换,so easy!!! from PIL import Image img = Image.open("images/25_color.ppm") img.save("JPGimg/25_color.jpg") img.show() 以上这篇python将.ppm格式图片转换成.jpg格式文件的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持

  • C++使用OpenCV实现证件照蓝底换成白底功能(或其他颜色如红色)详解

    本文实例讲述了C++使用OpenCV实现证件照蓝底换成白底功能(或其他颜色如红色).分享给大家供大家参考,具体如下: 今天刚好老师要办点事情,老师唯一的一张证件照是蓝色的,但是需要的底色是白色的,于是乎,好久不折腾的PS也忘记了,还好旁边的刚来的小学弟懂一点, 在那里慢慢的帮老师一点点的处理,PS在边缘的地方效果还真不咋地,确实是一门技术活. 于是我就想OpenCV能不能实现呢?一搜百度第一篇就是,但是人家转成红色,然后我又对HSV颜色空间不是很懂,最后在一个学习群里 但是文中未对HSV那一块做

  • Python实现将蓝底照片转化为白底照片功能完整实例

    本文实例讲述了Python实现将蓝底照片转化为白底照片功能.分享给大家供大家参考,具体如下: import cv2 import numpy as np img=cv2.imread('yay.jpg') #原始图片 #缩放 rows,cols,channels = img.shape img=cv2.resize(img,None,fx=0.5,fy=0.5) rows,cols,channels = img.shape cv2.imshow('img',img) #转换hsv hsv=cv2

  • C++ opencv实现的把蓝底照片转化为白底照片功能完整示例

    本文实例讲述了C++ opencv实现的把蓝底照片转化为白底照片功能.分享给大家供大家参考,具体如下: #include <opencv2/opencv.hpp> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> using namespace std; using namespace c

  • python实现将html表格转换成CSV文件的方法

    本文实例讲述了python实现将html表格转换成CSV文件的方法.分享给大家供大家参考.具体如下: 使用方法:python html2csv.py *.html 这段代码使用了 HTMLParser 模块 #!/usr/bin/python # -*- coding: iso-8859-1 -*- # Hello, this program is written in Python - http://python.org programname = 'html2csv - version 20

  • python 自动化将markdown文件转成html文件的方法

    一.背景 我们项目开发人员写的文档都是markdown文件.对于其它组的同学要进行阅读不是很方便.每次编辑完markdown文件,我都是用软件将md文件转成html文件.刚开始转的时候,还没啥,转得次数多了,就觉得不能继续这样下去了.作为一名开发人员,还是让机器去做这些琐碎的事情吧.故写了两个脚本将md文件转成html文件,并将其放置在web服务器下,方便其他人员阅读. 主要有两个脚本和一个定时任务: •一个python脚本,主要将md文件转成html文件: •一个shell脚本,主要用于管理逻

随机推荐