QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2131|回复: 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将红底证件照转成蓝底* k( k3 Y) S/ z
    前言
    - l7 C2 W) e! `emmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。) q/ k( k6 L6 J0 G4 f. E. P

    / z- B: Q+ C3 P: n" X0 e
    7 u6 M& r: s2 q# V: c7 d: y$ V1 H! b9 M/ G, t
    , c8 K$ L3 F$ [0 e+ I2 J7 H
    方法一: lableme  D+ ^# @  ]; G0 Y
    lableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.
    / m3 r- \& ^# X+ B1 h; A  ?9 z' Z8 d" h/ @- g) k# L# }
    # 代码来自 https://blog.csdn.net/hello_dear_you/article/details/120130155
    0 t1 ^8 P6 d- D  mimport json! l9 |1 C& M2 n
    import numpy as np0 b; L! |1 e6 K3 o3 |0 A2 K! U
    import cv2
      F. l/ @& ~( _+ y; s! s8 p' Q# read json file
    % i  M, S8 e) S" |! D1 e5 ywith open("origin_json/mypic.json", "r") as f:
    . N+ d) d; r  W8 Z0 X' B    data = f.read()
    3 L) _; a1 d* _0 O& Q2 ~7 b9 r$ L$ v2 J6 Y& K- s2 Z8 T: M
    # convert str to json objs: w$ L( A! n) Z+ R' e
    data = json.loads(data)2 g( V$ h% y1 b8 m! w4 c" s7 ?  {

    : u+ P1 ]3 ^+ r) z8 p7 _# get the points
    7 {$ Z! a4 {* y. M! C2 npoints = data["shapes"][0]["points"]
    . m& z( ?9 N! f# m3 {! I9 Opoints = np.array(points, dtype=np.int32)   # tips: points location must be int32+ u, h' m7 Z+ _9 b" ~0 [

    . J; h; r; a, }' ?# a# read image to get shape
    ! |4 {" V! k: g3 k, Gimage = cv2.imread("origin_png/person.jpg")
    ( r, _8 X6 u3 u# z8 ^5 R5 A& F1 ]& {2 _- `8 W
    # create a blank image$ W& }- g: q3 C. v/ w
    mask = np.zeros_like(image, dtype=np.uint8)
    5 C" f" n' [; v2 \# K0 J$ n2 m% k' r% X  w# {1 A6 p+ k# z
    # fill the contour with 255
    0 m- k# y+ h( j( dcv2.fillPoly(mask, [points], (255, 255, 255)). B- j; S3 Z" _, R; i/ p
    " i1 u- F+ x0 n5 H' z8 {% T% B
    # save the mask
    ' J% O( L  |3 j) k1 l4 r- A4 {$ Fcv2.imwrite("mask/person_mask.png", mask)
    / u# }: f& M0 Z5 H1) ^0 n7 C# V5 N6 U  f
    2+ B/ }# \$ y9 Q( G; f
    3
    # U% |7 D& R9 Y, x# O& e  _: O6 n' W4
    5 [: d" U( L$ ~- |: {* q5
    0 F! v* G2 C  a: o4 I6
    % a8 E" Q% T0 \7 F7: `/ i* C6 b' u9 W3 w# |1 f
    8& O' P' {0 [3 E6 @' V
    9
    . Z8 [# Z* Q2 Y8 t. G% b6 F10
    ( s4 x3 d0 L* S- W. Q* f! M/ Y11
    ( ~1 W5 x: I4 A. P5 x: G12
    2 b8 m" r( T+ u4 y: D3 T; X13
    " D# I9 Y0 g4 @14
    $ ?$ s1 n" Q; G, ~- a15& r# t9 S. i. V2 @" a
    16
    % _( H" J2 p- U5 Z' a, T- J( A8 H177 A; |/ v9 |) Y' u2 g9 C
    18
    ) P. q+ A4 C$ T/ S: H. b19
    , z: k( @" q, ^20
    - w" g. G) f" K* f+ ?/ Z21  S2 t0 }8 A  o" ~5 a& K
    22* k$ Z" e* Q3 S5 Y, [6 e
    23# [; K) ?* [# @- y
    24" D. S1 N4 t& i) ~; \4 S1 B
    25
    6 v& [: J1 k% G4 J8 c1 ?5 \' m6 L26' `' n* s2 X$ E) X) |7 P
    大概是这样:
    - ~: J# P8 G$ ^* _( D
    ' j! m( g" |) J% {+ h6 G' A9 n+ c; o" Z. s+ Y+ S- ^, f  p( C
    然后利用这个mask生成图片! h; T+ z9 a/ X9 Q9 [- d
    " v# }; f* [7 K6 j! R# ?( |0 C& l. M
    # 参考自: https://www.jianshu.com/p/1961aa0c02ee
    / I4 P1 k3 o  k+ uimport cv2
    ( m- t% v6 a9 @" t: a. L* ^& uimport numpy as np
    1 Y% p, N' O8 ]2 {5 p0 F9 i+ r0 z+ M

    8 e4 i" q5 S. v" q- P/ w" Norigin_png = 'origin_png/person.jpg'$ j, B% L) ^. G# N. m* v% s
    # maskPath = 'mask/person_mask.png'. M- a  b# A% l( O
    maskPath = 'mask/bmv2.png'7 }* l, Z; J! b! n  m
    result_png = 'result_png/result_png.png'* H8 g1 V+ G4 I
    " u0 u5 W! \) z( l: \

    4 d' Z. _& E0 c1 _  MmaskImg = cv2.imread(maskPath)5 s' L& S2 J, ]4 r3 L. o+ K& s
    img = cv2.imread(origin_png)6 a! Y3 ]5 z# M5 _0 p
    assert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'$ [& w" g% ^" O; v9 q
    ( s. H# u7 H! v2 U6 X9 ^
    h, w = img.shape[0], img.shape[1]
    0 R) P/ u, r( z8 M; ~print('图片宽度: {}, 高度: {}'.format(h, w))
    3 R- j; R. \7 [2 q. q' h; C3 C; {
    , q# T. j2 l7 `# @: ?4 t) ]rgb = (19,122,171)
    4 h1 `- H& g% u# gbgr = (rgb[2], rgb[1], rgb[0])
    + S; b; Y' o7 v2 o9 e! g' ]8 t# (B, G, R)' a: r! c5 [5 @& C5 }' n4 L5 t
    for i in range(h):, [6 d  l* O( t- `! o
        for j in range(w):" X  ~2 U# J0 _3 G; h5 B
            if (maskImg[i, j] == 0).all():% n) @( e& q5 D8 o* b
                img[i, j] = bgr: p, O; {  g7 h2 _7 g; J3 {
    cv2.imwrite(result_png, img)4 w# t. |& b: k
    print('图片写入 {} 成功'.format(result_png))
    2 m- I1 _. K) y# M) e& \- s' D0 Q1
    . w5 }# @+ b. V- g2% _4 {& T. y* \, z: o: t4 K$ s
    3
    5 m  P2 d) @/ [/ u" k6 n$ ~: K$ M4
    1 x$ |" @- G. J7 \8 U- X$ \59 A5 w- Y  v2 z$ P$ |
    6
    6 N/ P% c, A7 u8 k9 d7) H5 E1 j4 G& y8 f  @0 a6 [& G
    8* Z& v5 p0 o' D$ p: z5 H5 l3 j
    9
    : O6 R' l+ f0 d4 G9 f10/ x' {. s9 M3 j. G0 ^4 e/ D
    115 }$ u7 o5 b" m4 [
    12
    " V9 K& m: c% m) \, w7 W8 J13
    , L# N8 H' l& ^7 d. k9 B14
    . q4 d/ ?3 K% @; ?, }- O6 Z2 S15  ]1 x" |+ d! w
    164 A  }& L/ s5 D6 L$ ~% a* S2 D
    17
    ! o# \( [9 [. Q* ~! c! a18( a  }8 I9 _( ]# ?( X
    19, g; d3 X, z) _  ^+ e
    20
    4 u0 D  g. V1 o9 E' |) G0 S213 R0 G1 Z2 |' F
    22
    / P8 m* x: U1 I# E* }( n3 t23
    . L% r6 b1 i6 [24
    ) Z! b, u, y3 Y8 s5 o25; ~$ L9 e* v# Z9 _) @
    26
    7 q% c2 @" K9 R1 n4 a1 G2 Z% _27
    3 B& S. n% [8 B, E; e由于人长得一般,就不放图了…
    2 f2 m4 e1 p" K7 A$ l7 }+ t0 N  F
    缺点:
    6 w% {7 `+ l! S4 D4 |lableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。+ O% f, k. D9 e' V/ z# E
      U& R! F! t, x, C
    % |( a6 O" a  p- B
    ' I. L1 T9 n; Q+ {4 w

    + v$ F7 w& Q6 a
    $ y, J% M+ R3 T: I方法二: 阈值1 T7 o, f! t) t  I
    该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。
    / K( n( q( i$ R7 E$ \2 o, l6 C  w: ~+ p. A) Q
    Opencv
    6 e; {% n3 b# simport cv2
    4 J% h5 o: F7 H4 k9 L3 }import numpy as np
    & t3 T4 ?/ v' `% q. i
      L) y' h! d+ I5 k  L. T
    ! u5 Z$ P$ t: ]! U$ {$ o+ B+ Udef mean_square_loss(a_np, b_np):
    # O2 n# J3 P8 R/ m0 F1 |9 j    sl = np.square(a_np - b_np)
    - M" }# m: d* G. t7 s    return np.mean(sl), Y$ z: t. n4 y9 c( @
    7 Y5 y7 S. _0 z" D

    ' n1 ?2 d$ w- r5 d' x5 }def change_red2blue(origin_png, result_png):
    : u" J) Y0 T( t" x8 j/ D7 Z' ?    img = cv2.imread(origin_png)
    , a: i  p5 k* v* q6 T& \7 I: f6 x( k4 v0 Q1 d  {/ e+ U6 R# C6 O- s" ~( m5 S
        h, w = img.shape[0], img.shape[1]
    - K% X1 m) L- ^; O% _" ]# b1 |    print('图片宽度: {}, 高度: {}'.format(h, w))1 U+ _, Z# k8 W, \. w2 t

    8 b  ~# D! f, _$ H7 ~$ w$ n0 p0 ^$ n    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值( D% f+ G" {; t1 J! X' u4 s
        origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    - R$ W7 [% E9 o) y    target_rgb = (19,122,171) # 蓝底RBG
    , K4 s7 Q0 k5 v4 F$ L1 C    target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])( A: u, k# y) V6 d/ f
    . D% y! U2 E8 A$ v. B
        for i in range(h):& m* ?5 s1 o8 [( Y! K8 [& Q: M
            for j in range(w):9 ]! o% Z$ z; C; C4 x
                # (B, G, R)
    : ]9 S# |; ~' m% L  M4 r. q- H4 J            if mean_square_loss(img[i, j], origin_bgr) < 50:/ p; C! t! n8 d$ ^& i1 x8 j
                    img[i, j] = target_bgr
    ) t8 ^! W7 i- c* w3 E1 a8 K, u! f2 y4 o  }
        cv2.imwrite(result_png, img)
    9 ]5 a% U' b0 m  Y    print('图片写入 {} 成功'.format(result_png))2 [7 ?* ]  n- {1 w0 c( z

    3 a- G! \3 ?4 ?; I( x% v1 a. ]& I
    ( S0 ?. R" {( |' |0 Y% jif __name__ == '__main__':4 p; s7 t7 X/ w; ?+ H$ S: \
        # origin_png = 'result_png/result_png.png'
    3 x" k- g  j- y; p4 ^: d, _9 M    origin_png = 'origin_png/person.jpg'
    $ `0 r6 i% i0 }. ?& L  Z    result_png = 'result_png/result_refine.png'
    , F& ]1 t. \! k) B    change_red2blue(origin_png, result_png)
    ; C& {2 v, [  `( W1
    4 B+ i; F  v& k9 u0 R$ I- ?6 Y: ~2
    6 a6 T% a: Q' [$ f' G3
    0 o' h. ^& @- `' E4
    ( s5 m/ y& _  @4 W" T2 K# E5# u- @7 v( e! o# w& u! g
    6) n5 v& l# H; S2 K( p2 Y0 u9 h
    7: [: j4 N  H. D
    88 S/ N0 V6 S: ]
    9
    ) o( R! L. E5 c- r5 E) ]- ]' g( H10
    + n9 o, Q" s5 E- `" _$ }; {2 ]2 Y115 M& s; f% I$ b$ J
    12
    9 ]0 v, S8 l( h9 C- ]$ }$ h3 M13! j; q; N+ o) E3 t& G1 `
    14
    $ c. W- `- I3 h8 e- U  h: s151 N6 l* s: z4 H( r0 h
    16
    & c, S5 ^, c0 R( ]" B( Y17
    ; h8 C9 l* `5 z& H8 M6 a" w184 l  \0 ?% y$ K4 E
    19. k! P( l9 Y; a. Z8 r# R
    20
    5 Z: c3 B5 g" s( \; u# N; B21: a" {2 |" z6 ~# A
    22
    0 `9 R0 S2 q9 ?- p) y2 K/ I8 k23
    . J8 ^! }/ Y: D6 l24* H( j0 T3 Z! z
    25
    ' x; j6 n7 y( ]6 z! j; C26
    + ~$ u' p$ d2 [9 G27# ~% x+ Z( E. F( [: R
    28
    * x: c0 f8 A; i8 `  e29
    : }: ^3 U0 Z# p7 K30* S- F, L( P) K' m
    31
    - o1 Q1 }7 F4 r, G, N+ `* b327 _0 W" r7 N8 V& x
    33
    3 a, N; C! ]: w2 v- y343 }5 G( ?  h$ v5 {1 s  s
    35
    : l$ R2 N2 z5 `) Z$ b' j3 d, U. t: |  }结果人与背景边缘仍会存在红色像素残留
    . ?6 a9 q8 T; Y( p) z4 a
    / Y3 ?- g) j) g4 Y' G
    ; y5 D6 G8 }+ m: _4 a* C- V: n- d1 @' l9 _( z3 b" {
    $ L5 s0 o4 x6 ?4 L; w, t% E/ W9 l

    3 t# M) s- H$ S3 c7 r& GPIL5 g; f' u* ~% z7 ?
    from torchvision.transforms.functional import to_tensor, to_pil_image8 ]  {# ?& M4 D  [
    from PIL import Image) ?# B$ ?1 ?: ~# V0 ^
    import torch
    ( Y8 E' ~/ J6 P7 M# h$ |3 pimport time
    1 j. }' l9 G/ Z. j5 U: w
    4 b' ~/ \# D9 l, v# f
    ) v( ^4 |# n; z! ^7 }1 sdef mean_square_loss(a_ts, b_ts):
    & a- F( n1 p1 |( q    # print(a_ts.shape)' t8 u, ^4 U# a2 L! J' p- q6 D
        # print(b_ts)
    6 H" G: |: X* W0 B# N    sl = (a_ts - b_ts) ** 2
    ' B0 V; @$ L  \% n3 L+ x5 L    return sl.sum()
    ( i! Z! E) |8 e5 H  L) b3 z- y# }  x; V. p

    1 b3 e+ \/ i& X* Z4 f3 Pdef change_red2blue(origin_png, result_png):: N3 B" W' ], x7 {6 `- P
        src = Image.open(origin_png)" D$ A( E5 w' o
        src = to_tensor(src)! V9 [2 _) i' N( v( ?* g
        # print(src.shape)  # torch.Size([3, 800, 600])
    8 i8 L2 R, l  t$ D; x& r6 C+ l    # channel: (R, G, B) / 255& _) ]  y2 N+ n' x. E, M% [6 D) K
        h, w = src.shape[1], src.shape[2]
    6 Y, [$ J# A" ~3 W) @9 O: @; x; u" U( i" F" e5 f- w2 l3 h, `
        pha = torch.ones(h, w, 3); J. j- S; {/ ~% t  {; }

    ! ?: x0 `" a. s. n    bg = torch.tensor([168,36,32]) / 2550 |9 }  p6 \% ^
        target_bg = torch.tensor([19,122,171]) / 255+ x! R4 A5 W  D/ X+ Y# |

    ( x( Z" }, ]) ]- H( p    # C, H, W -> H, W, C
    9 \  h5 ]) c5 F/ w% A$ J2 g: k    src = src.permute(1, 2, 0)! U3 u- t* R1 z  |' o
        for i in range(h):
    + |" {& N% g2 {" U- ^3 a        for j in range(w):
    / t/ e2 x( u" N            if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数
    / c* `/ ~  ?8 E+ R- r1 x' W) s  A9 z                pha[j] = torch.tensor([0.0, 0.0, 0.0])0 E5 f2 v) d! Q, @+ j
    * t. l! }4 @  l8 p: z% n
        # H, W, C -> C, H, W
    & y) [. p9 u0 g2 E# P8 F7 e    src = src.permute(2, 0, 1)
    % L) _+ Q: K" w" f    pha = pha.permute(2, 0, 1)) ?0 v8 Z, ^4 e2 A" r' r6 M! k
        com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)7 S; D- x3 k4 u5 N3 X6 }5 a- r
        to_pil_image(com).save(result_png)
    ! F! ?8 v4 b" T) t5 N
    # ~) q. c( d4 A, d1 N3 e- W6 m/ P% y7 d5 T* \$ j; }
    if __name__ == '__main__':
    7 L$ s4 b  C* P    origin_png = 'origin_png/person.jpg'6 ?3 L* V2 D, h
        result_png = 'result_png/com.png') U! e9 e( m1 A1 |1 n" z0 p
        start_time = time.time()
    # y) s+ h4 R+ {" f$ H    change_red2blue(origin_png, result_png)0 }. h$ S! u) q  N1 g  K2 {! ]9 e
        spend_time = round(time.time() - start_time, 2)& h# P2 J4 [5 @& N& E, @# r
        print('生成成功,共花了 {} 秒'.format(spend_time))
    # |) q. X% e8 f9 }, u1
    / x% I) n8 E9 p0 _" \( h* [2' `1 e0 k8 Q/ N3 [) I) C1 ~  l& w
    36 [0 }; K( [) p* D  [
    46 k( x% W, K) r+ W7 v
    5! |2 H  G. Q8 |; q
    67 H+ f/ \, A6 v% U! a9 J
    7# [' ]3 |: H! s
    8
    ! ^/ C6 q+ U' a9
    $ l' v' a4 N' a( H10
    % ~+ I" ~8 r. ~, k; Q11
    5 V/ H& C2 Y4 |7 R* z. K12
    9 D- T$ K" f$ h. S13
    0 s: k) h( b# l14
    , e$ m$ Y3 x$ f% l! Y( e, G15
    ( ]9 H; U) C( `168 I& `1 ~. x7 y2 a5 ~! G
    178 Y+ P5 F$ b2 p
    18+ c8 y$ J. y5 n1 U
    19
    9 @* P7 ]5 `/ l. ]20. @% \5 d6 e8 L* `0 S3 L# B. p$ W
    21
    ( D  f0 c8 u6 O$ [& }22
    3 ^7 h8 q: h$ T5 a. c4 L23
    ! U  m0 |: Y# H24- ~; w2 q4 d4 M3 l
    25. p/ k$ X! U7 M( u
    263 q, D! w# W1 _; |% F9 M1 R$ G' V
    27
    ; N- B' O4 s5 d7 o+ u, U5 A+ f# L28; Z* `7 G  L* l; E( p( Z9 h
    298 a% e6 `2 ^6 I
    30' U( \4 F3 r- B  ?7 o! l
    31
    1 A2 K& K* e8 L$ M" Z: U32
    9 c( \  O- [% Z, u331 m4 h9 a: S; o0 x, T* C/ K
    34
    , G+ j  B7 `; w) \35
    1 b; {/ v% `2 A/ v) u369 F# S/ }9 b3 F5 G
    372 V) `4 p/ I/ @  n5 P* P/ M! e. |" t- k
    388 l; @# Y: G3 r
    39
    0 e% Y; Q& g5 _, j, I% ^! n# {3 I40
    6 v( ?# F! ]) r41% Q3 u0 T8 i6 M
    42: V6 j% J% S: y8 f, Q! {( n) ~9 R
    43
    - e) h, P# J, V7 O5 k" r; U44
    ' R; |9 f7 j9 e! L8 x. x45
    : h' X1 [9 Z. }* C46
    ' |6 u5 T  |# i+ @' x+ a  S) e该方法质量较好,但一张图片大概需要12秒。
    6 X: O: C& y- r) g! n: k5 @9 G# u) t: X: X- f2 @- [% Q, l+ o
    # b! q" m% G) U2 q" O6 N, ^
    : T4 q& D1 V* R
    方法四: Background MattingV2
    7 T( _' M+ }" j8 h4 p5 W" |( kReal-Time High-Resolution Background Matting1 o* O0 z* Q$ u- n  ?. |, S
    CVPR 2021 oral  {! C) q- W) n; V

    2 c0 O; f2 ~+ K" b6 ?" i论文:https://arxiv.org/abs/2012.078108 G' T& t: A/ M
    代码:https://github.com/PeterL1n/BackgroundMattingV2/ Z+ a3 E8 T2 |- I1 K+ j" V

    ; `+ ~* F/ I9 p% F( W2 ]" mgithub的readme.md有inference的colab链接,可以用那个跑, j  v2 h1 }  h* q1 t% _* ]

    + Z+ A! {8 J; k: }1 u由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。
    % C- h4 L. T$ `: v! x' \0 L$ q4 _
    于是这里我需要生成一个背景图片。' b9 Z6 J# v$ p/ g  K; k% S
    首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。
    - x& s8 A, i+ S2 o( s" P0 w) r" Y
    # g2 J6 @- I: L2 X4 E  H8 [然后生成一个背景图片。8 ^8 S9 p( L4 r4 N) E& z

    7 R' r% j, A  Mimport cv2  c+ E9 W9 n7 c' {( V2 R  V% B
    import numpy as np
    * _7 ?5 ~: a3 s+ u/ d3 E" f+ ^3 F" m& y0 r# m

      i0 ]: n# }+ q- Dimage = cv2.imread("origin_png/person.jpg")% L3 z, A8 P2 x: r/ a1 n
    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值- @2 I: A' }$ h, l5 t+ ^
    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    0 w7 _' _% o9 R1 v! f' pimage[:, :] = origin_bgr. s7 W* h  J- N7 J) n/ w. B

    4 J" E( y* g4 d- k- ucv2.imwrite("mask/bg.png", image)
    % t. O/ Y0 l5 I* R0 N7 F1
    + x+ X3 e7 _0 b; S3 ~2% b4 |5 i; }! l
    3: M$ T, v$ w. A  h& Y
    40 S/ t( K6 f+ o6 q# ^( S
    5: V: h( c6 A  s1 v# f
    6. F/ V! f- e( c, f% ?- w- Y# V) C( o
    7# N& A7 }) D  B5 _
    8
    & t+ I2 J$ H) s9 L9 T. C94 o) k4 h# n7 h3 R, r# t, G
    10( E4 R9 B7 m: o- q

    " Y4 Z; i! K# w% M. b% [* u需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码0 d0 ~, x; T& K& _; S, J2 t2 T
    5 X! p4 |  Q. f
    src = Image.open('src.png')
      m2 \! h( p7 |bgr = Image.open('bgr.png')" a; L9 c% j  G$ k$ Y1 ^
    1" V4 }' @. N* p+ p% h6 V4 n
    2
    ' W+ B* ]  [5 ~6 n* m9 e另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)
    * \* y: j, L5 X. \+ Q5 W6 o$ Y2 F: V' y/ c( ]  F
    com = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)( ]% [5 O& O  g8 l) C" s
    1
    8 L" n1 |; W' E4 F9 u  m" P7 p
      c3 [4 B8 m7 W8 A那么加入我要换白底(255, 255, 255),就是
    7 t1 ~+ c: S1 j
    , _8 P5 O8 A# e$ e1 _: w# P4 ccom = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)% v8 g/ U& C- {
    1
    3 K  a6 m8 k. E6 x% n- W( M% ^
    4 R" W, J% d! k, }7 h* B" }5 Q5 _: y! y假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是3 S  n( Y* H5 M6 S* K

    4 n# _; C" o, O" E  H' c& xcom = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)
    6 J6 Q9 \' P1 T& D& U# |2 R  B1
    ; d3 V$ d; d& F! s% n6 D; B( T总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.. t9 p* v: Z& l. i1 n

    ) O) u! `& C, {( k. h( e1 _, `2 c然后就输出图片了。可以看到效果相当好。不愧是oral。& ]& a5 {1 i, u: X0 A

    / l) x+ \5 z- e) ^$ _6 \, g+ w7 U/ H$ s0 s( o
    原论文可以实现发丝级效果9 @) K$ ?/ u0 \. L% T! y) G6 N5 z

      y. Q" O; U* H9 O' C2 ^& r) ^9 Y/ m( B& C5 ?6 Z4 x
    1 @! G9 W+ P( |' \* ^3 _
    $ [3 j* h% J, L, I0 T

    8 ]. N1 y& d$ }$ p8 D报错解决方案3 Z: S: C' ^; y# Q& |2 ?7 g0 K5 @( ^' [
    can’t divided by 4 / can’t divided by 16
    - q0 S+ [: S+ y7 R由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。
    . n' Z; ~8 d# }( ^% k) @: l这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize9 P( V, x# |' g' H; N
    ————————————————: Q: V  Z9 o0 c! t
    版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
      W2 M1 `! u- Q1 X3 `原文链接:https://blog.csdn.net/weixin_43850253/article/details/126376767* R* i/ ^/ B! Q

    % H) U0 ]" }  Q+ X: N3 B
    * `  O4 r, @8 z. W' e
    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-8-4 11:18 , Processed in 0.466219 second(s), 51 queries .

    回顶部