数学建模社区-数学中国

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

作者: 杨利霞    时间: 2022-9-7 11:41
标题: python将红底证件照转成蓝底
python将红底证件照转成蓝底* P0 t! m# q8 R
前言
  X# W) U5 V. M: Iemmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。
* W% ?9 {* x* N/ Y" q. f- a9 ]$ K& {# @2 U& b0 Z# }6 o
3 ^# f5 V  w: ?! @
. _8 h+ E8 _6 O
; m1 a% g  H& t: u! d
方法一: lableme
) ]) M  j" w) @* {6 |" H% glableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.
! K6 ]" O6 \! |
% o* B; s+ ]" d' C7 @' q! H( k4 m# 代码来自 https://blog.csdn.net/hello_dear_you/article/details/120130155
3 d. b/ `4 T6 |" ^: H4 q2 |import json
  c6 V8 {6 z) [7 ?+ D. wimport numpy as np
2 U4 l8 F) F  f2 t3 i! n8 c* b6 A: zimport cv2
0 [5 [0 S1 ~7 j" n$ q# read json file( h+ f, s) x: [; R% x8 U9 |
with open("origin_json/mypic.json", "r") as f:: F( \! l) Z4 \, I; @& e$ t0 I& _
    data = f.read()7 M( }: Y- E0 \
; P1 ~- q8 |% J9 V$ B5 p
# convert str to json objs
! B% X  a. Z: ^! Udata = json.loads(data)
' @+ `$ R/ h7 j
! H' D. ~8 q6 l5 Q' d3 _: E# get the points ; L1 V8 o, [! G& a
points = data["shapes"][0]["points"]- X; b& k8 ^9 d
points = np.array(points, dtype=np.int32)   # tips: points location must be int32
2 c% ]& S8 ?0 y. Q# u* e
; ^1 H8 \! `1 |# read image to get shape! o- x: l6 U0 Z+ ~
image = cv2.imread("origin_png/person.jpg")( _+ `" F6 d6 f2 N3 z* `

( W4 S; K9 |, ~" R6 j# create a blank image7 G6 P1 l8 p& y- `2 x' a7 s- W
mask = np.zeros_like(image, dtype=np.uint8)% c* `7 i, H! @( v' D/ y
  X& @! K- l0 j" i& A  }
# fill the contour with 255  F0 l2 l/ t1 V4 k0 Z$ g* v5 y
cv2.fillPoly(mask, [points], (255, 255, 255))6 r3 Y2 K% r2 Q: W" ]3 N. _$ @* h
& N$ x$ ?+ _% u1 B
# save the mask
! P) t# ^; `$ U) \+ l/ Dcv2.imwrite("mask/person_mask.png", mask)
5 @' T6 r& L( p! T1
# k; S+ x2 |5 Q, h; G* X3 k5 b( t2% n% c6 m7 i3 D$ k
30 T- o8 F- t' r. L3 m/ \  K9 h
45 G2 K$ k" i' ~. t7 }8 b/ s
53 G( o1 T7 p) k$ q1 c" @
6
9 F# @7 ]' N$ N7
, ~/ e4 |1 G! c* E89 A, i$ m: z4 ?: j' K/ J3 M
92 ]* i& U/ M. g" T2 \! }1 u
10
9 E! Y% g. S- P7 Z# G( h& l* C11
6 f8 i2 E& G( ^" M12
, ^3 M: S  m9 L& p, |13
5 L, G! G  H; i' q; P14# k' Y( z$ |1 h% Q; {. x
15* {& r9 R8 v- v* w5 T$ M; g
16
6 J) X% _3 L2 l1 k6 Q9 q9 t17
0 D0 b! f2 F! G8 s  G18
$ Z- G6 u# D: `. Y+ i19% ~' T# i) u9 Y: \) n
20( |( {9 D% U3 b
21
- A% Z8 y" `* h+ p' z5 Y7 k6 f22
  S  ^" `  f; M23
5 }4 J& \( U$ q, V5 |! i' U% t24' @2 v6 ^, a! y6 g  ]% i3 m
255 t- |2 l+ w" ^' B' U
26
! i/ }/ b6 t  N0 l大概是这样:
5 u2 E' h! T6 _4 q+ h1 J4 }. c% U
/ d! F  \3 }. p* H* m
然后利用这个mask生成图片
; D9 o# `& H! ]2 r7 c. D) v. o$ c# l2 ~! `/ I4 A$ v9 Q2 ]" B8 o
# 参考自: https://www.jianshu.com/p/1961aa0c02ee
0 O* u" Q4 I& g4 A5 Timport cv2
# H: p% T  P9 rimport numpy as np
% W( n. q- O) B" C2 F; S0 ]' J  f" k6 n. K5 F" {9 ~

. a+ ~( {- o2 W# F* u4 Lorigin_png = 'origin_png/person.jpg') N3 O! F$ l  p# G9 w
# maskPath = 'mask/person_mask.png'
8 F: J  h7 h1 kmaskPath = 'mask/bmv2.png'
% ?& b$ O) ~% `+ D5 f% Gresult_png = 'result_png/result_png.png'* {9 k% v/ Z' G( S- [/ G4 k+ b$ ^

; T% @+ g" _- v
, C; E: S7 T1 t! m- O/ t! F* x( nmaskImg = cv2.imread(maskPath)
! M  l( x& J1 [( J- [, Vimg = cv2.imread(origin_png)& r- b/ G9 v3 G: a% E2 ~
assert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'* o* b1 e; J. n. I5 V9 {
4 t8 ~5 d# H6 R2 G% F0 @. P; R
h, w = img.shape[0], img.shape[1]
: ]$ c2 G2 `  B' l6 h) F" dprint('图片宽度: {}, 高度: {}'.format(h, w))
0 }; y2 g2 v; o$ k5 h7 `" l
/ T3 v( x3 o' f/ N0 F( d* G9 ergb = (19,122,171)
! M" {6 k! M; X0 w3 Ibgr = (rgb[2], rgb[1], rgb[0])
$ m2 O$ K  h; o$ ]* c# (B, G, R)8 d6 j! s( a1 D% [6 [& i
for i in range(h):
4 Y, ?# a7 u9 i1 }) }& v- D    for j in range(w):# ~: ~6 Q9 }" S4 _! K- I0 N$ ~
        if (maskImg[i, j] == 0).all():# E/ ?1 Y+ J1 ~1 I, C
            img[i, j] = bgr% G0 ^* x& D7 ]" M% W7 i8 j
cv2.imwrite(result_png, img): U7 m' E+ @( ~( y
print('图片写入 {} 成功'.format(result_png))
% D+ A5 j7 t& V7 D3 H0 P, u5 J$ q1
" X; r" ]* y$ s9 }% n1 A3 }2
- E& N9 ?9 L! c9 ]! J1 e3
  Z2 ^4 H+ V$ o4
7 a/ r3 Y  a- T, K  x. n58 k! m/ |0 ?* _1 {3 ~
6; f* C) k8 q# Y& G& u+ R& \
7
4 i/ g, P1 I/ K: R4 j2 i; H6 A* a8
& q  k5 G! j, Q* w$ z8 a9
' g+ F. X- ?5 J- m# ~, v10* T3 o! q1 F6 _8 y5 Q  a
11* a% E/ `5 N1 U& R& I, |# Y
12
: y( Y9 [2 v6 ^0 @) V8 l13/ n3 c6 H/ o" \  i" W! T
14
0 N: H6 R5 q$ w$ X. {6 u1 F15- }1 `, V/ D& A, T
16
+ {* K4 T7 Z# L  l2 D: m17% n0 I6 g0 M' {' c  \8 Z1 G: v; ~
18% _7 L; e$ `; ?/ f5 e( u
190 x6 e6 y# a0 }2 N3 K
20
/ s# e( L" t. J+ ?: m: U5 h/ v2 G21
8 P7 C' w: T+ z' P6 J# O8 ~22- b) h& a: F# S. y- r. s
23
" `/ N# P! @) g5 s, m24
4 M/ F/ A# x  a# b" m25
5 ], U7 _8 j, F! H2 N% v1 Z7 f. j26
/ w8 V" w( n/ M27
' X2 {. x2 W' X7 o& D由于人长得一般,就不放图了…
8 ~4 R, j2 t' |! N; |# F' z8 i$ L+ \/ A& _- Z
缺点:
; l$ ?# B% |6 x) |% o# ilableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。
4 X6 \. D; d" R1 L- I9 s5 G4 ]" U# ?

6 q* N! K% r0 ]& B- a
% P$ p  I% {1 N6 l& t: T5 [9 A7 E$ i# e: F0 D5 y$ L# O

8 s8 h+ [: j; _. ~/ U+ T4 L' Z! M6 P方法二: 阈值1 U' o! W* ]! k% d, N. N9 @7 f' J) P& {
该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。( Z3 N+ h- ]$ E+ ~9 O- L8 O) G

' ]3 r. S$ f( ?% e) t0 z. c; ?Opencv
7 @% e" F0 t4 L* y. P" i$ L  }9 ~import cv2+ o; B0 l" ?0 R7 }7 u
import numpy as np* ?3 a1 X% X5 H: f1 l' C
1 \/ C( `* v3 _
& c, p3 m- K3 h/ N3 z
def mean_square_loss(a_np, b_np):
, _$ \- O, M1 |6 I    sl = np.square(a_np - b_np)* w5 c+ w# C7 q1 {+ S( `' ?" c
    return np.mean(sl)
" B. N; I. |: s1 H, x7 f
: _2 P( w5 l  Z% m2 c6 V: R* p" E6 m  W- J, {
def change_red2blue(origin_png, result_png):8 R% D, C/ t* f9 d
    img = cv2.imread(origin_png)3 }* i/ A+ z1 q+ M) J# J
* p  `6 C! b3 X: L1 x6 A' t
    h, w = img.shape[0], img.shape[1]9 y4 f9 ?% M) T  o* J7 g- \
    print('图片宽度: {}, 高度: {}'.format(h, w))
$ @' w$ V! L. p0 n
8 j, a- ^. G& c8 F7 x+ ?2 t# H    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
$ L6 I8 W+ W% ~0 a- g    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
& K) t) Y( Q3 J0 @* U    target_rgb = (19,122,171) # 蓝底RBG' R3 Z1 k% B, F3 w5 I
    target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])
8 K/ e; u& d( i4 {  b- P1 h+ D9 y/ x* }2 M3 C
    for i in range(h):" E* {# Y3 M* K) D2 S
        for j in range(w):5 N) c1 E5 w2 Z0 Y5 n
            # (B, G, R)1 F7 e1 V4 J1 ~( u: J
            if mean_square_loss(img[i, j], origin_bgr) < 50:
: T9 G* O" N" e% e' a% u: {! [* i                img[i, j] = target_bgr
- o8 a! H! ~4 w2 G9 z; a3 ^& z6 G, g7 Q8 w- \! u+ F. U- r, [1 f9 I# q% p8 u
    cv2.imwrite(result_png, img)3 y+ n/ ]: Q' G! ^2 V2 Y
    print('图片写入 {} 成功'.format(result_png))' m( l; q3 n, n/ P3 C& w$ v3 I* v+ G

( Z1 Y$ n! s; w! v7 U5 k# q6 T- T
" `2 M) Q) b, [- ?! {7 Tif __name__ == '__main__':
. q4 [" h! h$ Z- w7 u) K    # origin_png = 'result_png/result_png.png') g, m' a) \, ]% `* f; {  R
    origin_png = 'origin_png/person.jpg'
$ U8 e' r2 Q% h7 ~/ a    result_png = 'result_png/result_refine.png'
  C. k" o, n; @    change_red2blue(origin_png, result_png)1 }) U* a  t8 L
11 z. t$ |7 D0 R" `' h
2# |8 o, k4 _, _- F2 m% ]
3
. [! Z4 W1 o' B% E( R1 p- ]45 h. ^; n2 f6 x' c: W
5
2 C% w1 n; Y% H5 K: s4 b) s6
9 S+ G' A/ p! G# q7) r: d4 T+ `: a
87 L$ V! P6 _. e5 d
9
, D$ d3 X8 E5 j; Z2 a3 w( I10
, O+ l# s5 Z9 H11
: X# a2 c4 l, M6 _: e( v  f, \12
; \  ~! b* W) F8 K, E' j" C13. {& X) b" L/ S: e4 q; ], w
144 z; O4 Q4 _/ e" @; M6 H
15/ i. T+ U" a1 y" }7 ~6 }
16
/ \5 Z/ E5 s' A5 y17
" t7 {: A4 s; b2 ]$ Z& A18
4 [# D4 {% w* E7 X+ Q8 J9 g19. d8 n4 b  }+ x" S4 ^6 C3 w
200 t4 @0 s$ |' R9 B- ^
21$ B; z/ c! O; L# A# Z5 U4 {
22
* P; H* n5 n- Y8 m% M! H0 t! e23
$ l4 A+ o; E/ L- b# V- |24& k" D) i% Z7 W" W; I* g( V+ e
25$ \& v% Y2 D" h4 ^1 M/ a- ~" B
26* H' W7 t  r) s$ M
278 B+ Q+ h* A7 ?3 q/ l
28
8 }% L! N( A" l29
$ U  M6 C9 B" F- c' W30
: d! W- e* ?$ |1 S! z31
! v8 Z+ M% |+ ]. H; t1 p3 {32
+ N7 y9 n( a0 |: n3 H2 y33: O3 J6 r$ n' y! z/ {
34
) y$ |8 j2 V7 V! I2 J7 h35
7 h& M4 n/ U. ^! Q6 h  i5 ^结果人与背景边缘仍会存在红色像素残留/ v3 Q: R/ q7 Y: b4 b6 @

5 {8 q  z! V# G$ s4 @2 r; y; k3 t5 M$ v+ e3 u/ V' A$ G' ]
( ]! l) d4 q5 I1 J' z

! ^, b1 R, h; p* \* a1 q* ?9 P' @4 @* S0 K. ^0 q3 G+ m
PIL7 j2 M' l" n5 Q6 f& w
from torchvision.transforms.functional import to_tensor, to_pil_image
8 X2 f: F2 }, C) \) q" qfrom PIL import Image7 L, f# |4 q% Y
import torch
8 }9 r& u& u) G% s) Eimport time3 ~5 _, d9 Y/ h: K% v2 b

$ _! K$ q6 P  e( s+ Y  k" N6 Z8 {0 u- y& _6 q1 B+ Y
def mean_square_loss(a_ts, b_ts):6 X8 e  E! s/ ?9 T- D$ T  O8 T
    # print(a_ts.shape)- Y6 s& F9 W4 P6 x- I6 z7 i3 u
    # print(b_ts)0 `0 M% j1 G. U0 b& r
    sl = (a_ts - b_ts) ** 2/ E: T1 ?* k; X* f8 b* {
    return sl.sum()
; P3 M7 L( f# w! C" c% i, D5 u0 ]9 [( a
- b' v. E, i  z+ z4 a; j5 q' [
def change_red2blue(origin_png, result_png):
2 R+ f" n6 B+ o. D$ ^% N$ {    src = Image.open(origin_png). [1 q. q+ X8 N1 L( c
    src = to_tensor(src)
  c1 F+ F( _2 L2 X    # print(src.shape)  # torch.Size([3, 800, 600])
2 ?! y- O! ^  C0 Z1 Q    # channel: (R, G, B) / 255- j' L; v( q/ [2 H2 T$ P- j
    h, w = src.shape[1], src.shape[2]
; Z5 p8 s6 Q+ S" c! S- {# m1 d7 X! b: M% `! W$ |* X6 y3 ~8 f' P9 [2 h1 ~7 g+ S
    pha = torch.ones(h, w, 3)
3 U/ z5 s( b, Q5 z9 Y* `1 m4 G7 h/ m  j
    bg = torch.tensor([168,36,32]) / 255
$ x1 `5 f7 ?% [' h, a/ _    target_bg = torch.tensor([19,122,171]) / 2554 |( }  r3 F; f

" `8 ]# y7 n2 s    # C, H, W -> H, W, C2 R7 Z/ }* `; R; _0 o  A
    src = src.permute(1, 2, 0)
5 ]) `& i2 T+ M$ s1 P4 [6 H    for i in range(h):1 f% T' i0 Z+ ^- N. ]( O, L
        for j in range(w):6 F# c$ {. ^. X
            if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数, C9 Z* t0 s9 K" d* q/ \, W
                pha[j] = torch.tensor([0.0, 0.0, 0.0])1 w: p" g: b' O2 p* U

: L6 m% P- K( d; [+ `* H    # H, W, C -> C, H, W
$ _* z, ~" Z& T! P    src = src.permute(2, 0, 1)
' B$ g7 C" h9 T: E1 s    pha = pha.permute(2, 0, 1)
6 }$ ?. y2 b% I7 [$ D    com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)
) C9 q8 G, i" Z! T: P. y* W( x    to_pil_image(com).save(result_png)
. _2 d% @% e# \+ `( p  \  |* c1 U
3 O9 m/ s! `% u* m0 Q/ _' v' ^: @/ K( j2 R5 q
if __name__ == '__main__':
" o: ^) {+ B% p! O% I: ~, a( O    origin_png = 'origin_png/person.jpg'
+ f- ^5 b& W. i+ m, _/ c    result_png = 'result_png/com.png'  l. j" ?0 }8 q/ M
    start_time = time.time()+ D+ ?  ?! o7 `# T. o+ [3 S
    change_red2blue(origin_png, result_png)6 p0 q% R% F# _% j. x6 ?
    spend_time = round(time.time() - start_time, 2)0 U$ t  g  ^, N# q: }3 j
    print('生成成功,共花了 {} 秒'.format(spend_time))  Y( H" X  o# D4 u8 e
1
0 {9 E% o& b1 h, }& e# y2
3 P& D) M, f  |6 y+ }8 R3% J2 J$ m2 y* u( W/ A' M2 Y# \
4' a8 E2 U" G0 F9 V7 I
5
3 s/ w/ \3 [& h' V6
5 \4 ^0 ~4 {* J7
8 u6 ^2 V4 l6 A# ^& r8
! x2 B( u2 \: g/ }7 m# b! U& P- v# `9
8 R2 V6 \$ j% z5 e5 q102 z/ Y% H# ]7 p% L8 B
11
' G, x2 |& c+ C, ]& d12
1 ~* A3 [1 ^7 u9 g13! y# b  z4 z# |6 A$ |
14/ T$ ^" A3 V) @. p& X
15" }0 R- o8 `) c
16( G5 }; A. E" ^' z' F
17
4 ^8 X/ K8 o+ ?) z& [7 Q18
* w7 U, i4 A( M: I5 U7 T19
& k, B. s2 D6 `6 Z* E20
* Y! h6 a# H" o$ y" a* U. b; m21
( {! u0 z' ~0 H4 O4 u7 M! O220 B6 k/ ?9 F7 v2 S
23
9 w+ z0 |$ d, R: s/ N24. U6 _9 H  b' x4 f) V2 ?
25
# F( r: z9 q* d26
7 ~* a+ t9 L$ b2 m) p/ |27% v2 W/ D% a0 d9 Q
28
6 ~4 X5 U) a$ P2 h8 ~! p% b$ D29
/ h+ X, Y, k. I0 x30  }' _- k7 K' g' Q$ ?& f+ O% E
31' S: j' C8 Z8 g- X9 E) G6 [4 l. D9 A" _
32
) l: g+ c6 u1 u4 u: [+ O+ A0 e33# _# E5 t. J* z8 D9 n5 x2 k& W
34  q# }+ y& P* y' ?1 X5 D0 P1 v
35
4 k1 V0 v1 z# q  l36
8 {& {+ h: t+ r2 a6 c37
& `& [. E% v+ u4 w6 D38
+ ~' ]; i( R6 U$ b39
' r& M2 T5 e2 M- ^- \" g% N40
& C4 i4 j" @2 A) k/ c8 @# f$ O418 p* C$ D4 K3 F3 l
42
- i4 }4 F3 Q2 {- n43/ V9 G: X% k2 q" |, ]6 Q5 J. B
44
: W- k" S6 x8 U" V; t) [7 H6 O45
( ]0 q/ u( P: N+ j) B- q! q464 ?/ a# f4 b% A' k, u) F
该方法质量较好,但一张图片大概需要12秒。* N5 n( I$ u, n3 J+ P: x8 p  @+ C
  h/ N) M: C6 D9 E7 E9 A2 J0 S
* |6 F' w# }1 T% N

3 ?9 t' B+ @* d1 ]- O- c方法四: Background MattingV2
3 u- }' s$ P7 |" G$ lReal-Time High-Resolution Background Matting
" b+ S* A, U1 q* h0 a) N4 ^CVPR 2021 oral
- @# ^, ]7 R4 }, d
+ }! z( _- V& P8 N论文:https://arxiv.org/abs/2012.07810
$ H) M/ x0 t2 x+ f+ r" ^2 N代码:https://github.com/PeterL1n/BackgroundMattingV2
/ x! p6 }+ D5 O3 V3 m8 h% Z, {; V7 ^0 o
github的readme.md有inference的colab链接,可以用那个跑
$ ^' ]' k5 ?+ _, B* }
$ r$ q5 u- j6 I/ f7 ~2 L2 J% `由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。
* z3 s; _# k2 U. R7 R4 R) X' V# r6 g& {' `3 ~5 h# M- L
于是这里我需要生成一个背景图片。
; R! z7 g; E& ~. l5 x; F首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。
! H! ~+ I. x: m8 z; f# C; b' u, M4 ~5 w7 u
然后生成一个背景图片。4 W4 v) y2 [  _! ?( d- r& c# Z: J
( S$ d: w: n8 ~% g" I3 R$ n
import cv2
: s6 Z0 G4 C; @9 \( Rimport numpy as np
- K* X( s# ]: g, r5 A* X- H7 h0 I; b  b) `4 c. t
1 n" q) q; j' h5 f% a+ v
image = cv2.imread("origin_png/person.jpg")
( D7 q- D5 A- s$ P& D! A0 l2 uorigin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
  e  y" {2 T- P! W1 A: U7 Morigin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])6 `" {  F% e5 ?
image[:, :] = origin_bgr
+ }5 v. t* J9 s: P+ Y  v) z, x' _% u) i( \
cv2.imwrite("mask/bg.png", image)
; E$ n9 ^6 i. i4 g( D9 Y10 p5 b4 X' l; ~0 j; b
2% ~+ q! K1 M9 m3 g1 X1 Q
3
. H2 V2 v9 a3 |5 H% D4 C4
% L+ G7 d( T. {! T5
. Q# c6 E" U; I6
" p6 W, r* _: ]" x/ F& X% a7
, Y8 o1 D9 S! s+ q: |5 |! s8 ]82 N( k: ~& P+ P
9* }; W+ W: K  ~0 `* g
10
5 A2 T+ D6 J3 b
5 v0 ~9 x! h7 u需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码
) S( E7 d5 K* U# e% e- p* ?. a5 t- l
src = Image.open('src.png')9 U1 Y6 U* V9 `6 L+ S
bgr = Image.open('bgr.png')1 X- g. }- S; j* R% A& V9 v9 ^7 n# t: ~8 }
1
% n9 g8 y1 o' d, v  Y2 U20 T% ]7 F$ N2 B" g7 d
另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)* b/ n) U- w9 i+ i3 ]
% V3 j- s6 M5 [/ J$ W( M
com = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)  T4 ~7 s- E7 b7 O
1
/ U, m3 a! ^* {( u/ R! z. x
0 P- @7 R7 G9 w* N/ ~; x/ v3 R那么加入我要换白底(255, 255, 255),就是
& ^- t3 e: ~  f& x( z# L- [# i
* W0 m: P% J2 N2 X, Z+ g. d# _com = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)8 Q9 s4 Q5 H8 y. m% x
1
8 V. k1 L6 ]; y* M/ Q
# Z- d2 c" u" b; T3 J/ A- k假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是& d! ?! x' H7 d; a. H0 s% D
5 B8 F- i1 N7 K
com = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)' K# j7 F9 C5 c* P+ N
1& I! m; k' Y4 s8 m
总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB./ s+ d7 N' m- B- A8 [1 R

( }2 q7 M6 P, Y* W然后就输出图片了。可以看到效果相当好。不愧是oral。- \4 y3 ~* g! A9 i/ K# P
& ]  @+ ^3 N6 {5 ]- z

* ^! w& [. ^3 K" s8 ~. U4 A+ z原论文可以实现发丝级效果$ [2 H( H7 r# I4 R' e, {0 T$ |
- r1 }; d" r( O, t1 ^% W

4 N7 J. [- n$ p6 B* w3 d) v- R" k( I4 a2 }1 N8 g( [

6 O0 X! x# t8 d5 C1 u$ d
5 s! r/ }8 R$ a: ?9 H$ Q报错解决方案
5 f8 t6 M; z5 e4 ~0 [# r5 \can’t divided by 4 / can’t divided by 16! Q( b! b4 F: T# g8 L
由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。5 d* b7 _; |' J- L  f5 W' r
这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize
) l/ ^8 [) l; b. B* F————————————————- r. N7 }# W. D2 c3 o
版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
; u' I* ?2 s4 e1 H+ p) Q原文链接:https://blog.csdn.net/weixin_43850253/article/details/126376767
# o0 m! g; A9 v2 O9 S& B% T! N2 ]1 C% o: V8 F
+ s( H7 b' _" E9 f# A, u0 N( R





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