python将红底证件照转成蓝底

news/2024/11/23 5:40:07/

前言

emmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下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 nporigin_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 npdef 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) # 蓝底RBGtarget_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 timedef mean_square_loss(a_ts, b_ts):# print(a_ts.shape)# print(b_ts)sl = (a_ts - b_ts) ** 2return 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) / 255h, w = src.shape[1], src.shape[2]pha = torch.ones(h, w, 3)bg = torch.tensor([168,36,32]) / 255target_bg = torch.tensor([19,122,171]) / 255# C, H, W -> H, W, Csrc = 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, Wsrc = 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 npimage = 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_bgrcv2.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


http://www.ppmy.cn/news/750567.html

相关文章

图像处理(八)证件照蓝底换成红底,白底

✨✨✨ 感谢优秀的你打开了小白的文章 “希望在看文章的你今天又进步了一点点&#xff0c;离美好生活更近一步&#xff01;”&#x1f308; &#x1f680;往期回顾 图像的基本处理&#xff08;一&#xff09;图像基本处理&#xff08;一&#xff09;_am_student的博客-CSDN博客…

如何自己更改证件照底色?如何生成蓝底照片电子版?

为了达到证件照的使用需求&#xff0c;有时需要更换证件照底色。怎样将白底照片一键更换照片背景&#xff0c;生成蓝色电子版证件照呢&#xff1f;分享一款在线证件照换背景工具&#xff0c;只需三步轻松完成证件照换底色。 1、上传图片。 2、选择蓝色背景色。 3、保存下载。 …

PS证件照蓝底改白底?

如果拍摄的证件照是蓝底&#xff0c;但是需要的是白底&#xff0c;要怎么办呢&#xff1f;方法非常简单&#xff0c;借助图像处理软件PS实现背景色的改变即可。 纯净之家-win7纯净版系统_win7 ghost 纯净版 方法/步骤 1、在PS中打开图片&#xff0c;直接单击魔棒工具。 2、在属…

​可以给证件照换衣服的软件有哪些?教你如何一键换装

有什么软件可以给证件照换衣服呢&#xff1f;证件照是我们大学毕业之后必备的一种证件&#xff0c;报名各种考试或者是找工作都是需要使用到的。但是大家在使用证件照的时候&#xff0c;往往会因为各种原因使我们的证件照不合规定&#xff0c;其中就有因为服装不够正式导致使用…

证件照换底,红白蓝底随机换(附:一寸二寸证件照制作)

证件照的底色以红色、蓝色、白色为主。有时我们手上仅有一种背景颜色的电子照片&#xff0c;又不想费时费力费钱的重新去照。今天就教大家如何利用ps完美换底。 对证件照换底的难点在于发丝处的替换。所以仅使用颜色选择选中背景区域后&#xff0c;再填充新颜色的方法并不完美。…

自己如何快速制作蓝色背景证件照

根据不同的使用场景&#xff0c;证件照底色会有所不同。其中蓝色背景证件照是比较常用的&#xff0c;比如学生证、毕业证、简历、工作证等。如果有一个突发的情况&#xff0c;需要准备一张蓝色背景的证件照&#xff0c;那么我们该如何解决这个问题呢&#xff1f;下面小编就教大…

Phoshop证件照换底色(红底换蓝底、白底)

Ps证件照换底色时如何精细到头发丝儿&#xff1f; Phoshop证件照换底&#xff1a;红白蓝互换 1. 导入图片 可以直接拖拽到Photoshop界面 2. Ctrl J 复制图层 需要注意一般不对原图进行操作&#xff0c;在这里CTRLJ复制图层&#xff0c;对新图层进行操作 隐藏原图层 3. 选…

蓝底证件照如何制作?快速学习教程来啦

蓝底证件照如何制作&#xff1f;在我们的日常生活中总是需要进行证件照的制作&#xff0c;无论是报名考试&#xff0c;还是投递简历&#xff0c;这些事件都和证件照息息相关。制作证件照有各种各样的样式&#xff0c;这里小编给大家分享的是蓝底证件照的制作方法。 方法一&…