QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2088|回复: 0
打印 上一主题 下一主题

python将红底证件照转成蓝底

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2022-9-7 11:41 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    python将红底证件照转成蓝底! O$ e9 [4 G" C8 c0 ^
    前言: g. L, s5 j! N' a* @: I8 F
    emmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。# W! U" A$ {7 n3 I- K
    : r( ?3 d- A" o; [9 T* F- L

    " \# E' l2 d, V9 I+ ~* P
    - g' n+ \6 J( d1 Q$ ?
    / u6 c% G5 w: v2 C4 L方法一: lableme
    ! e1 G3 R, n+ w- jlableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.; r; |, h! v- n4 h8 W! L' b: o

    ( v* t9 g% C: {; Y/ `# 代码来自 https://blog.csdn.net/hello_dear_you/article/details/120130155
    - ~/ w) p% ^1 D) d5 g7 R5 X. Q/ {! aimport json# Q; L; `1 W! I( R& G% o
    import numpy as np( U, {3 s. N; m2 w8 E7 [
    import cv27 N4 K  h) L0 I$ ~( P1 d
    # read json file
    * D; i! V/ {2 ^; J  q' Mwith open("origin_json/mypic.json", "r") as f:9 F0 r2 E- K9 P: ^. X/ n
        data = f.read(). I6 R, x5 F5 s& N& j; [0 ?# s

    & ~  u0 U. |, Z9 e" X3 X; a# convert str to json objs* [+ l2 w# D# {% `3 V
    data = json.loads(data)) L0 O- Q2 u# A  k& a
    ; R% Q% a+ l  `
    # get the points 1 w" h" F# W/ Q. l+ h: O: v5 l
    points = data["shapes"][0]["points"]8 O  I1 K  q5 ]* p" |% [6 ^0 z
    points = np.array(points, dtype=np.int32)   # tips: points location must be int32& }8 c. C$ D2 ~* {, _
    5 l! h1 ^. W- K8 ]! u- H; a
    # read image to get shape
    5 M2 I, y3 H) C2 V/ [( |' eimage = cv2.imread("origin_png/person.jpg")
    6 {( k6 p  R( J, t
      y( W/ Z4 @$ Z6 D1 O8 Y( ~2 S# create a blank image
      J( Y, q; w+ k% Imask = np.zeros_like(image, dtype=np.uint8)
    : B7 {% U  k$ G9 L! P. ~3 v5 K- N0 t' r# s* A, M+ Y
    # fill the contour with 2556 R9 V; h4 \( B) B" Q% R* C
    cv2.fillPoly(mask, [points], (255, 255, 255))
    6 R' D/ D* w. N: m8 v
    - x+ Z# d9 X+ f# save the mask
    ; K& S/ L9 k5 H! I4 x3 _' U: vcv2.imwrite("mask/person_mask.png", mask)8 a( M9 K1 p/ W
    1
    - T' H" |5 }+ \, G9 Z" L. d- k- J2
    ; l" v$ v* ~8 Q% z3. e( J" k% u) V
    4+ x6 {- n  j- a/ _* U( w
    55 \- T' `3 P9 x
    6
    7 ~8 j8 ^: E( m, p7* _/ n) o3 G0 l  z
    8
    . R9 {; U$ d2 f* O9
    ' H: ]- ]5 V& B  e10' A2 ^! F6 `& |# I
    11
    + s5 B% p9 C) {121 Z9 F, ^8 I& D: O5 h. E
    13
    4 |8 h5 h+ |# O7 z6 N7 o14
    6 }8 Q2 H+ w3 o0 m+ P1 B( G152 J8 k7 W3 E: ^7 \
    16
    , J+ p9 |/ W  @# V  W17' m& _8 m# ]! h% B
    18
    ! X+ V* j5 f4 m/ u5 g. b190 c1 }$ Z% c1 m' E" u  P3 f' K
    20
    # A; f+ M+ X: Z! U! q210 U1 n# D9 i0 N( w3 G" m
    22
    8 p; L% U. x0 t, _5 W23
    / T0 M+ q" L* I$ V' k  Z' |24
    . m1 U0 u8 t2 e& O) B0 G25
    , W6 ?4 |! B5 z4 j- U1 u26
      q; I: U0 @- G6 A, R. @% Q大概是这样:
    ' X+ {7 B3 o5 P- w
    8 x; v/ @& X) ?) _$ K( `" r( I: i* E7 L* y6 K; D8 d+ P$ v
    然后利用这个mask生成图片
    : {" N' {9 k9 R9 @$ o0 T" O# \
    & D" U- C4 ^2 y1 Z2 i# 参考自: https://www.jianshu.com/p/1961aa0c02ee
    # t. z2 l  {$ Himport cv26 P5 j) c# F% p% h& E# X
    import numpy as np
    4 y( i( ?# k" `, o1 s$ Z* Q0 f4 Y5 b
    6 f5 R7 J2 E4 u! i! M
    origin_png = 'origin_png/person.jpg'
    $ [8 _0 O' l& `' Z& Y# maskPath = 'mask/person_mask.png'  Z7 p; C5 _7 g1 P' j
    maskPath = 'mask/bmv2.png'
    6 c) O) `8 p+ o+ s1 T1 Rresult_png = 'result_png/result_png.png'
    5 b+ f, D2 T9 e+ u7 s/ N( _
    , v- V8 N8 O& A  L: ]! l6 p. \* E4 r# o5 X6 |6 H" b3 _7 I) b; C5 ]
    maskImg = cv2.imread(maskPath)% J( V9 ^4 }' M7 |- w
    img = cv2.imread(origin_png)
    - F. t4 A' j- h8 M+ ~assert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'
    " z0 |% [* @. D- u+ `9 W7 E  g7 ]: v) L
    h, w = img.shape[0], img.shape[1]
    $ T( D: ]& ?! D. ^, u2 Eprint('图片宽度: {}, 高度: {}'.format(h, w))7 ~7 w4 h) K( {) U2 v: ]# E" x% t: `

    % Y1 o3 E" m. h2 J3 q! \rgb = (19,122,171)) i- u1 D2 {6 |+ q" z8 S' B2 E
    bgr = (rgb[2], rgb[1], rgb[0])
    ! R& A# }- m/ ]: m; W# (B, G, R), n% Q" L3 ]) \, C4 N# V
    for i in range(h):, c& Y: l' p% x4 ]* s
        for j in range(w):
    * `6 k$ q2 T9 |, Z$ V        if (maskImg[i, j] == 0).all():
    : |0 H& E: t- o/ Q            img[i, j] = bgr
    ) [5 u7 R* M  k, [! o! J: ~cv2.imwrite(result_png, img)
    1 u' k& A1 i# ]. k3 iprint('图片写入 {} 成功'.format(result_png))2 U$ Q% ^, m' f" _$ g; @
    1, g7 l( b/ W# Y4 g# [+ A, [" d
    2
    ' g! f' q3 x' P1 p6 q3
    ' U8 [5 K6 x( H( q5 x5 [49 S4 N/ a4 j% V  p
    5
    8 m8 t$ V) A. `0 i0 t9 F6/ F2 q& l9 ~) ~0 c; ]+ m  k5 }2 U
    7
    ! f1 o! t1 V' N) ~8' W3 \3 s" [7 \: w; Q2 _" P: a( C
    9
    ( P0 v7 u! ]6 X; j10
    2 H8 w: h( g0 V2 h$ A11. }5 V6 W8 K4 s6 l: G4 s% N
    12$ M; {2 m" h" y6 U0 A* M6 l4 ]
    13
    : c: X8 p/ \% t5 n14( ^1 i* w" H. K% Z* W& {
    15" o2 H3 J" e" S! T
    16
    0 S$ x: X. b1 j174 X3 M3 h' V; i4 W
    18
    ( x+ f& {' l1 K* `19
    ! Q9 ^2 u8 \/ x2 W+ V$ r4 M7 n206 {  W9 s3 E' m! g; a- h
    21: P' a4 p* c- k5 a  u  p3 K
    22" m- B% x' `) b# Q1 n8 M
    23$ G" \$ p- _, O
    24
    0 \! R  o$ X8 r0 L25& d* t6 k8 M. x. P; j5 Q' o/ n
    26
    . d. G9 q2 F* e27
      g+ N: l$ B( r5 _( K由于人长得一般,就不放图了…
    : U( z1 ^) [: u9 Q1 K4 F6 ]
    ) ?, \& a9 n4 u+ D& U) W缺点:
    $ H, A  b! S7 p( g& S# t5 ]: I; u7 `lableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。4 e/ O( ^3 a" f0 w* R: w! H. Q

    ( c9 h8 k+ ~3 T: B* `$ J+ s7 X/ s- ^( v5 v( _) k# n% V1 v

    # k6 t! }" r; _4 v  h
    / u% H" t+ v+ G; y1 z+ `: W7 g, W" x
    方法二: 阈值  ~5 e1 z" d) M- z. t; i" z1 ~
    该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。! x& s: r; F$ V2 m1 Z# J, C8 t) j
    & X. F& v3 e! _7 W
    Opencv, }& j: f) g+ \
    import cv2* {: ~8 m( j3 e) m3 \
    import numpy as np' V! r# i( }6 b* n5 {
    + w  j3 a& W/ L7 ~: v. k! p  ]

    ; w: |3 n, f1 @- V; B/ W9 Ldef mean_square_loss(a_np, b_np):
    4 S* D0 ~" V' H    sl = np.square(a_np - b_np)' q" b6 E# z8 S& w0 ], G
        return np.mean(sl)5 P! m* W, e) N) _/ F# Z9 T
      z" h- d, M" h. c

    7 Q% X+ S- w% j% x# \7 Wdef change_red2blue(origin_png, result_png):
    1 O% L0 ^) p2 G8 @0 R, [    img = cv2.imread(origin_png)% ^' x- N( X8 S- A& I7 M

    $ P. c% _7 h: B    h, w = img.shape[0], img.shape[1]
    , {% r/ {* K1 D# T    print('图片宽度: {}, 高度: {}'.format(h, w))5 T8 M/ h; T2 f! c" _  x5 O

    " ]% V1 I$ Q8 ]0 R% V    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值7 U( f1 U- M& W# P# t. E
        origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    % r5 r# C. J' n% ~    target_rgb = (19,122,171) # 蓝底RBG* L5 D7 [- z. H  ~! r' e
        target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])
    5 d9 C7 R2 F4 T5 t
    4 h" ]% D+ l! w: t0 Z0 O/ M# H# L    for i in range(h):% x5 ^: f, p: L/ e, _
            for j in range(w):; r$ @4 {  P' K0 d* Y
                # (B, G, R)
    3 ~! m$ g/ D, B% o* \1 k            if mean_square_loss(img[i, j], origin_bgr) < 50:
    ( Y& w- J. c# H; ]6 C- g1 F                img[i, j] = target_bgr
    5 ^: j  n& F3 q5 J6 W$ U, U8 _+ M2 M# m/ g" E3 o, C- Y
        cv2.imwrite(result_png, img)" c( C! |& l3 s" U
        print('图片写入 {} 成功'.format(result_png))
    4 U7 |; }+ u) q& |$ x2 k
    4 B* M2 p( \/ I
    ( h9 c5 m$ [# e5 M/ a3 Gif __name__ == '__main__':
    ' v0 T0 }4 X7 z* h6 f! o    # origin_png = 'result_png/result_png.png') ]# K* k: j6 E; [+ L
        origin_png = 'origin_png/person.jpg'
    3 z: L0 K5 W/ A# d- V  ~  l# Y    result_png = 'result_png/result_refine.png'# A: F. r0 n5 i/ }' N
        change_red2blue(origin_png, result_png)
    4 T6 A. |% ^8 f  `3 S1
    3 I, z6 g; S2 w4 S* ]% t. j2, F7 z. Y! S) S1 @, B8 f) S, t
    3
    ( k" X0 f5 _% \2 O! C& f( s' A; `4
    6 h3 T" y7 w" `; W( {) S( ~54 X' w6 ?# R( ^
    6
    , @4 {/ a  d  c; S# S7' r2 Y3 U) T1 ?6 c0 @$ s# b
    89 t0 U/ J" \$ G6 a* I" j& P
    9
    , s3 H2 M" k" x10
    8 G8 s; {1 T9 o5 I11: d" }  b: C' m
    12; g  N* x- Y5 L2 k
    13
    3 w5 \8 ?# f" x' Y143 ~2 i& G3 u8 s$ E; g% o  W1 ~
    15! d  P5 H3 @% ^( J
    167 h0 w( y8 Q8 q/ E+ c
    178 F: H1 Q# S: K0 P! L0 I0 T" h9 |
    18
    6 }7 Q5 e- r% y196 C. W, }/ m( ~( Q7 Q/ U
    20
    7 K' m! j2 i2 L6 B# e% K21; \9 ^1 O9 |' t
    220 N4 x: ?1 R3 `
    231 t) i5 ]" o, V) n( T+ v# m
    24  Z' P4 z. q6 `# S* Z
    258 D7 m8 i- z" R& J, V) G
    26
      e8 q  M# Q. {3 U4 C277 s; D2 g0 F/ a4 |& T! U
    28/ W# {' {+ M, O& s4 `! c' q
    294 |/ @) ?) F- O9 k  E
    30
    7 G+ E: y) N# u$ g7 z$ l4 Y31% i2 [9 i, |5 ?- s# R7 V1 G
    324 j# ~2 y6 Q" N1 e: V) @
    33
    ; ?5 U* B$ i7 ^% |3 o8 s% i. e34
    ) k- B1 J* y/ {$ a35+ m4 \( p6 @# _7 L1 c9 p0 y9 u
    结果人与背景边缘仍会存在红色像素残留5 a: B# m8 \: E: N6 U7 y- b- z' ~

    - s3 f7 }% r. ]1 r  |' M1 c8 g1 {, \5 A/ b& b
    / o& E; y, f4 ]2 i$ [" Y* Q
    1 ?; R  S% O6 g  {, v# [4 @; N

    ) a. f# y/ }% V, UPIL: x8 j" i2 Y- a
    from torchvision.transforms.functional import to_tensor, to_pil_image8 Z# E2 D1 Y; s3 F
    from PIL import Image+ n$ I# H- t2 d7 w
    import torch
    ; z. Z' J' i* P+ ~+ wimport time2 V/ S  x6 U0 [7 Y- D
    : c' n( c7 ^8 O. R& W0 }
    $ x0 I4 k' U" j
    def mean_square_loss(a_ts, b_ts):9 F. V2 t  p+ |8 ]
        # print(a_ts.shape)
    , E8 d, T  Z  U+ B    # print(b_ts)
    * M% M  ?2 y1 u0 m9 s  d    sl = (a_ts - b_ts) ** 2
    9 z# t4 C4 h% p* [' F; }3 Q; o    return sl.sum(), b; v/ J- l% S8 |5 }6 ]
    0 ^+ d9 ^3 |. Z; |+ c- \

    ! X  _* q1 H0 Q( fdef change_red2blue(origin_png, result_png):4 {+ K9 u5 M; ]$ f( O
        src = Image.open(origin_png)# r7 K$ r) ~: s7 I
        src = to_tensor(src)
    / V, N7 z; F4 N# r8 s& F, H    # print(src.shape)  # torch.Size([3, 800, 600]); k) y" X4 \# ?: d6 e' i
        # channel: (R, G, B) / 255! r7 B; l- w5 j- {
        h, w = src.shape[1], src.shape[2]* R, Z5 Q: j6 w6 R2 }4 K

    ) K0 z+ }! r# U/ y: I9 u5 E    pha = torch.ones(h, w, 3)+ x) f' }2 g# G, S0 p3 i
    " j1 H' ]. F4 t9 n
        bg = torch.tensor([168,36,32]) / 2553 y' O1 Y& \2 `) T$ t6 Q
        target_bg = torch.tensor([19,122,171]) / 2553 D+ q' o2 ~% U

    8 L2 l6 Y* {, S  t* m, U; e2 k9 S    # C, H, W -> H, W, C
    4 g  c6 v: _5 X1 z/ l; L    src = src.permute(1, 2, 0)
    3 A6 h7 [) p! A    for i in range(h):/ ]; d  }! S- g. i* O& U  Q2 {
            for j in range(w):# Q) e: l! Q3 |& Q
                if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数
    $ ^2 U- C" e: P! d5 S9 s                pha[j] = torch.tensor([0.0, 0.0, 0.0])+ U) v% t& r0 ?6 U, n/ }! [

    ; o, y3 K% {0 v/ _( g$ q    # H, W, C -> C, H, W
    ; `! [6 j& X9 r( e' d    src = src.permute(2, 0, 1)1 F0 w* q3 W! P6 n) g# F, g
        pha = pha.permute(2, 0, 1)
    6 N. c* _; Z. z% ^! Q    com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)" b- W. {3 H0 E+ j' e/ x
        to_pil_image(com).save(result_png)4 j* f1 K/ C( {" ~  v

    8 u2 f' k. s1 J! Z: _; P7 P$ T0 ]2 t% B  ~! Y( l8 y
    if __name__ == '__main__':
    / [5 k. I+ j8 p- A  A9 j: Q9 w: M    origin_png = 'origin_png/person.jpg'
    : h5 [& P0 n. F" o* n* }0 \    result_png = 'result_png/com.png'" ~; U8 U# r- W) C) j+ e3 w$ a
        start_time = time.time()" q/ i9 y: k4 w6 p% @* ?
        change_red2blue(origin_png, result_png)- @0 N- S- |) m9 C, \: h! X
        spend_time = round(time.time() - start_time, 2)6 \& L% }4 y* z# s6 ?
        print('生成成功,共花了 {} 秒'.format(spend_time))0 J1 {& ^) V% b) `
    14 Y8 D* Z. E. b9 l
    24 p' v' `# E0 \4 y9 I+ X# ~
    3/ e6 R% k% r0 g0 u" M2 |
    4; @$ l/ M& W3 ]9 o9 R
    56 Q) K5 z' d5 D" @: n! B
    6
    , p, O, T7 x% L( Q6 a& G- ?- Y: z7' K( h2 a/ k# g$ j" Z6 j
    85 W1 c' y1 l% c# H" S, f
    9
    : G1 k. e8 w. F0 M6 Q8 x10, h2 ~# t$ `8 I, ?
    11. b! o1 C; `1 [# v6 [
    123 n. t2 Y. ?* f/ x
    13
    / y+ B8 a1 N. L# X( x0 M/ D14
    2 J/ V& C2 j# C# I) x15
    5 e) a: j$ a  y6 ~/ C3 A" W164 C0 R; H% `& H: |" F- U- y% m
    17( d) _2 Y  z! X; K9 k
    18/ H2 Q+ a# p7 G9 k
    19% E1 i  }- y8 @
    208 Q3 w) x- O5 A& O3 d: H( n, i  Z+ F. Y
    21, F1 D6 N, t7 }1 L+ H8 z
    22
    : c! d, L, ]+ N23* f. E- W( l9 O; p2 [# S7 v
    24
    , n) n) o( c* X25$ ~- s" D0 c6 }7 w+ s  w3 a
    268 {3 c5 I+ P0 V3 o+ Y$ J( v+ \4 y
    27- |7 o$ H7 Z1 K
    284 `+ c) Q( M7 C  ^0 j; C
    29
    , @1 A1 f" _$ I30* R/ B' q. |& M: Z- f  ]+ w5 M! g  T7 i
    31( V( p( H" N* |$ K8 ?2 A
    32+ W% c0 u9 l' d) e1 B; S0 @3 i: \
    33$ X$ V2 r- o  x/ s" ]; W) V
    34( O5 |- y7 q1 P
    35
    9 C9 K0 C5 l5 ?% ?. E! Z4 P36
      u9 w( V5 {8 D+ M* o37
    & H6 N7 Z  {$ |: Q! ?7 h38
    + F8 X, I0 ^# G; x7 n- Y39
    & A9 O! G+ J  H: s40. G8 Y3 h: M3 ]7 `! Z" y
    415 c% V# B6 A8 w$ j
    42
    4 F7 p: V8 ~1 S6 i. Y43) W. m( }0 c" i8 w& X5 M
    44
    , N4 u7 T1 |. S' j% v457 Q2 j6 `* e1 p% _9 U
    46. ~" f5 H% B$ ]& J; `( ^
    该方法质量较好,但一张图片大概需要12秒。
    0 S1 ~  i8 d8 }0 {9 [; m
    ! W( V: H! f7 k& t: |5 z! M2 v' ~/ }5 s3 e2 H& P. ^
    0 p& h! e$ H3 Z7 A! R$ a: u
    方法四: Background MattingV2
    ( F2 }$ B$ X% A# X+ T( IReal-Time High-Resolution Background Matting7 u+ }- G" Q: E0 Q: \& \5 T
    CVPR 2021 oral6 _: \0 f) ~1 }

      m$ m& b0 G) j$ r论文:https://arxiv.org/abs/2012.07810
    3 v  E. I. \; Z7 ~代码:https://github.com/PeterL1n/BackgroundMattingV2
    0 d* |2 o# ~) t* E. ]4 e1 r# j
    8 A& ^# J) U) wgithub的readme.md有inference的colab链接,可以用那个跑
    * P! y- X9 |# J! E6 ]
    : ^) m0 G  K" T- i6 X, T0 M* v由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。
    & [2 x, Z  K7 O  M1 ?6 r' D* z: b4 \# e% w$ ~( I$ n
    于是这里我需要生成一个背景图片。* X. W  X& O2 w# a2 a: A% O* F
    首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。$ }5 C( X1 e6 Z/ g
    ) {, t& |4 j4 w' t' Y
    然后生成一个背景图片。3 K6 s8 T" o  F6 g( v% I+ H
    0 L( t) |9 E; P' V' o; J
    import cv27 V) j- v2 S( o8 }
    import numpy as np
    3 M! |* y8 ^8 j2 p1 i+ H+ d) l6 a4 _' a9 E

    3 k1 F" f$ o5 W& v; }. ?image = cv2.imread("origin_png/person.jpg")
    ; W1 M$ a' C3 M$ a* t* H$ w4 borigin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值' `8 A# `' M* \
    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    6 Q! v1 n( Y5 W8 g2 [image[:, :] = origin_bgr
    " Z" w# D( O0 n, |( B1 {* y+ ]; ^
    cv2.imwrite("mask/bg.png", image)/ P) k( `2 T1 Z4 u+ N- O8 d/ C
    1
    7 m$ I4 {* u- d8 L2
    3 c" J+ k8 D. D% V3 G4 A7 N) ]3( V- _% Q! T" F3 D$ b# G
    4
    ; ?4 z" }) l7 q3 ]; ^5
    - ~: y1 m7 `9 v4 M. V% ^$ Z3 }6# C7 a' {( w& b$ b( `
    7
    3 a: a( s" H  r! Y8
    * q0 o# z* N' ~+ Z0 S, `+ U2 B+ M9
      S0 \+ Z' g2 A: ~$ |% J* V10
    ( p+ y) ^$ m% d/ A# v6 C" @* _8 n
    * f1 b: B- }3 {2 Y+ ?0 m1 l) n4 q需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码
    + M# v/ R3 b. }8 R9 o7 W( T  H  h. `5 y& u- x
    src = Image.open('src.png')
    % C/ s% O% {, G! w" bbgr = Image.open('bgr.png')6 R0 I' u6 `7 l) M+ n
    1! G/ k) u7 A: p6 y9 K) N! b
    2- F5 q3 Y5 R* s! o- ?" ]) y
    另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)7 h  X% F  E4 ]1 d# l

    * t3 _9 M2 V7 j$ {+ D+ acom = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)$ p- W& o7 v" V  {; z
    1/ Z4 G2 H6 ~& u! N7 J  f
    0 M1 V; l- F# j7 P
    那么加入我要换白底(255, 255, 255),就是, Z% s  [+ u- v9 V7 J+ m
    1 h" }3 f9 t; s# u
    com = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)
    ) k5 i7 |- [7 \" l' H; l/ _1
    , e4 }4 Y5 z0 ~5 A+ N$ h( u; ?
    - P9 e7 {. w. q' \/ f% ^. W假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是# z' o' F6 e2 a9 Z, V" \# }
    9 w) j& l0 B5 y0 J
    com = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)
    % a- X* Z: s2 o3 C1
    . e/ h  }# p' i' A  P4 P0 Q! e总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.
    $ A4 D5 A4 j4 i- \; N4 v
    3 B) z* r0 M+ c( Y# ]# G然后就输出图片了。可以看到效果相当好。不愧是oral。
      A0 X: h3 j% U5 @
    : n  d/ [% R4 X/ W' ]9 |6 y  h8 v( |6 g  M
    原论文可以实现发丝级效果/ p1 b* ]' A! J8 ^6 p" D" Q
    . y* P9 p0 L$ P  c- {9 _" V7 ?

    2 k& [; W& I' B1 n2 m# V! ^) ]$ ~$ C$ k: a- T
    ! @! ]6 [4 S5 S1 V( E
    - w6 A3 H. l! h4 q
    报错解决方案: I0 h3 d* s& e8 V; ~7 A( j
    can’t divided by 4 / can’t divided by 16' j) Y/ F) {7 N" _
    由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。/ H' L; v2 ~5 \1 j  p# F1 k! `
    这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize
    4 f7 p/ x& S$ h+ S————————————————! Q# I$ P2 y. C7 I$ E+ a7 E
    版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    4 A+ L5 P, g. C0 q, c. n& N- s" k原文链接:https://blog.csdn.net/weixin_43850253/article/details/126376767; v( c1 l0 u& h) _

    5 G2 `5 k$ ]+ ]. }. ^! s. h7 Y% Y3 `! o0 F) F
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-4-11 00:54 , Processed in 0.427838 second(s), 51 queries .

    回顶部