数学建模社区-数学中国

标题: python将红底证件照转成蓝底 [打印本页]

作者: 杨利霞    时间: 2022-9-7 11:41
标题: python将红底证件照转成蓝底
python将红底证件照转成蓝底4 E. F" m* n' a% ^
前言
, s" q& `/ N+ }, v( @, G' Vemmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。/ s, m7 ?4 _0 p2 F0 k, U* s

: s" ^$ s) _6 h6 P: e
- {, w+ l2 j# I
7 o1 a; k4 _- }$ j8 u# K) e* ^% b( k1 c( @% n  D
方法一: lableme% Q, A  H3 f2 v9 d" t
lableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.
5 t' g8 k9 V2 p3 D. P
6 m8 n) [0 n  s8 c# R0 A2 o# 代码来自 https://blog.csdn.net/hello_dear_you/article/details/120130155- S" N5 v0 E6 V
import json
0 ^4 m; p2 f2 h) |! m; Y" pimport numpy as np
5 _) [; f  @. a9 E# r; l8 ?import cv21 t- W- ^4 r  Q9 V/ s* I
# read json file
: v! X. F1 Z. B7 e/ [4 ~with open("origin_json/mypic.json", "r") as f:3 o2 J0 u: [% r+ Z
    data = f.read()
# V! L# \3 s  g" e9 p. R! b$ c$ A. ?
& D/ b% q" L% o( s/ l; A1 J# convert str to json objs
4 L* f' K- n/ H/ G2 Kdata = json.loads(data)1 T2 {9 p' p! f) J

) [" ?5 _* s" P9 N4 h2 ~( t# get the points
2 E2 S+ j# m9 I. z0 R( Wpoints = data["shapes"][0]["points"]
( n/ @$ Q- C$ R; R+ i+ j. ]$ u+ k2 zpoints = np.array(points, dtype=np.int32)   # tips: points location must be int32( c: R5 x1 Y9 x& Z
& l* \  a2 [$ _/ I3 E" M
# read image to get shape
  Y$ E( }6 E$ I% I9 zimage = cv2.imread("origin_png/person.jpg")/ F- e/ u2 s/ V/ B, b  |4 w
: |2 U/ L; g# j; F
# create a blank image; i+ X$ S; W8 u& N4 h/ C
mask = np.zeros_like(image, dtype=np.uint8)
; |) }# x2 ~4 E+ r2 P5 K$ S3 G* e% e+ v+ [: R+ Q
# fill the contour with 255' B6 L5 r! }1 a( S' X7 k( F6 ^
cv2.fillPoly(mask, [points], (255, 255, 255))
; s% ^8 O; K/ C) ?" U
- Z" F# }% }7 J5 I7 d0 g# save the mask * z5 ~' N% W% E, Z0 W, }$ P$ v) W- f
cv2.imwrite("mask/person_mask.png", mask). {' K" o; n% g6 F
1
( Y! a9 w$ x5 i; P" M$ Y2
# {& p3 r$ ?0 ?* {3 a' T7 u( o3& Q4 M! l( {4 i  O: M
4
) Q6 h7 y6 R( I& D1 B59 K& M  p8 r/ X" L; G
6
+ k. W- W' C5 w; I; j7% a! {/ J2 ^8 ~) p/ @4 a
8
3 z0 R/ S, T9 U/ M0 X9 K9
" V7 F# }8 s, z& g3 D* [9 [5 K2 Z10/ D' H/ j! O2 ~; Z& h& L8 D+ @
11" R; O8 t8 ^+ b( v
12( m/ {4 v  N! A: K$ l+ A
13
$ ^/ y8 a8 K6 d: J% W8 G14% M6 v: ?5 s  s, Y; I
15- n) R+ i& g: J2 m
16+ u( Q  `+ V- h' A- d5 K
17/ a; @7 i! P% n. y8 M; W/ j
18
- l) Q2 k5 {9 ], y9 `' F+ ]& a19) v5 q9 z1 n. _
20
' ?: ^% E) [, F& W) P4 x21- e3 {+ b5 C& ]# u$ S0 {" y
22' Y, p! z# U! P8 E0 r- n
23
( z/ c1 |& e" A: m) n$ k2 y! \24
( E/ F! X  O. W5 G! \8 e25
* w- s) I! `' Y- @4 k3 C+ S26  x3 C* F! T/ U6 \; {
大概是这样:$ N/ p9 s9 u4 u! O; T  ~! a' z
! S+ q/ W: w0 _- N3 }$ T

! F+ s& m3 F6 s8 z0 \然后利用这个mask生成图片
  i' }, z6 s' ~% T$ @
6 d6 G" M" X4 L- Y# 参考自: https://www.jianshu.com/p/1961aa0c02ee6 B2 y2 H- P) e4 N5 y, g
import cv2
$ U+ z7 y) {4 \" Cimport numpy as np8 ^  x1 l( y: b  n: \* a0 A
$ P9 i; w9 w% S! L/ C
1 Q  E/ M( r9 J' K9 m4 B
origin_png = 'origin_png/person.jpg'; ]& C& z6 \% l; O4 K
# maskPath = 'mask/person_mask.png'
/ ?# h+ q$ k$ n4 s7 xmaskPath = 'mask/bmv2.png'
4 v7 O; L( E: `! Y' nresult_png = 'result_png/result_png.png'
! g- g/ m9 p* X9 O" o
, s# w$ L- w$ ]: \+ ]
. s% L2 v; i7 F7 omaskImg = cv2.imread(maskPath)
4 W( @# [" q5 a# x) h3 x- `img = cv2.imread(origin_png)  a) y# A. D6 y* h( y8 O% }9 P
assert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'# `, [6 ?/ Y: O: w. B6 X0 G8 d
  ~- `/ L. {7 g+ \
h, w = img.shape[0], img.shape[1]) N0 i8 H% N/ @1 H
print('图片宽度: {}, 高度: {}'.format(h, w))
. T0 a7 E# d9 |3 I$ s, J) G+ U( J0 c2 `
rgb = (19,122,171)
! }1 v9 V1 H* ?, jbgr = (rgb[2], rgb[1], rgb[0])
/ x9 w5 p: H& A2 x& i, I( y# (B, G, R)
& n2 O6 ]( @* L6 N: l% Pfor i in range(h):/ @# @  h* {3 o- n8 @' V
    for j in range(w):  d& @0 e3 f4 J8 w) L# p. ]: W
        if (maskImg[i, j] == 0).all():8 h* f5 s/ K1 ^9 l# `2 }& d
            img[i, j] = bgr
" w, V1 ~; G( X. Icv2.imwrite(result_png, img)
  k  W; F" A7 H9 rprint('图片写入 {} 成功'.format(result_png))
8 m3 y- p1 J) a' F1
0 M/ y6 D- `: |4 U0 {  ~# G28 X+ M2 n' y8 i6 P
3
! x* ^* O1 I8 j, B) S4 F; }4
+ y/ B; ~8 n" v  _9 ~% h5
3 X) J/ q. v/ L8 h/ l6
$ e1 I& K2 ~  Y& f2 U0 \8 J) {" e( Q7* k$ M( w* n/ V$ O9 o- u3 k
8
+ n1 m" T$ |7 |9
5 U+ f6 U) X, T: W' Q3 z10
! s  m" N+ V" C& @& v11. K: a  w9 @! S  O" O5 E
128 M$ G3 X2 y0 b# h
13
& @1 g. m  C0 u& }/ A: a! T# I14
. w' [( ^) ^3 R! y3 h' z7 l. \15
- W' T! ~! N4 ^; c) C16
' H# L& I5 L% ]/ T17
" O0 [5 C8 [& d8 e18! Q! x* `4 \2 M3 `
190 E, t6 \8 }0 ?+ Q6 f, F" E. d
20
* ~1 H# L( g  q* m- K, V219 f# G' C) l- l* }" F' A
22
0 \$ x/ E+ d- C) D+ p( @4 v. r239 D( L' t5 a, F, J6 h6 s
24$ \8 G) K& H( ^# a- e; j% R( U5 N2 s
25' j, O/ n5 d. d- I) I7 Y7 M' z! q
26
0 j  s7 z( x( c/ E* ^. l278 T8 P( K. Y" t% ?
由于人长得一般,就不放图了…
& p) C* S3 [3 b; r+ a. g5 s; d. K+ _  S
缺点:
- C% D- U2 h% \5 R; Alableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。. `$ t6 A5 ~! T. ]2 |% D2 e- W6 D
9 d: K3 s9 y( T9 m. s7 T

2 U6 U" j" l) m) ?/ e: \7 i! C; o- `5 h' A" L/ q

: \2 `8 H" o- \+ n" N' ]. l4 u
. @9 j, T, r1 o/ f方法二: 阈值$ m5 v2 D6 l: Q1 Q
该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。) c% z  M& o. l7 n
3 y& y4 U. j, @7 t' o9 t7 a* K
Opencv& f; \* x- _5 f' U: A& e$ n5 x6 D
import cv2% ?/ u# \4 C5 q: Y% ~4 e
import numpy as np
8 O# l) {& r1 }, e: k: u" U. U. E$ x

) x2 q' u- h# p; Fdef mean_square_loss(a_np, b_np):7 X  N0 \( p" O* t8 t5 B9 s
    sl = np.square(a_np - b_np)
5 V5 q" R  k3 D& F: r& e    return np.mean(sl)
9 x. W! j1 H9 ~- o! j9 F5 \% Z& T6 D8 ?8 P

* C5 L" K9 i7 i! Q* Udef change_red2blue(origin_png, result_png):! C1 Z2 H$ R# ], _
    img = cv2.imread(origin_png)
' l+ K; h- n; n* }  o- W: Z; M' s4 `. e: j: N  K
    h, w = img.shape[0], img.shape[1]
) J( o9 z2 K  L/ i    print('图片宽度: {}, 高度: {}'.format(h, w))
% _! w4 p% L& W- Z* Y
. H: T: f6 V& V    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
% D! W3 x/ s, }' T    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
  i  z' X- c! d9 i3 }3 S! k    target_rgb = (19,122,171) # 蓝底RBG
) ^+ D( L, Z5 P* ~6 i4 K* n    target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])
9 `/ @( W  ^' z- ]* X* u) s; d/ p: @0 C8 c" e6 M
    for i in range(h):
" h: v( n, V0 A3 Y; L6 z" k% A( A        for j in range(w):
& @# b& k' V# T/ \            # (B, G, R)' b* s% Q# T. }0 I. ]% R
            if mean_square_loss(img[i, j], origin_bgr) < 50:/ [0 {+ d) J/ ?+ y' M6 _2 ?
                img[i, j] = target_bgr $ h& @1 [; S/ w9 K. a8 K2 D1 }
% \8 G1 r0 e% t$ g/ d
    cv2.imwrite(result_png, img)) a4 |' v& p) W
    print('图片写入 {} 成功'.format(result_png))
( H) R7 z1 C9 t' l
4 g- L/ {: q# {1 K' b& R; e9 a' f4 j5 F
if __name__ == '__main__':
$ U8 w. N! n, I9 A7 u    # origin_png = 'result_png/result_png.png'
" b! K- ~+ \$ n/ [! ]! x    origin_png = 'origin_png/person.jpg'2 \9 }! g6 z, ]$ @% f! D+ n5 W
    result_png = 'result_png/result_refine.png'
) M7 C, a5 A* g+ c    change_red2blue(origin_png, result_png)- K) t! _! }* }& {  c" B/ |% P
1
: P3 _. Y7 n8 }% M, O20 }+ L$ ~. w1 Z0 a1 k5 F5 j
3
* X5 H' ?" k/ _9 N+ }8 n4
  H! L) g4 @9 u/ T# ~6 r% C3 Y5
# J2 r' a9 u6 s  U( U; A6  G: e2 y4 l/ r
7
; C& ?* M, z+ O/ U9 C5 d: O8& P) q7 t0 v( p3 H- n/ k
9
8 c" J* L2 D2 d7 d1 o1 ^+ `10
* h+ ?# |% g$ t9 h' I# h/ a' V& V  s11
1 I) Z) x3 g  U( z127 z' C; _# t3 [/ W- v8 z' c1 Q3 r, a
13
5 D8 h' U( V9 p- W' a+ I! }; q! k14
! B# Y+ g- f7 x$ y; }6 p15
5 i; b& n& m0 \2 q/ v: c/ n0 B$ S16  x/ W3 u) _4 m" O
17- Y! q1 q8 z3 t: V( K1 K. p
185 x$ A& H6 b' @# w( V) p
19
0 Z- g0 b3 n' I, X3 r: S  C20" ^  P) ~* l' E. Q, T% g
219 a# O6 F) H0 l: H8 r
229 L8 C+ w: ]. `7 m
23% _1 i/ V" B9 h  l
24
6 ~2 C2 q( v/ l, q) v25
- @. K- E0 t  h9 e: s9 b8 q6 N* W26
6 L- `, l1 U! x4 j- F- W27
6 W. x9 Y6 P+ T0 m# p' v28
3 ]! ~% l, M; L$ e* L1 w+ b  v. L29
9 }- l% J  a  I8 O% y1 q5 o30& o; A1 B& G& G% l- j0 I7 P& _5 c" Y
314 ~- f7 H' \7 ?* l" h; w
32+ [: M; t4 h) w% H; s/ B+ S2 ?# N
33$ i0 ^4 l* s6 x- n" c8 ~' p5 k
344 S; s$ [  k) N7 c6 _
352 B2 K5 d& x# S# F
结果人与背景边缘仍会存在红色像素残留& s, y! m6 b; P. s: t

" r9 b1 l7 I3 `9 C
( ^3 c3 y: L: f, F9 Y
% [( S( k9 Z* y1 l; P3 `
* b8 q6 y3 T2 e
- V( l; x9 ]7 D7 qPIL
5 p" L8 f! ]# r; ifrom torchvision.transforms.functional import to_tensor, to_pil_image0 n3 ~% _% o  y# r, M$ G1 B
from PIL import Image
" W2 t9 O" v: d1 K, M5 t+ [import torch4 O. ]" t3 _0 i% w
import time
1 x- r- i6 i4 r- X$ y# r0 A/ i9 V. ~" l' Z  L; D2 T
9 e4 ~  a, v# O
def mean_square_loss(a_ts, b_ts):
/ Y5 c" T! Y! k- ]    # print(a_ts.shape)
% s+ X. ?& g6 d% u( W& `    # print(b_ts)! W% k1 V) M  o$ v
    sl = (a_ts - b_ts) ** 2
  G8 p) B" A: u  Y! N# v    return sl.sum()8 I; \8 v# ?( R2 D4 i) z( m# Z* Z
9 K  R8 N9 C2 Z8 @+ M
9 b$ o* L0 K4 e2 p' P
def change_red2blue(origin_png, result_png):
2 n4 I7 M" G" _/ N& e/ K/ a; n1 r    src = Image.open(origin_png)  s: f% w' z9 z2 N
    src = to_tensor(src)6 t( I9 o( n: `
    # print(src.shape)  # torch.Size([3, 800, 600])7 P) k! I) Z" |% u& w
    # channel: (R, G, B) / 255
% I) g+ R. W* _+ f+ S, {) A    h, w = src.shape[1], src.shape[2]8 a+ G) M( T  o% E

0 |2 o' a/ C& g    pha = torch.ones(h, w, 3)1 s# w2 {# m6 W9 K
; m( l' r. _+ I6 ?: M9 R) M
    bg = torch.tensor([168,36,32]) / 255
0 e. {! x8 l/ I. F! O, Z1 d    target_bg = torch.tensor([19,122,171]) / 255! N/ X2 L* v- M  h* m- f* |, k4 y

' M: p0 ?% N4 F$ U    # C, H, W -> H, W, C3 b# S1 W) Y& X( n: }5 ~7 R' O# X
    src = src.permute(1, 2, 0)
( G8 C4 v3 S: B4 ~3 H2 l+ w5 Z! f& u* w    for i in range(h):
3 o* E# q5 |' d* v1 {1 @        for j in range(w):/ ~/ D/ i! w- ~+ ~7 {% a! S
            if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数' N  Z( {( |' V- d2 L5 ]9 _
                pha[j] = torch.tensor([0.0, 0.0, 0.0])% d7 q- ~& C1 R- T: A: Q6 @* k

3 b$ [. }$ t3 E) w& n    # H, W, C -> C, H, W
, Z/ {5 J1 n" E# n    src = src.permute(2, 0, 1)6 F9 e! }# V1 g4 U% A5 O( @7 h
    pha = pha.permute(2, 0, 1). t9 k5 Q3 Z/ Z% O( L
    com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)
9 @2 d' Q4 v! M  f    to_pil_image(com).save(result_png)
% `2 |" w1 w) \. X5 C$ d2 i6 @$ Q" q" `/ ~
* P; |2 V7 `7 J  s+ X) `) X5 B
if __name__ == '__main__':, T8 B+ I, \  w2 @9 z+ E
    origin_png = 'origin_png/person.jpg'
+ i5 n0 |# l$ C, P' h    result_png = 'result_png/com.png'- P, {; _3 j% i; u3 ]' B0 J/ }
    start_time = time.time()! c3 P. q8 V( R
    change_red2blue(origin_png, result_png)1 w5 R3 {; H9 b- C3 M& C
    spend_time = round(time.time() - start_time, 2)* i0 @: C9 ^8 |1 R) S' ~7 O5 ^
    print('生成成功,共花了 {} 秒'.format(spend_time))/ g1 O/ ^/ }, c( R7 q
1* R* z/ n5 @" Y0 p8 b1 A$ c5 @4 d
2
# Q4 t6 s) D& f4 u3 O3
$ z" D& F8 W8 M3 b4
2 d4 \2 {. g" v7 Q: `  {$ s5
! V( O" D. b* n4 L$ L: ?1 i# t6
) @! e7 y  Q' A* E5 y73 {$ b% D) B2 D0 l; l$ x
8
2 U+ g. d8 t% D8 p2 Z1 u9
6 r0 `1 ], W8 E  [1 Z7 ?4 @101 P/ q+ b9 V/ I. ]6 r
110 g4 l  u& K- T( R: J
12
  V" S. V5 c* Q( K13
; e0 c* U0 d& l7 E1 k" e14
, `4 N; \% [$ R; W15
5 _) }* B2 X& Q, m16
$ k% V2 v/ e" c5 u, n17+ ~; |! t' a2 l* O0 Z  ]  G: ]+ L; D
18, z. ], Y, s! R+ j- E3 `3 L
19+ v2 @- g6 ^' k6 a) J
20
* ^# d* N7 B- Z# R' ?21; j; J3 r0 w) `% N% R6 p0 j
226 K) o# z/ A" |7 k; h+ o. M. Q
23* r% y5 s. |; `6 q  G
244 X3 D( `) \9 _: M! c8 n' G; _0 i3 ~
25( o  p6 |9 [0 ^# B+ z9 B
26& |/ m/ v+ O2 S: z1 u  h
27+ w* b8 E% m! V) c
283 c5 m* F  T' I/ e# ~5 S& r
29
+ O$ i3 R- b: m  ?( ^5 Z2 n9 c30$ r) Z) S3 p* Y. I# ^9 r+ [' u" E8 d
31  v3 o0 t/ Y, V6 x
32
3 ^5 l& B8 z( B" a337 K: L* G* I9 K
34. `, ^( u. `" O( ?& Q1 r
353 \7 p3 r; Y! {8 |/ D& |
36$ _4 y& A7 G" h
37
! p3 G) y% \% c- D( N4 a38
0 L) Q5 G8 O& u39; R% C6 V! d' ]/ d0 o, |# B
40
, A! v% x# \. A) |  w41
2 {/ t) X' I  {- R42
& N2 f9 {9 G8 |0 @43
( Y4 e1 D" r4 S& N( ?44' {6 W. y; y& g% o) c
45
* n) v; K/ {1 w( g) K' k9 G3 q3 b464 J$ ^* u0 r! ~( p
该方法质量较好,但一张图片大概需要12秒。
/ _1 Z* q' M6 l. B  `, z8 |( g" ~# H+ g1 q. X- V% q1 w
0 f/ x& t2 j3 H

' l# [. ^# Z6 z' u% r方法四: Background MattingV28 s  f  q8 v7 {# w6 R. Z0 F  _, m
Real-Time High-Resolution Background Matting) `/ L! q$ b8 x/ y0 q$ [
CVPR 2021 oral
% c6 J$ S: m% K! m5 `" y/ \+ X( h& U' w: `
论文:https://arxiv.org/abs/2012.07810
7 X9 H* w' g7 Q/ W- g代码:https://github.com/PeterL1n/BackgroundMattingV23 l3 L% B; L( u1 S6 ~

, w* g6 r# K2 i- |& `, ngithub的readme.md有inference的colab链接,可以用那个跑
/ u$ P+ L" b# ?, R0 H' o8 I/ X, D' c
由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。$ ?( x5 u, k0 e# Z0 z. h

3 V' Z6 b( J8 T' e' S于是这里我需要生成一个背景图片。1 b* o: h  Z. r6 q
首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。4 n4 j) `$ C' S. a, W
+ K% r# ~9 G$ T5 r# k; g6 ?
然后生成一个背景图片。
1 X% |+ O( c' [9 o
0 g1 W% f, [) e# ~# Simport cv2) H* E! o. R8 ?. a( E$ j
import numpy as np
" b7 `9 t5 p) P' P- ]: ~5 A( u* l; Q5 Y' Z4 j
# ?7 h8 T" x0 i! C6 z1 ~* h) s
image = cv2.imread("origin_png/person.jpg")
8 T* e) E3 R9 s) `' [origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值& t4 q& X/ G! h5 B4 e. j5 T! S6 A
origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
+ M3 t/ I( B, _% h& oimage[:, :] = origin_bgr( z0 h, @* ]2 n* C. n

0 e4 J; K6 U& b' Y+ J9 T% F) Jcv2.imwrite("mask/bg.png", image)
: b* ~0 x2 C' L2 W( W6 t; V3 G1
3 Z) z6 c. ^" n; K6 T* X2" Q6 o* `- S" k" U! n
3+ D( v% \/ s& I# h2 V1 d. s
4
4 [8 V" }2 b6 j  K& d4 l5
/ p4 ?9 d2 Q3 s$ K9 t" l" t6
4 Z9 u8 W! m! X3 H' E) N7
: P& x: U, V$ \6 x( J88 l% @3 d- [! t
9/ R+ [& J: d5 t+ c, h  n
10
8 z6 a& y+ e: Q; [. ?
1 s9 \8 K5 k- N7 I! p% x7 M需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码
6 \8 p3 D& P- ^! @) j
! [. O& n- b5 ^* B8 ksrc = Image.open('src.png')! @& Q9 j$ A6 ~; a. T
bgr = Image.open('bgr.png'). L  \9 C4 _0 q: ?5 i: M
1
+ Y8 ^# s) E  u. o2
" j& h9 }5 W! H0 T5 E6 i另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)
: z: e* H2 f% t& O2 i' y9 a9 X+ ~% z. N) H9 k* ^2 o, ?+ S
com = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)
6 x! ]8 q, d  `  S" b3 x1
5 B* \5 m& {, ~1 D4 R2 T
+ T5 ]" \5 Q5 B) r$ C8 Z那么加入我要换白底(255, 255, 255),就是5 f6 P* A6 X% B+ p3 F3 s
* I( _9 Z/ [% f
com = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)
1 y3 r7 ?% q" R1! i; y- P+ T2 L" I) b' K' z+ `
1 X7 p! J# G3 K( ]; |! F9 O+ @
假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是; E. t9 O, r; f# T. a; p& {

: s; Z+ F# r  h) F! F* Dcom = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)
4 m* g) O- G0 O6 M8 ~7 n' F1
* ~# l& D  O- W总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.% M6 A0 h% P# q  N4 Q  G
9 q( x, ?& q* L( F# ]
然后就输出图片了。可以看到效果相当好。不愧是oral。& e: ]2 Z- o: s* K9 C

8 S; ]/ {+ v9 j6 a( G, q! G9 j1 e' }3 t
# C5 P* k  k# Z& D原论文可以实现发丝级效果9 G. ]5 G  c( Y. ~
# `& ~! b! L, e# M9 }8 e

& M5 t6 e. ~! F, g+ R9 _, z$ }) G( c# w8 _( d( @. `6 b& W( u

* @* b$ z8 x, J$ b7 `- m& e, ^8 F( e7 I4 I) p- ^, N
报错解决方案2 G3 Q  g- ?" Z: H
can’t divided by 4 / can’t divided by 16
5 v8 ]3 _9 i; q由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。
* y, L5 H( Z8 S) w( |, x这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize
) y! e5 g1 M/ |2 S' {————————————————
. [' I+ Q7 N- ^0 I& S4 u7 L版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
  C2 h7 i( f' b; G1 S( k, E+ Z原文链接:https://blog.csdn.net/weixin_43850253/article/details/126376767
* D. f( x' X0 w3 v/ x+ R2 p$ [8 F: d/ Y; g" e, N
( ~7 b4 l$ v) p3 n3 _2 R" T+ x! V





欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5