数学建模社区-数学中国

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

作者: 杨利霞    时间: 2022-9-7 11:41
标题: python将红底证件照转成蓝底
python将红底证件照转成蓝底
* C+ f6 @9 i. x5 X* D. E前言; i" f2 c: p9 O  R& j8 I1 \1 ?
emmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。
# P0 d% _! J  n  Y+ z: ]7 U2 _5 o# [' _
$ @$ z2 E! }' ]- Q% k+ s. B

( ?. r7 O# B' [$ q8 D: G- v0 i9 `9 t3 f0 T5 k' b) z1 ?
方法一: lableme* Y  r) `) S  y9 `
lableme标注完后。得到一个json文件,然后将这种json文件转成掩码图." ]! ]$ v2 K$ C8 j* ?/ h% o$ T
4 n7 }2 G4 O& \4 c, H/ Z& N
# 代码来自 https://blog.csdn.net/hello_dear_you/article/details/1201301553 q5 q# j# H1 j3 ]2 C' _* R
import json
0 v, n% ]1 E+ j$ c; U9 Cimport numpy as np
4 m2 p3 Q: ^$ c4 [* k) T( Timport cv2  c) X0 I. [. @- ~  d
# read json file1 o* t  M. }' V" o1 Y
with open("origin_json/mypic.json", "r") as f:
9 ^; r% Z2 t  E# V% ?- g. }3 u    data = f.read()
* F; w) l% X# f# F$ v/ Z3 K1 H6 o* [7 R) O" ~7 G' j2 ?: e0 O7 a  L
# convert str to json objs
  c+ q2 I% c9 u! S* [3 Cdata = json.loads(data)
/ i3 T  m+ \2 \- {& L2 R1 V7 P! [$ Z0 Z+ X* O. {
# get the points
( H6 H9 a% K- V" Hpoints = data["shapes"][0]["points"]
4 A, F. s: j+ ~4 d. U- I: N2 |points = np.array(points, dtype=np.int32)   # tips: points location must be int32( @; h9 t5 B8 E1 w& P

3 b" w" O7 w; M7 {4 r$ V" d" O# read image to get shape
5 r; K0 a4 e6 ?' ]image = cv2.imread("origin_png/person.jpg")8 t: |- |4 C5 ]+ @
9 r2 _  V, [) Z- ?' [# ~& \  i; K$ R/ H
# create a blank image
. }6 l6 L2 E4 C* \' Omask = np.zeros_like(image, dtype=np.uint8)
6 ?0 c  e- m1 y" C; ~* R9 W6 g
7 s# O- o$ R, s* A% I# fill the contour with 2559 @; j. [6 z* W: M
cv2.fillPoly(mask, [points], (255, 255, 255))
8 @. r3 B1 o: V* o# P$ Q& |% F: q9 k8 h
# save the mask
* t1 y- y' t6 q/ H: j1 k" dcv2.imwrite("mask/person_mask.png", mask)5 S9 \5 L2 M  M; D% ~* C' {4 q$ q
11 v+ w9 s9 D* B, p1 m
22 P3 N1 e8 p& f6 z! N
3
5 Y* a4 P; [9 Q" J5 O: G4
0 Z% F" L/ |7 u; [( ^4 b0 ^57 j% H/ c& I# k$ b
6
' d* Q7 h; c; j; G7
: V  G/ D- @9 u88 {+ t* y3 N3 w& b; i
92 Z, F: h! b" \2 [3 p
10
3 i$ O5 V. {% G11
# b* B8 V$ x* [/ N) J( I12
0 G( f. {$ O9 `+ z/ j0 b4 ]! d13
$ x& ]5 B: }9 d- Z! A14
9 I: U- b1 T+ W$ ~9 d155 E& ]! R% N4 ^  p, m. |
16; t& \% ]- j( q- ?$ p9 ?7 ~* v
174 {! T* U( i  M1 p0 e2 d) @6 O
18' r; |& s: L0 v. e# k( Z3 Q; }" g
193 w  s# c0 e0 `5 y8 b0 t$ @
20
. H- w+ I  m' k5 F6 ?, r+ C21; }! ~# x* C& v; {9 B
22
! i0 v9 g3 I0 y' w3 u+ O23
1 r: _  K% ~+ j$ j" A248 h* Z0 J! x2 r; J0 O% ~
259 a: R+ Y2 X3 j1 A: X; [& t. g
26
: n: }" o2 z3 x1 @0 G$ L& M大概是这样:
) ~  |, Y- C# s, l$ d8 m
- H' c1 v0 i+ O, Y1 r1 G, }; e: }) t5 c* e3 T' q; W
然后利用这个mask生成图片6 L/ B7 n3 W! _9 X7 p) j
' U6 C6 X& W7 b
# 参考自: https://www.jianshu.com/p/1961aa0c02ee
( `' x2 D0 A: n  L1 `4 ~6 a& i- Bimport cv2
9 s8 {5 y; {0 s& Gimport numpy as np
2 ?: H+ s, V  R( r- |
  k1 ?, k% o8 M9 K- ]" T/ s2 U! B1 X9 h/ b! e
origin_png = 'origin_png/person.jpg'/ M1 k0 h9 g) Y' u  [/ \' D& O
# maskPath = 'mask/person_mask.png'
2 J" t9 n: T. a0 m; gmaskPath = 'mask/bmv2.png'/ Y' M3 L% }" c0 e7 j
result_png = 'result_png/result_png.png') r1 w5 D; y+ F5 h# ^& \" D. X

5 D( t% S* U: W8 x/ s/ }
  q! ?/ Z$ {4 M; E- JmaskImg = cv2.imread(maskPath)1 m/ L  D, A6 O
img = cv2.imread(origin_png). h- e7 z9 u/ q
assert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'! J3 p" {& m: ^
- k% F/ A5 H! y( M
h, w = img.shape[0], img.shape[1]
9 }+ a) b* E" n/ ]4 y! J& U. {1 i7 mprint('图片宽度: {}, 高度: {}'.format(h, w))
$ V# v3 q2 L( U7 n% z) i8 ~, z$ n+ Y9 q1 E: ^
rgb = (19,122,171)/ j- y+ O. p0 a9 r7 w7 b9 M' F7 K' K: E
bgr = (rgb[2], rgb[1], rgb[0])
! U! R+ i+ B9 D4 s  D# (B, G, R)/ r% {+ T, e( \4 n2 j) q
for i in range(h):. s3 n6 g  s' F! \2 [$ @
    for j in range(w):
, J6 @0 o7 ]7 t1 {2 o        if (maskImg[i, j] == 0).all():$ A3 w! K7 B/ Q9 L3 p4 P3 O+ v4 I
            img[i, j] = bgr. O8 q' h( Z0 j2 D4 O
cv2.imwrite(result_png, img)- t# O  ], A: N& u* z* s' g0 c
print('图片写入 {} 成功'.format(result_png))
. l$ o3 P4 w( u2 x4 h' S3 E& r% T1
2 z4 i! v+ _( g9 U7 t0 c/ w2
3 g5 N  f% [9 K0 ^+ @3$ G5 ^3 r$ p+ Y# N9 R2 l* g3 A
4. b9 v. J6 }& M: x5 c/ [  l7 v
5/ h% A/ z/ ]; x
6' }4 N. i0 L9 c9 `* Z9 p6 S
7; u/ O6 `+ m) t, c
8
! R4 u- z- c8 u$ y9 a& C: P9
9 S4 q/ {1 V0 ?; }7 M1 h10" T  h7 l# b- Q) @$ t% Z
11
8 E7 D% K2 W' b- R  i# O121 q( P9 H3 `4 I4 p/ g3 Q8 y' Q
13$ Z$ K0 P9 J. q/ K, [7 {* G
14
/ N8 b% _; K& E( T- y8 J6 }15
1 \/ p+ c7 H2 T8 J4 c2 f16* }. Q$ W# u/ Q0 L( F) Z' c9 u  V4 i
17; \; e, f, b- f/ r8 K1 L
18
# _5 S" R, I0 _; C( b# T( S4 Q9 r19
+ ~3 I8 v7 M- l5 G, g% {20+ O+ [8 T0 Q* G1 W9 \
21
, R- ?2 ?) `; ~/ l9 A9 R& c6 A22
6 q% C4 z. \' A% o! d23. E* b. w" |5 U& {/ D; K
24
0 a1 E& J( y$ z$ Q% u  w' [25" t* q% l" g; T' Z3 K  @
26
5 z% ^$ E* E) n" ^( ~27
1 q2 A. X+ x- _由于人长得一般,就不放图了…; w0 K2 ?! O8 R) @, u0 A

9 z: S- g/ h" z" |: m缺点:3 v$ O# N: b$ d0 \/ r9 j% i
lableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。
' `4 E0 F! T! a. L1 s9 a# h8 g0 X5 Y

4 x1 ]6 c) H6 U% y4 j
; S, O0 m3 }* `% {: J4 u5 J& X
1 @3 C' f* P& R4 w) ~
- ]8 ^/ g& L) T5 y/ y方法二: 阈值3 s5 \; u/ O5 A7 E0 j
该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。4 p+ |$ P: v# `/ l# p4 ~  F
: m3 a$ Q, a9 ~0 c
Opencv
( Q! Q3 V2 w+ a" c! @import cv20 I2 E1 {7 z/ p1 z: v
import numpy as np8 f) }+ e2 a, A. @

& Q% V( j* d% r, f* r$ x
+ x( g, r& ~4 G! ]0 u. Kdef mean_square_loss(a_np, b_np):
2 ^3 ^$ y, M/ X) R" T    sl = np.square(a_np - b_np)( _! d1 X8 d+ m" @/ Z8 A9 V2 g
    return np.mean(sl)
9 E: q, s9 r2 B& Z2 x8 s4 ?0 @  O7 g9 X5 E3 V

6 k! K1 V" b' x6 ydef change_red2blue(origin_png, result_png):
9 K) Q: {" O4 Z4 j' ^2 n$ _% R    img = cv2.imread(origin_png)
) }! `+ A0 a5 M& V; g+ F3 K  i" ^- S* \0 W! @+ d
    h, w = img.shape[0], img.shape[1]
+ {2 @* i) J& E* @; Q. n9 P    print('图片宽度: {}, 高度: {}'.format(h, w))+ k7 F+ u' X/ R
! r. K5 ^0 w/ O( N
    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
3 g9 x" G! ]* j' k, \" l    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])4 W( A" Z7 S; M+ X" ?
    target_rgb = (19,122,171) # 蓝底RBG
9 r! y/ C& R* Y6 _    target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])
! P2 C# Q) v1 A6 a; h$ G/ U0 P& [2 N# C. C
    for i in range(h):
5 \' Z6 Z8 E% n' V0 e$ T        for j in range(w):
) I- C5 J+ O8 j, e5 S. z6 Q            # (B, G, R)# k% O+ ^  r/ L* x% }& Q5 O
            if mean_square_loss(img[i, j], origin_bgr) < 50:
, b0 r  M2 ]% }# N                img[i, j] = target_bgr
# \4 R$ n) n; i2 i/ }& q, Q% x% s; \; P+ K: j  o) v: G
    cv2.imwrite(result_png, img)1 M% P9 S) C! {) x% j
    print('图片写入 {} 成功'.format(result_png))
! D/ o# W' I  u" n* V8 R2 h8 Y6 l1 S) Y6 ]8 d+ T" l

& `0 {+ S+ F, i: W0 vif __name__ == '__main__':3 \2 W6 l; P: B. [( ~# H
    # origin_png = 'result_png/result_png.png'
; b0 `  E9 e0 o; j. E! R. v5 T' I" w    origin_png = 'origin_png/person.jpg'# s$ J& J8 D6 i, o, D( h
    result_png = 'result_png/result_refine.png'# g- X; J; K  ]6 r
    change_red2blue(origin_png, result_png)% i* m) J. b/ l
1  H/ U: F6 {  d
2
! G9 |/ A: R# S  M3( H; t& \3 P" |  z$ r9 \" n) `- X4 D
4
3 H! F. U* o# B5
5 x- m% U% k  k2 ~6
; L8 _/ U( v2 H& G9 @  e! M7
, N+ ^. c% k7 R1 j  F8
! k9 M/ d" u! \3 E* b& b9* c$ \) |' k$ X) h
10. m0 }+ e; D# k" W+ L4 L  k" x
11
6 V2 B" M: E5 M/ x4 q& k* R  X126 X. }& ~+ i7 {3 n0 X4 m
13
7 W' u, N% c: F+ E- K- @14
2 w9 \0 u. C4 W* f/ c3 x151 z$ D4 U3 m. {% `: f3 c/ [
166 m5 N& d+ x- B! {1 p
170 t# i) a. `& }; b) T; y9 I
18- Z: T2 p& i$ U; N
19
. \8 k' R: w8 w" w  Q; P6 z20$ w) ^" y1 W/ v4 B/ U- R: k% w5 V
21- C8 w1 \7 |$ `/ D
22$ F  b- T' \& [7 u9 p
23
. t0 T2 |: U( l! F& n24/ I8 S/ J' A& `) G* V
25
* W' n& z9 {+ t6 B260 J! z) o6 J; \* ]
27
/ x9 f" N. R( w28
' [" {0 j" O' f3 O292 }0 C/ a( s/ F( P
30
9 y+ v. L9 U! g! f4 B31$ P1 i, R! u$ G7 [" H
32
: t0 o% ^* d3 j* P8 g0 b& K33, t* d& G5 c1 w6 L$ v" ?9 ?
343 x( \  ^& [+ M& u/ L7 [
35; e" K# n; C8 d) x1 ^; i
结果人与背景边缘仍会存在红色像素残留- ]" ]- n  Y2 J! V

! a! C8 v8 j9 Q
, U/ }: m& f9 i9 U* N
/ Y: o/ g. O  L7 `5 z9 p* F+ V. R% {! F  U2 N9 y0 ]+ [, Q
9 j8 o) p6 y: _2 x1 N
PIL7 G* W5 A! J8 \4 |/ F, \0 \
from torchvision.transforms.functional import to_tensor, to_pil_image
* U% f7 \& N4 |  g% P/ Wfrom PIL import Image1 i& l5 H! C" K( d( @9 l/ b( u2 x
import torch; T9 d: ]5 G1 _
import time) f# e6 v+ Q' y6 k7 `: X/ }0 x

0 I  }0 M# ~7 d2 Z
6 O. n) y! Q7 J, v( Q, Y: ?3 Ldef mean_square_loss(a_ts, b_ts):- f( y9 s. ]& v; x& T4 ~
    # print(a_ts.shape)# n, O: }  U7 ]3 w0 `; Y
    # print(b_ts)
9 x  g* [4 g, X- T# V    sl = (a_ts - b_ts) ** 2
. s1 K7 j1 ~7 [    return sl.sum()& z& O6 {, ^9 Z7 f
$ N% S* I5 v0 ?/ t4 v, b
/ z7 \6 Q& d4 `; {! E3 V  j2 b
def change_red2blue(origin_png, result_png):( {& u7 s( w- ?/ W! {" }
    src = Image.open(origin_png)6 d# \" F8 Q# N1 k' K  u5 F6 V
    src = to_tensor(src)) `- s+ ^- s0 }/ \% N. i& I4 M
    # print(src.shape)  # torch.Size([3, 800, 600])* W2 n& n+ A8 L$ u& w
    # channel: (R, G, B) / 255
0 r# k) a! \6 J, O2 W. e0 \; [    h, w = src.shape[1], src.shape[2]5 Q3 A* @& O6 x. I8 A' j

8 P2 o; t5 ~0 P7 [* u9 D- ~3 I" ^& h    pha = torch.ones(h, w, 3)
* t9 D6 g% X' o
$ `  I3 q( t! ^    bg = torch.tensor([168,36,32]) / 255& v' J4 a3 i4 _  j" x
    target_bg = torch.tensor([19,122,171]) / 255
' S: X1 p& v- i
1 ^) Q! I% M' u+ p    # C, H, W -> H, W, C# M! d5 ]) X5 V1 Q
    src = src.permute(1, 2, 0)) ^2 E3 o; M& ^9 \3 c* T
    for i in range(h):
5 U9 U* L- r# G        for j in range(w):
! [% d! i" @$ N/ v0 v- \; v            if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数
$ k. i( |0 e. ]- {) C                pha[j] = torch.tensor([0.0, 0.0, 0.0])
' M9 o% \" N7 u8 f$ f+ C' ?, Y* W. O5 K
    # H, W, C -> C, H, W: w, J) f  M5 p9 Z& O
    src = src.permute(2, 0, 1)
! l- D, N8 M% E1 b. P. h    pha = pha.permute(2, 0, 1)  I' S$ a& s9 Q
    com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)  Z1 a! U2 S; a$ m# P# y1 x
    to_pil_image(com).save(result_png)7 `2 {* y9 x9 n% j" B2 g  X
$ }, s* F/ C4 t% s+ W4 Y, Q

1 [1 j* ~$ D) W8 e5 r! N4 |if __name__ == '__main__':
1 }+ m/ a+ J' H    origin_png = 'origin_png/person.jpg'0 ?% t! I( k, _. ~/ `
    result_png = 'result_png/com.png': W7 j: O$ z& L9 t0 [  b
    start_time = time.time()
% a; `6 N( C/ {/ B  ]' Q3 w    change_red2blue(origin_png, result_png)
8 \# p. d! b/ b; s& }4 s    spend_time = round(time.time() - start_time, 2)$ s! f% a. l7 a8 f; [
    print('生成成功,共花了 {} 秒'.format(spend_time))
! j" y# u' k) A5 k9 n1$ h5 f$ o. q" l7 b
2
: ~1 g: X% c# w& H* ~) v' K% f+ P3
; ?/ \- t; l* @! O9 s, C41 S) L9 R% Y3 e; a% t
5! B- q1 m) q+ U( x4 o2 C
6
% G- h$ t' ]. i* w5 n% P7
$ E" c1 D2 s7 ^. h3 b! w8
2 h# A1 G( p/ z4 _* y, _97 N2 i! G4 k; A
10
/ v. {( h1 g% ]- m/ B" q11
5 g% V' u- {9 A7 r7 g0 X- u12. M, \5 m2 |1 H, O
13$ d# q( b7 A& d8 y$ b
14* n5 \) @) G$ d2 ^5 V
15
- A- W3 y' P6 T; o' E( ~16/ y/ w& l  c7 Q8 X
17' @3 p4 r/ i1 V* o( K% s
18
( [( S6 O5 |$ V7 [195 l/ |  ~2 N. v. u
205 m) t  J3 S+ Q
21. w# y7 E# ]* \, w- h
22
+ N; T8 ?1 S& H239 F% N- r, x4 e$ M
24
  |9 I9 A/ L  T0 _* }/ S25
5 }5 m) A* m' m* ~26
" |* Q& _" m) A! u4 a. f) ~27# E9 I/ C& U0 \. ^1 O  m: [2 b' _
282 E9 l8 M4 N% ^$ |2 x3 a8 W, W& M
29, W* ?. Z8 C) S
30
* J3 [, ?8 R* d' ^0 K; H% v1 ^31! |. a* G1 [) L' ~8 B
32
) X5 ^! j4 v3 L. }33
! p0 ?* v: @1 v6 u0 G9 d342 n6 Q8 c1 B' G' \% o2 ^9 L& q9 a$ Q
351 l! |$ u" z. y+ K! o  i+ c: M
36
0 A' ~# T# q7 D. w6 F1 M6 R0 M; E37
$ {2 {& W5 V+ ~38, V4 s/ |( Z: m* `; C
39
. g4 R3 H9 f2 v: Q0 v/ |40
3 g3 U/ _2 Z' B41
* \, {' V/ a3 q3 y42) G. V6 }- `0 P/ \
431 g3 n' t: ^3 y
44
  u0 u" @( b) Q1 F0 I( h45' D$ @: I4 ^/ A: i& n2 w4 r
46) a& A4 z# S1 i* J$ l; C0 n* D0 Y
该方法质量较好,但一张图片大概需要12秒。7 ?" j$ `& D- |. b+ |" _; K. G

5 H0 r& f$ k! O, y& c0 S, j' ~  O* ?) `( {* {! y

; B& _) Q( h" O% X$ o方法四: Background MattingV2
& j- U0 V5 Z( wReal-Time High-Resolution Background Matting
$ i# v! t# J* n% ^! N% u; A% [: H$ QCVPR 2021 oral
5 V8 `' V8 e7 h- |" t- y7 C9 ]5 H$ c0 ~- U5 W& ]. H3 I
论文:https://arxiv.org/abs/2012.078105 X% j+ ^" m* B
代码:https://github.com/PeterL1n/BackgroundMattingV2# v: X+ i& r+ N3 d( e& b; k& c
2 ?0 B1 d* @* D
github的readme.md有inference的colab链接,可以用那个跑
. c' j- Z, ]4 X/ C- a, R$ f$ @' i- a  |7 ?/ L  h$ {1 z
由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。
  E. K4 [; v  O* L% `2 c
2 v; u3 o& A0 t! f) E8 x于是这里我需要生成一个背景图片。
+ n- ]5 w# {' @, p9 G; O1 b8 g9 N首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。
8 P+ b# [" u9 U
5 c: J+ w( N6 u5 S- V8 [+ j然后生成一个背景图片。7 D: ?5 V9 d; v5 R; L. R$ h

9 f- w- }" ~: himport cv2
7 a. p) b+ r+ A( P& L* o% Limport numpy as np
9 ~; R- k% M+ ~8 T" F
) o2 \0 [: U1 b' }: ?: o* @
/ V  i- @5 p5 s6 zimage = cv2.imread("origin_png/person.jpg")9 O  f2 ?5 m% l* B- K: Y
origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值1 X' s& d! i$ T, ~
origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])' ^0 \9 C( |3 s0 q& T, U6 r1 f/ x
image[:, :] = origin_bgr
$ e0 u, J; L! j6 G- \) \1 C- Q
# s9 c9 ?, i9 `$ [2 K; [3 p* ^cv2.imwrite("mask/bg.png", image)
" I/ s" ^) |5 A8 R0 k1
, u" x- x  D- Y* k+ S! h/ V* a2( I1 ~# e; j; h& r* W& F" x: |
3
0 ?9 V! y- @5 X7 j4
6 v' w; i3 X) L; Q: g) h" s/ J. _$ Y5' y5 U" Z' N8 i3 Y3 ?& z3 ?0 K
6
6 \; S5 Z; J. u' p/ v7
4 r2 R9 w& e+ D! A! A8% S) V+ Z0 U4 X& T: c7 q
91 v' l7 _8 A) |0 x. v2 Q
10
; N; {: A% S# z$ W
7 E- g" e: k" {3 w6 q6 m0 {2 f需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码
' G4 q, i) n2 T" U; N4 H# Q* J: N; T( J0 j8 Q% }& H
src = Image.open('src.png'), c# H6 u" L# O7 O( h
bgr = Image.open('bgr.png')
/ b" x) \1 w+ M* p- X1
9 i' u1 Y( _, q$ N4 m23 p! l# f  r& k2 y( {  H
另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)
6 w  N/ t7 S& e2 F7 j8 A; }
/ P) s5 s! B0 k. f* O6 hcom = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)
+ U$ v. M  J8 l! b1
3 K0 M2 f1 q: i: Z" U
: L  }( j( ]- w% q9 ^5 \( a, k那么加入我要换白底(255, 255, 255),就是' x) d& M+ K  [0 _# Q

4 O+ L; p1 h4 J! ?1 Pcom = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)+ I( _4 z% ^" {  [7 W3 q: U. a& w
1( R1 Q( U5 d0 _9 W5 _& s

( w4 c# ~2 G% D- `, x假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是3 R( T. ]$ `- D4 p6 Z" e

8 J# g' j: C7 m8 Wcom = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)- H3 B/ _, m6 j# }
1- E( K& Q) z; I: [& [( X% g- ]
总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.7 n- W! E' r' U/ |8 n
0 n( ~7 K- u0 h$ K8 B* A0 e
然后就输出图片了。可以看到效果相当好。不愧是oral。
8 f- n8 |1 E- s* j4 I: x9 W
$ L; w! `$ F3 X
& p# Q! H1 n% i4 Z' v3 \原论文可以实现发丝级效果
- z/ Q' Z6 v% l
8 ~& c( {. E$ }; c7 u! D- m- c7 Q# I9 l% S( p

, ~9 i& E! J+ n7 A8 \: B5 ?' n# ~3 g
# T4 I: ?; k8 m% E' ]8 c6 o/ R/ g" H# M5 o1 n1 o5 ~
报错解决方案( s, `! g: C1 P9 y0 `$ }0 Y6 o
can’t divided by 4 / can’t divided by 16/ _* I3 y2 A' Y% ~+ @# e3 Z, E3 R
由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。$ b) {$ c( S' I8 O5 I
这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize
( N+ C5 @) f# d1 r& J————————————————
; ]+ o& a: M! B$ W版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。4 ^( e' h5 Q& {5 a5 l
原文链接:https://blog.csdn.net/weixin_43850253/article/details/126376767
2 x$ y" C$ r  }6 c( O8 J( p( z" K. b2 Q$ x: Y; o8 d1 |# k, U8 L6 f
' |1 I) X0 @9 D' \





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