QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2112|回复: 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将红底证件照转成蓝底9 K* R3 d+ U, {( C8 c
    前言
    / L9 _5 K  g9 k6 A( o. M9 V7 Kemmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。- h5 X. n" k# V: Y- a" j( K

    " w# W2 {. U. F, X4 a" m9 j2 J
    " \1 V( L% D# I# A( O) U! a; H1 i* u
    " N8 I9 `# {+ |) f
    方法一: lableme! ^, T7 @, b' n2 }9 w% q
    lableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.
    + W3 M6 O( h$ ^+ Y: `9 X# [( z  y. _& l* A" O) F  l+ R1 ~
    # 代码来自 https://blog.csdn.net/hello_dear_you/article/details/120130155
    6 R+ K" L* I5 @# `import json; M: J+ [* S! {2 W" B5 c
    import numpy as np: D0 b" L9 L( m0 y# L/ ?) O. ]2 ~
    import cv28 q% e4 P1 X  s: l2 m
    # read json file! o4 t& `& l9 M! Z0 `7 U3 `
    with open("origin_json/mypic.json", "r") as f:( }- g; _% ~, \3 ?" ?! v* ^$ ~
        data = f.read()
    ) S6 L; z( U3 Y4 C. L3 q6 @% m1 u/ k! ]9 K( |6 t
    # convert str to json objs: ?7 C/ g3 |0 n
    data = json.loads(data)
    : u2 e& f' h# u4 |8 O( b
    ; |; Q# j& ~- {" g9 ^# get the points 8 ?  z$ s0 I7 i+ |" K
    points = data["shapes"][0]["points"]
    ' \2 t( W+ i3 x( x# f5 spoints = np.array(points, dtype=np.int32)   # tips: points location must be int32
    ' P3 i6 P  W. s0 J) o" Y6 v, S
    6 o2 r/ W9 q6 Y: q% _# read image to get shape
    : U* |3 p0 a2 z' J* _: yimage = cv2.imread("origin_png/person.jpg")
    ( ]9 r+ _* w: E$ ]2 D1 b: d: l. P! e+ Q
    # create a blank image* S7 w7 @3 h/ ], A  `
    mask = np.zeros_like(image, dtype=np.uint8)
    ( ]6 U9 {. ^5 J1 H) |6 z$ i# }, D, m: F. I" R
    # fill the contour with 2559 A8 Z7 _& k5 q/ u& `8 u
    cv2.fillPoly(mask, [points], (255, 255, 255))$ n% P5 f: [, W/ m* _" ^1 @3 O4 Q! v

    3 i3 s% G# M8 g6 v# save the mask ' K: L) l) ~9 B6 A2 H+ Z
    cv2.imwrite("mask/person_mask.png", mask)7 D8 \1 S4 z+ x5 H3 Y
    1
    7 ]$ J; i5 r! X/ a9 [4 L0 e5 |2
    0 T6 E! `! R5 r8 R" l5 m, l, N37 `& u2 d3 K8 m2 `6 |
    49 x+ C5 E1 f7 K" k7 C. {( F9 |' H
    5
    + A1 }# r% e2 Z+ ~. b) y# P6
    # N; @# T/ F7 u  K% o( a/ O7
    2 G; v+ j6 H' T. g8
    1 v. Y+ R; a% T- c9
    * I4 K# d" O; ]1 `+ G10, Q* }! G/ C( K, e
    11# k/ `5 `2 W6 }0 r8 A
    12# \4 J4 Z- Y% B  X4 `0 @5 Q& G
    13
    ) m2 e* T+ U2 d5 i0 v14
    2 q9 D9 n* f/ E6 V# D151 N, `3 |( R! v( V2 o: e
    16) [# z3 i$ b4 ~: [$ x# O( g5 V
    17
    ( \, x! l8 F; d4 M18) q, W7 n1 _0 Z
    19
    & T1 |* y6 t0 t8 ]20, j; h* S; D' e$ W
    21
    7 T$ p) R+ m+ g1 ]228 b3 Y. z! Z- \, Y4 P8 T
    23
    5 c2 D; V7 h( M* b3 y% t" ]0 ]1 E0 F! w240 L0 i9 ~: S- T. U6 p" |
    25
    8 |) g* P6 |. c2 _* u26
    # A6 k& l+ W+ s' u  T大概是这样:) w# M8 {" X: Y9 g& P
    # |% E- E6 [& O- v
    ' m. q; @  \. D. G+ W5 j
    然后利用这个mask生成图片* y! f) \' `/ P" ^9 Z% V* \
    " W- }, a& H) ^
    # 参考自: https://www.jianshu.com/p/1961aa0c02ee, n. |( m2 O' u9 e7 g" i
    import cv2
    + P9 f# C; Y  ]; s9 yimport numpy as np' [4 B: l* |: T0 _5 h

    7 m7 w, w& F) z7 s% U
    6 u- Z; Y. X# S! z' v8 D7 borigin_png = 'origin_png/person.jpg'
    ( s5 P6 r# V7 C6 I' j1 f  H% p1 z# maskPath = 'mask/person_mask.png': U- j3 A8 a; _8 a
    maskPath = 'mask/bmv2.png'" E) J7 Q1 B  D2 J* d, x
    result_png = 'result_png/result_png.png'9 U5 a4 z/ o; s8 N4 o( z5 T: A# Y

    ! Z" q8 c: s1 d9 m! X6 n% L; @" b( |$ U8 Y6 `/ p& ~1 @7 ~
    maskImg = cv2.imread(maskPath)/ m( c7 U8 T" {$ ]3 y( W
    img = cv2.imread(origin_png)
    - D3 x  J# ~9 H7 S9 k9 U+ t- ]! xassert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'7 W% w$ P. a1 {5 K& m

    " f4 O4 Q6 a! l/ U5 xh, w = img.shape[0], img.shape[1]
    4 O6 G# t- {: j, g9 b! x7 Sprint('图片宽度: {}, 高度: {}'.format(h, w))
    - o3 d" g& E4 f. H* `2 y+ w* \
    ) i) R  {% m% i/ a. `rgb = (19,122,171), s! [" f! b. e9 a6 t! ]
    bgr = (rgb[2], rgb[1], rgb[0])
      S/ _7 b% A8 ^2 O) w6 n" v6 m; n# (B, G, R)
      Z/ d2 K0 Q9 q' M' o  l0 ?for i in range(h):. W/ C+ s6 I- n! ]2 W; C+ V  o
        for j in range(w):8 x) E- @9 S; K/ `
            if (maskImg[i, j] == 0).all():: P0 p! b4 k2 [" W4 a
                img[i, j] = bgr
    : S% K4 c% `) A; H$ bcv2.imwrite(result_png, img)" X% @% w0 h# H8 J4 q9 Z& h
    print('图片写入 {} 成功'.format(result_png))
    1 }( ?0 J9 X" h3 {1
    9 j5 [( a% h9 W23 Y$ a# B8 H. w5 ]  i
    3
    : z$ S. y; p' x$ D4 E* f4
    . |: E7 n" `2 A& a2 _2 l50 Y/ Q: l* }/ R+ a' Q. _
    6# @& w0 W+ {0 [$ v; C5 X
    7
    8 F! y+ P& K4 B- b* x% f) l8
    ' }. I1 t& _' X1 S9
    & J* D" h# M0 W  K$ m$ J10" u8 I& t6 N/ T
    11& |& D* D1 N2 z+ h: H1 J: y5 D' p
    125 l# R2 l; F! N$ f" l
    13" A6 J) e. B  A( F! j6 M- Z  F
    14
    2 K1 G: d! f( D5 C9 B2 H15
    0 P0 U2 H1 Y6 T+ I/ I: `* Y6 A& ?16
    / G4 y3 N/ D  b17
    & Y! d% q! c/ G- `( x: L18
    ( r+ p  v7 ]. ^2 O- ?- T198 `5 H6 r! l" |$ M. R
    20
    , c. Y" d5 r4 W) s8 [3 ~' V21
    , s$ W" I5 Z2 @8 I0 S7 D22  c# X8 W& Z! {$ _# T& K
    236 [4 M+ P4 D+ z3 e* f
    24
    3 s9 w: b# v, R& T4 O# A- ]25( F9 }9 [1 U" {3 e0 N: v
    26
    0 {* O2 G( v$ \* `/ k, J27
    2 l  E4 J9 Q/ R; f% E! X3 V* F由于人长得一般,就不放图了…
    4 Y; M' Q3 g- `5 [1 ~! P  p$ ~9 c1 E& `
    缺点:4 X) R0 d+ q7 J' B7 H
    lableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。5 @/ H6 r, g1 g& ]; y

    $ N: T6 B' b7 p! T
    ; ?* V% ^( q0 ?$ y0 \+ W/ m( I5 j. H! n; x# i
    " x( J4 B/ t' F, `$ w2 e
    # _6 X+ b; ?/ I9 x
    方法二: 阈值3 ?- v; X6 ~" S, ]
    该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。, ~9 |; _1 u. p+ E. o7 z6 Q
    ! k6 a9 y# @% N* [5 s
    Opencv7 n2 x: h* \; F' R
    import cv2
    7 ?. t3 H+ f# v4 z4 pimport numpy as np
    8 d1 L# O6 N; j7 l' ^% P! v( A# K! _: }* {( V8 C5 }6 B
    2 S+ g2 \) B# `: J4 O5 o- X
    def mean_square_loss(a_np, b_np):' }- ?) O+ }) C: \1 ^) }
        sl = np.square(a_np - b_np)  h# U, V8 Z3 [" A  e
        return np.mean(sl)$ j7 T- g& ~7 q1 I0 A3 [
    4 X5 H2 K" N, ]

    - c6 v. g; o$ M" Fdef change_red2blue(origin_png, result_png):
    % `5 _- i; p4 v; X    img = cv2.imread(origin_png)
    ) E6 e7 g" [. X0 x) W+ X( Q( G6 P9 J, b" ?+ a$ Y2 Y( P  W# C
        h, w = img.shape[0], img.shape[1]
    / M! E- @( h! B- A2 v+ j/ n    print('图片宽度: {}, 高度: {}'.format(h, w))
    8 h) y8 G) j: B( }) y. b( E1 W) _: g& [# w. W/ c1 m
        origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
    5 d! D* r4 L( c5 _: Z" ~# R    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])8 m2 N; {) h$ m0 W. g9 w
        target_rgb = (19,122,171) # 蓝底RBG( {: v8 Q) {4 J' E  M1 u9 Q
        target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])" E& B. I0 S* k) u/ p

    0 h* q1 i) G9 \' d: h$ L" D' P4 v' t! X    for i in range(h):
    4 s( h/ h) o: E- I0 F( |9 G        for j in range(w):" ?. a+ a) ^9 }& J9 j
                # (B, G, R)
    4 R( j0 {# K  {5 ?& l2 e            if mean_square_loss(img[i, j], origin_bgr) < 50:9 G) Q/ H, ^. X- u" h
                    img[i, j] = target_bgr ( t# G' [# y( `) l& `1 a, H
    ; s' m/ c1 l: e- O* @+ i
        cv2.imwrite(result_png, img)
    ; E, p  |5 i4 E2 F1 h6 @( L" k    print('图片写入 {} 成功'.format(result_png))5 w: r6 E2 }6 K0 _
    - E, X3 Z* ^+ W' |( \$ z

    - f7 I5 _9 Y  L- d+ D: |if __name__ == '__main__':
      {  L' o3 k: d" f1 t    # origin_png = 'result_png/result_png.png'
    & ?) ~6 }$ p7 z% ^7 O. G: y2 i    origin_png = 'origin_png/person.jpg'. B3 Z7 q# j- v/ d. h2 }: \& G
        result_png = 'result_png/result_refine.png'1 c) t' h4 n  v1 [% U8 j
        change_red2blue(origin_png, result_png)
    , H+ D9 q" x0 q# O) |1
    $ `0 Q4 U, m3 q$ r2
    ; g% F( g9 s8 }* m! r" A3
    - L/ n: y* }1 ~- k9 ]8 |7 X4& m9 p# n7 V& y2 H/ q  N
    5
    ! R! W$ O% o( F$ e" R! m6+ @* m* P8 P  F3 L, G
    73 B% j( U$ `0 t1 k( p+ |
    8
    8 n# ~4 z1 V) h* C0 u9
    5 g5 }5 L  }$ |1 m10
    9 u5 w+ T  F# y  f3 J112 Q# b" @8 C* o" v4 J
    122 z0 `- a1 T+ }% C9 E
    13
    % u( j+ }- C: |* l- T# ^: m8 E6 T' y14
    ! c* o0 F3 n5 Q+ Y. d, X  G15% e- s$ W, ^0 W. R! H, N0 Q
    16
    + f& S6 u' z* b176 Z6 ~0 m# n# I  L. b# g3 U
    18" ~; _+ O( K+ L- e9 D
    19
    ( @6 j" X, b' x' `% `20
    , A. ?" _) z# D" B21
    # U: |9 m; b; _( N. M22: D# x# L2 H/ [( @
    23
    ( F' a1 z# Z1 u24- _8 H& `' {  b+ m* E3 V
    25
    : S' B# H/ N2 j  p7 b) ~26
    % A- n- j3 M( b27
    3 X6 ^& L5 Y- ~28& W+ P) |9 O, K) E# U, `
    29# W% Z6 N7 M; H2 O/ {. Z
    30% s5 s) b6 C# }
    31( R' y8 P" H% k; \
    32; ^3 c( r* y4 g
    338 C9 s* v5 w. v7 W1 a" O9 q3 z
    34
    " k6 {/ i4 h* O/ ~35# U$ q+ {9 \4 x' r. c
    结果人与背景边缘仍会存在红色像素残留  S& [, s% V! v8 O: q1 O$ f
    0 q, n5 y5 `8 F: l0 S
    % a0 W8 f$ S" O' Y

    $ {& b7 V2 I( r; F& s/ M+ E3 a: v1 y( s8 `2 [* w

    ; a1 |. [' y7 o' X, ~' e, iPIL3 }2 Z6 W& z4 D
    from torchvision.transforms.functional import to_tensor, to_pil_image/ ~  }! j6 E" b3 p  I
    from PIL import Image" v1 \' V! i  o/ Y0 O
    import torch4 u& P- U' g/ ^2 f
    import time+ p4 f# s* a2 h1 ]: I
    0 I. ]6 V& Z! |" u* @: P

    - v7 w: @2 A3 e7 n0 x) ~! M5 ^def mean_square_loss(a_ts, b_ts):8 r0 }7 L' c  {$ J# |  E% S: h, ?
        # print(a_ts.shape)( X6 n- J$ q* h: C7 X
        # print(b_ts)
    ( j: k5 g! |' {+ K3 Z+ W    sl = (a_ts - b_ts) ** 2
    3 p3 c8 ^# D) c- o2 a    return sl.sum()
    - O- B8 Y8 P( ^* l5 F# K" @- n6 b! B; x* T9 l: g

    " r0 I8 i0 k: [3 |; {5 O& ]def change_red2blue(origin_png, result_png):
    + H# `; _! b1 `    src = Image.open(origin_png)  y6 \. l$ ]7 Q5 v' x, v
        src = to_tensor(src)
    , W8 I& L) [3 U. K8 V    # print(src.shape)  # torch.Size([3, 800, 600])0 A2 K9 x3 Y. a! t* o" U5 L2 m1 V! ?8 ^
        # channel: (R, G, B) / 255; ~  q9 n; H) C+ J- ~0 ~
        h, w = src.shape[1], src.shape[2]
    ) G0 _# g  [6 H+ {, A. ]; h; a
    5 l& A2 u& m1 W4 s% j, h    pha = torch.ones(h, w, 3)
    3 n7 W+ X4 u% x0 o% x+ ~
    : G+ i; S- n8 a) G. l$ @    bg = torch.tensor([168,36,32]) / 255
    # j6 B- n9 D% g' e6 J' v    target_bg = torch.tensor([19,122,171]) / 2556 W, _$ |- z* v

    1 z9 D& ]  _: w0 v8 d/ G7 k: F0 R    # C, H, W -> H, W, C% [2 T1 J1 S. b7 r( a
        src = src.permute(1, 2, 0)2 G: Y3 Q0 [5 X. Z5 B
        for i in range(h):+ `. }9 ?- X" X3 P# a$ n6 S8 V
            for j in range(w):% b7 |  b0 m% P# k
                if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数' F& h! V6 Q( z  F4 l" l0 G
                    pha[j] = torch.tensor([0.0, 0.0, 0.0])- _5 t, m* |) ]+ c' Q: z3 }# p6 \
    ) f- s1 D. D2 [9 r
        # H, W, C -> C, H, W
    5 J' u' }: v& e; L7 \, a    src = src.permute(2, 0, 1)
    $ u' x: W% o( U8 q    pha = pha.permute(2, 0, 1), A+ z: C( K- P- J
        com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)6 C& D" @7 Z. y+ ?
        to_pil_image(com).save(result_png)6 z# b0 _+ a7 H- f: \. w- \
    * G) I9 E) y/ |/ i4 D$ b: E5 a
      T; Z/ q# ?" @0 |) L0 u$ F
    if __name__ == '__main__':, b/ d% R* Y  s5 ], R$ M
        origin_png = 'origin_png/person.jpg'
    5 O; Z* ]6 v& Q, ~6 O+ Z4 F5 h    result_png = 'result_png/com.png'7 G9 C. u! c, c
        start_time = time.time()
    1 J$ k' c% ~0 H. B; |, i7 O8 w( ~    change_red2blue(origin_png, result_png)0 [/ L( w5 u3 A1 F0 p9 ^4 K* _' C
        spend_time = round(time.time() - start_time, 2)* g# z/ n4 p: Y- d2 h: M% r
        print('生成成功,共花了 {} 秒'.format(spend_time))
    . h+ }  B& @& T5 t  n4 Z8 ]: [1# A6 x) Y: ?. g% n% p# ~
    2( `/ F' Y8 M/ E6 F3 _' e
    3$ _8 }! _, u% Z/ `8 H5 V
    4
    $ a' o3 L  v! H2 l. G3 l2 b- _5: `% P+ M5 L4 f/ Q( \9 ]$ Y6 G
    6
    ( `7 g! A; b" s* e: A7
    ' I. R# g/ n$ b7 n3 e% L8
    2 ~( F, f$ e* g8 K+ f; T* z. m9
    ; s- S& P1 B) N3 ]* M1 b% y10
    5 X3 |2 n. T" I6 X  ~11
    2 S% J, Z1 Y& ^1 e12
    1 Q/ C7 `4 k! X. K6 s8 `13
    # A, O( C- j, i6 d$ F! b4 K, r143 Q" V1 u/ t5 ?+ S
    15+ u! I! y& c9 F( D! |
    16
    % V* K7 e- J( {* v. L# X17
    $ u: `0 w. e. `# \  [18; H( G6 ], k3 v2 t7 s- l
    19
    # Q2 H' A# E' `0 ~+ v7 a5 K# i205 d( P- A% S1 t* b
    21- P( W9 V) k( |) u9 p+ C
    22
    & o* \7 o3 A  U8 z230 h) K' o/ K/ M& n9 N6 G; I5 L- O, ~9 L
    24  }# b2 ~5 k3 S. e' O6 {
    25
    $ _  `1 A" j& A* _$ t267 `; L, W5 d# U0 }3 q
    27
    ( b& s# h- I, O( a% C" A5 ~- [28' h: q0 d1 e' O! s
    29
    7 v$ a" A4 Z- g, i% a: M30
    & g, {6 A  F0 N9 p4 N31
    6 n" u! J- K, M/ ~" y32
    ! [5 L' G" T: e0 V9 h: }4 }, s& Z33
    ) Z1 j" J# k, \6 J! R- s( i34
    8 V1 J( d( ?! _0 o) s2 V2 r35' a1 O! C2 _) r! y5 P; h' t
    36
    5 b0 ~! A+ u4 o373 B) G7 C; e2 T; F! ]
    38* V3 m1 K! O$ Z3 V1 C! l2 m
    39
    0 ~9 O0 J1 ]! r* n- ^401 L2 g* T0 P2 E7 B3 @
    41
    & S$ f- X7 s6 @427 [' p' Z' G/ E! o7 w
    43
    / G$ K2 M  T# d! x( _6 W44' E4 N# s2 ^( ^( o- B
    45( Z% o! b1 X6 A$ ^" b3 X
    46
    # P0 \$ S1 u. y' `该方法质量较好,但一张图片大概需要12秒。
    5 e+ {5 M/ _; i& H4 }4 x% O4 M7 }' o$ O
    3 V3 E# j# _: J* p  g
    ' ?9 {* G8 m2 ~# N! F7 o
    方法四: Background MattingV2
    - W6 E; p$ U! q4 z# rReal-Time High-Resolution Background Matting
    8 K/ I; Z& ~6 L; f; l" a, WCVPR 2021 oral  W* `/ T. h" w; W* ^% u" e
    4 Y; _5 B5 ^% @3 U, C6 \
    论文:https://arxiv.org/abs/2012.07810
    " E! D# y& X8 |. e# d代码:https://github.com/PeterL1n/BackgroundMattingV2
    + G* n3 b5 S+ M- I) w  R5 Q) _6 `$ K; c7 g5 n
    github的readme.md有inference的colab链接,可以用那个跑% E: }8 o1 j0 K
    . t% l4 |1 x  x$ P6 h
    由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。
    + {* u) Y' v+ N, r; K3 |" o5 a; E, l7 R% K& n' w! O  w- U
    于是这里我需要生成一个背景图片。
    ) \5 S+ u6 u3 z; K首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。# v6 O# J" G, J: B
    3 M1 R: m3 ^1 M# u0 u4 b2 |1 ]* N
    然后生成一个背景图片。
    , V* @' f6 {2 n+ a/ `: X
    1 |& E. c* F+ Z+ V, @3 p& nimport cv24 X" g2 R' q2 K( {0 i" t
    import numpy as np
    8 |; _8 }9 D" k( ^$ L- C8 Z6 F& ], F7 f: U0 e% d4 H6 T& v
    ! J% l6 B% R; l
    image = cv2.imread("origin_png/person.jpg")
    4 w% |  |. ^0 A4 L" v5 ~: Z1 horigin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值2 ]2 @! A1 n. R$ x/ n5 F% S
    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    4 i2 K" M8 r: Iimage[:, :] = origin_bgr  r. S3 v- [) D( w

    + V# O4 a: n* ocv2.imwrite("mask/bg.png", image)
    8 M% \4 Q& w# y! w# e. @, w; E1
    7 S+ u* O; q3 q! a. }6 s21 q: G' p- U0 c! B3 E! T" m
    3. V5 E1 }/ K0 J6 w
    4
    $ y. @* G7 l, s2 p" I6 a5
    ! i$ B* b- K2 N) O4 u/ a* R+ M1 d6- `2 z7 X( ?, h0 d
    7
    + ]" i8 V) s' ~& E; G) w3 l8& ]( i, q- e! D: V( v
    9
    ( I: I- P* ]5 L- {- F/ \10
    . I9 N1 r2 K) s+ B. s5 C# d. u$ I- R
    需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码
    - L' V. O* [! n
    ( w. d  ?% h5 X+ N; v' ssrc = Image.open('src.png')" m: W& g. `$ X& h* ?( J
    bgr = Image.open('bgr.png')
    3 I  I! r6 M8 L3 ^" x  x- f12 E% \7 u  q; P  f
    2& {) W0 N" Y" W: y/ b! ?7 z& j
    另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)
    7 `  U6 u) s% E' m" A2 \9 k
    ' B+ L5 N# W; ~, ~2 k2 Ucom = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)
    4 z- [8 j* V. V! I; e7 m* z1
    2 r! L1 ~& m. c( Y5 e
    4 ~+ M/ W- f" _3 [- M, s% r9 z那么加入我要换白底(255, 255, 255),就是
    # b/ T0 |7 `; D* ~
    4 W+ i/ q8 ^. @) E( Ecom = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)
    , B# D6 p4 Z) P: @; F) K( U1
    ) |* j$ t7 \! c0 w+ V' l- f) h% d: u, V
    假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是
    . C. [: O0 B- F( ]# R
    $ C- K$ ^: y+ a; d% Y, ccom = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)4 H" Y* S6 a: h7 @8 e$ |
    1% l/ R3 s, {* ^+ k
    总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.
    " H  q4 j8 O' K, h7 O
    1 V- q+ p3 C% b8 F. j0 Q然后就输出图片了。可以看到效果相当好。不愧是oral。6 g2 W9 \4 h7 ^
    # J* H" x" ?  N2 U( K  v

    $ L2 k7 A$ R% Y原论文可以实现发丝级效果5 m' S, O/ [0 p6 F1 }" E
    ! Y7 a5 ]8 |  s& Y2 t5 ~

    : Q" D) d) K2 i9 m" A! ?  `' E9 N: v% L/ y9 l. g8 p

    ) N1 _- `7 a$ ]% C0 V
    5 S! _- U2 y$ g: a& e% [! t4 h6 N报错解决方案
    4 u* d& g& A3 m% J. Fcan’t divided by 4 / can’t divided by 161 G( Y/ s1 o/ J0 c8 ]  S& C$ N7 ?2 I
    由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。! t! A: O% ?! h: Y
    这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize
    : z& Q; h! V+ G# ?# e————————————————. d2 d" ]4 M# J8 Q- S! O' g
    版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。/ ]4 X0 b7 {# S) O6 d
    原文链接:https://blog.csdn.net/weixin_43850253/article/details/126376767
    % y8 K* K1 |' S: a- N  h; L6 p( G+ J" F! s3 J

    7 B* H; P- ~. I' b" 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-6-15 02:47 , Processed in 0.401920 second(s), 51 queries .

    回顶部