QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2086|回复: 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将红底证件照转成蓝底
    8 s; v$ B& f- t% ]6 C) Y- ^+ `前言# U' S# N' A% X, b
    emmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。4 W* W- s6 l! f$ j) }/ h" N

    1 K. V* \& w0 A
    , C0 e+ M7 f9 M1 w. h/ c9 |/ ?8 S. _
    3 p# L# P: b9 E4 `2 b
    方法一: lableme
    . P" L' h$ y. }" n' R) ]4 Ilableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.
    6 l1 y) X8 Q4 {+ \3 X- y
    3 @' M2 [# _! D: a1 X9 M$ y1 j& w4 [# 代码来自 https://blog.csdn.net/hello_dear_you/article/details/120130155
    6 \& p2 ^3 ^* i& A9 ~import json
    , a1 Q3 M$ S$ g# Q- Simport numpy as np
    7 C9 k3 P# X, }: M: h3 Z* dimport cv27 T8 x$ _- S' ^  v/ ?
    # read json file, i3 U! x7 e8 }" C! M4 X
    with open("origin_json/mypic.json", "r") as f:+ i; @; |" Z  ^' Y: a' ~
        data = f.read(), B. I' u8 g$ E& p1 E! L5 u
    & h$ n; j% F  k* o3 T$ @2 S
    # convert str to json objs
    ; I; {' \" W+ ?: Zdata = json.loads(data)
    " l; Z8 n( e" l. B8 U- ?. Z$ u6 X$ q2 Q, f
    # get the points
    . y9 T' G7 c/ n( A' V/ Bpoints = data["shapes"][0]["points"]# \; M! v( M0 S! z4 l- s
    points = np.array(points, dtype=np.int32)   # tips: points location must be int32
    3 a% u+ a  L; B5 j& P. b. }6 J( W( ~$ u  U" s& |1 X6 ^
    # read image to get shape3 k- z' G  m$ ^) f( H: r: C
    image = cv2.imread("origin_png/person.jpg")
    + P: ]# a# V5 V1 e2 U
    + F" z1 p: m8 M: S4 _8 ~0 @8 p, H# create a blank image
    + o$ _* t0 Q& o% o6 c  Z% gmask = np.zeros_like(image, dtype=np.uint8)
    * v9 i7 r1 @; {) R; m) z) z, _2 [6 b; [/ Y0 G9 X
    # fill the contour with 255) c' G4 l' F3 O) u8 V# Q6 H5 A* R
    cv2.fillPoly(mask, [points], (255, 255, 255)); v7 D( f4 p% i6 P
    * l4 e" |, ^4 X5 O4 K
    # save the mask
    2 o/ A! ~6 z/ L9 G8 t+ Hcv2.imwrite("mask/person_mask.png", mask)2 i: B% }# ^( W/ z+ o/ A# L
    1, `7 f* O- Y$ v/ ~/ M
    2
    3 c- n2 ], c4 p/ k3+ U0 A- Z, L, k% R$ k4 ?  f
    4
    . W9 W% H# a9 l, r5' ]' m  |0 _9 R/ l6 ]: P& ]
    6
      \- j. l) n7 _. j$ \0 G7% N- J, I- S: I! F9 _
    8
    / |8 B8 y! E% g- g( s94 J( C- D$ {# V" @7 r' y% u  }5 z
    10
    3 |- M* G* A. b: H; L5 K* ]! b8 j11
    " ^6 Z- H# c9 u3 X12
    # G9 r0 V' m& x13
    - b- q  S; n! L; n8 O  w: o& n14
    3 A- d& Z4 o( U; k) n+ b/ f4 s15
    : Q5 d: r1 N7 Z% V, x3 y7 ^; B16
    " s7 y8 T) P* [, X4 ~. I% S17$ h: b- @& ]6 ^. q2 a
    180 b( M- O) o$ G1 a9 M, `
    19
    % E9 s3 @# W" q7 f, \20% _1 e$ l2 c+ \
    21  G" H9 c3 |2 T" U& \! R
    225 Y) S& b& S$ J) H: J6 B4 U- h6 S
    23
    : H/ t9 X. M3 O  R2 I& Z24
    / q  f, `5 ~! |+ D25& j% f5 K2 Z# e" |5 U6 x
    26
      ]3 ?+ p) Q1 j大概是这样:- O; r8 C3 d1 x3 E/ n; B& Y! b

    4 l" ^$ ]9 L, C- a
    ( ~1 Y3 k: v& M0 w然后利用这个mask生成图片; M1 u# t) h- b) \5 W
    * N; j8 s* ~: ?$ H) r
    # 参考自: https://www.jianshu.com/p/1961aa0c02ee
    5 _" y9 t: s% V, m% J& s2 R& Rimport cv2! f. z$ v# o; f% b9 z3 n
    import numpy as np' k" l; Q' q5 k

    ) S8 V4 i. Z% z0 Z, B7 H. [$ L2 V: d; w* ^% g! `) O2 m/ m+ C
    origin_png = 'origin_png/person.jpg'% |7 g9 t1 `' [& i
    # maskPath = 'mask/person_mask.png'. X6 s8 B0 V( V& a6 Y6 I7 @
    maskPath = 'mask/bmv2.png'
    ! n. k( e1 ^. d) k( aresult_png = 'result_png/result_png.png'
    / P6 H/ g# k4 p" @2 C3 Q
      ?( u- d. j. k# t% ]# }/ a  l( c3 P0 R, V+ y- Y$ c5 c
    maskImg = cv2.imread(maskPath)
    ' @: u5 b/ c& e# himg = cv2.imread(origin_png)
    / n# D- W6 a+ U' E5 P" uassert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape', D' Q% r  q- @+ n0 X$ }

    1 o. O+ N1 u4 w& G6 W+ p& P& y- I) Oh, w = img.shape[0], img.shape[1]
      m+ t( ]! N5 Z# [$ E9 cprint('图片宽度: {}, 高度: {}'.format(h, w))
    ' q0 e( L4 z3 @* [; B
    . N9 Q' I, }; K; K( ^3 hrgb = (19,122,171); |( U$ ~2 t$ n( }4 C
    bgr = (rgb[2], rgb[1], rgb[0])5 w/ {, W0 O3 d/ n6 J
    # (B, G, R)
    " G9 L  `8 Z& R2 @% S3 m7 Cfor i in range(h):
    / x' v) q1 b9 K    for j in range(w):! Y  Q0 s% L' k! B0 \/ N
            if (maskImg[i, j] == 0).all():  T& b8 j; z2 R
                img[i, j] = bgr/ E) R& a/ q5 V( S3 A  ^" |
    cv2.imwrite(result_png, img)& ^. Z# c  K) d
    print('图片写入 {} 成功'.format(result_png))$ N8 Q3 F5 X7 T# [/ F* ^( P- N
    1/ o# g# h4 C% _: \$ [6 [
    22 ~5 r& A; E+ u: h
    3, G7 ^, o. N/ n& r
    4
    6 g4 W6 ?1 q5 m+ p5; l2 `# i1 h7 C/ {! R
    6
    / y; \+ \, [" p6 C7' [  m, s* d4 ]0 A1 j+ `( h
    8! J4 E" w3 v  D* t( B' Z: E
    9
    - |* O1 x' j1 w  T: ]. Q8 k' v10
    ) i& C( N) l* @" S' M0 B11* c( u2 x5 [: b* v6 v
    12. n4 T  M' Y; \. N$ G; }! o9 Y
    13
    ! m$ Z  I) D' R% P& e& T, A9 G14
    0 W+ ?8 e: |: [) i( E- b  L15
    3 d$ p( F9 ~+ F- G; h9 B7 v16( S- {6 z1 C- J" Z1 G! u4 [" |
    171 m7 l& \6 W8 M$ F8 ~" d5 A+ r" U
    18
    3 L2 m% z' ]) p* Y6 Q3 b; ]19+ I7 {& n9 `3 Z3 \# b
    20. J  T) d+ Z5 G4 Q. ]
    21
    7 y6 W+ M& P: h2 I2 E7 {22
    1 S" [4 r0 Q; Q! Z/ X( |23
    ( p1 D7 b1 \+ Z24
    : h" i: Z9 _6 P9 v# p+ n25( r+ R/ X: T' x! S1 _3 g) z- r
    26  W; ]. _# o: A( b% V! Y
    27
    : |4 b5 c+ _9 ~7 _* n4 u2 o" t由于人长得一般,就不放图了…* v2 ~, X, R7 V( Z+ F& I

    4 U0 _" o% E  [8 K" @1 o缺点:
    7 u" E2 z5 z. z3 G% @3 H& V, p* G& Jlableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。# q* t) D1 Y, F2 z
    ! [8 q7 o! K' }, H! D' N
    " ]( B/ B! V% G8 N, H( s

    ! {7 n" I0 O  T+ Q# ?3 h, ?( i( ]$ T6 o0 m

    3 l4 [2 e5 X/ i: D+ S+ P方法二: 阈值
    3 q- s- `' ~4 f该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。
    : y. i8 z2 s" H# o8 T7 U8 A' Y1 I, P$ p2 `  T1 j4 W
    Opencv
    : u, P, x' d6 }1 L# d4 _import cv2
    1 t. x) Z7 b0 O1 Vimport numpy as np2 F$ H& r, J) ]2 X

    0 t1 ~1 ^& A5 b4 X" e6 C0 a6 B$ |+ S: H- C
    def mean_square_loss(a_np, b_np):
    - k0 k& s0 E/ w/ ~, F. {    sl = np.square(a_np - b_np): q8 v& G0 N, x7 ]. K0 r
        return np.mean(sl)$ d( K$ y; T- \  J
    3 @4 Z& E! P' k

    2 k+ a( y8 i- ]" rdef change_red2blue(origin_png, result_png):0 N3 P5 v% s2 K0 Y" O+ y, k! U
        img = cv2.imread(origin_png)( K8 M7 s8 [. k7 S# U- I: k
    1 Z0 o2 x2 _) c
        h, w = img.shape[0], img.shape[1]
    1 S9 X" d/ y4 b3 S    print('图片宽度: {}, 高度: {}'.format(h, w))
    ' d$ c+ I" K7 H( }2 `$ E& u) Q+ X' B1 p" J: m5 o) i. a
        origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值2 P3 c, J- E) R2 t. h9 E
        origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])9 T2 v3 b8 a4 s" W3 t. V. A2 ~
        target_rgb = (19,122,171) # 蓝底RBG
    + S0 z! p3 F6 {) L    target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])& s' R8 r4 O# @" V
    1 \9 U8 e9 l6 O+ T, `" Z! P8 d+ t0 c  _
        for i in range(h):9 f8 [# ?3 B( i) s5 A- u6 n
            for j in range(w):1 q: k+ Q! p* V1 @" F
                # (B, G, R)) B9 H$ g2 s- T4 q
                if mean_square_loss(img[i, j], origin_bgr) < 50:
    ; n1 X7 w9 y9 z, @* B/ t                img[i, j] = target_bgr
    3 C' J, M- T. @0 s7 \9 U3 M/ p) @$ q3 N9 C
        cv2.imwrite(result_png, img)5 ]& Y2 f2 V' m( U' ?. E: W9 A
        print('图片写入 {} 成功'.format(result_png))* f* d1 y! {+ ~8 N) b& A: g

    ( c' I9 T' l8 b& {5 U  K  x& [% P" l! f- t( D" _; A9 [0 C7 n) G5 V
    if __name__ == '__main__':
    0 z+ R3 e% _, ^, ]3 p    # origin_png = 'result_png/result_png.png'6 _$ Z7 k# H$ P  j$ ~: W
        origin_png = 'origin_png/person.jpg'  K9 ^2 X. y- I7 j- L6 J! B  j: ?6 z
        result_png = 'result_png/result_refine.png'
      e+ Y7 c  R& A) N# g" ?, X4 w% r    change_red2blue(origin_png, result_png)8 Z, T* F+ L# @8 L4 M- |
    1* P3 z0 w# M0 C+ Q# s' J% B+ k
    2: L6 w+ I( B1 f; T( X
    3
    6 M3 v4 X% i- T$ r4
    7 a; A, K; z+ n7 V5 K5
    + I+ o1 J5 o0 E: @, d% N/ w69 Q) U" B* f) t$ w+ z
    7+ h* ?& D/ A7 ?) M
    8
    2 }7 G, ?- T: o8 I- r8 O9+ u. U) N: U0 ]$ h* c0 x* S
    109 I& x6 S. |5 u) X8 _- g* H* O) B. d
    11- f- x1 i+ V6 A8 U
    122 j5 [7 j4 R2 n5 @
    13
    " t( N& d* k% E8 F+ ]* }5 h. f14  R5 I3 h, w& ~) Y: y- Z* B
    15" v6 m& W8 s4 F" W6 _* b. a
    161 [' x/ o( z+ x( A0 n- f
    17! r! \$ i8 T6 U6 g( {! u' x
    18
    ( Q# |& G0 z4 Q: G; a, }/ k" u19
    / S; a+ t0 a( r, i2 U6 M20
    & y7 h/ [, k" \2 T; A215 J9 B8 h  C" i* D& W! K- G4 S
    223 A/ y+ F3 M( }. x" g
    232 p% B4 L2 N+ F9 v5 X
    24+ i/ w& l% }# k$ z' E4 F2 x( P
    25
    & _) J! R3 O, ~) l* |3 n26
    ! _9 f; G/ V2 x2 P* u( [27
    $ d  _  g3 N9 H1 k4 t28- G% K; Z. Z8 B% b1 \( Q9 Z- A! V6 U  u& A
    29" [; O3 @8 R1 w, g* G) b( a
    303 B) u; @- @" v2 @# f* z: k
    319 ]7 N% R4 _& _7 ?/ V* J" }* D9 o
    32
    : j; J9 h, x/ P; e" [33
    " N. Z4 K9 L" X" c& D4 G34
    ! J* a% {! e1 k) p* q; M350 l2 \" l9 i" x1 N
    结果人与背景边缘仍会存在红色像素残留
    ' f  `. l2 E) C- x- O! K
    - r6 k0 v3 b4 L# j9 N( \* b( y: g+ E6 S7 D6 T8 y) W# \% p

    ' C1 W6 n! v/ E  h7 b% o/ X7 l
    $ ?" ^# u) Z7 }$ k# h, i5 V# E' J" f! ]. W6 x) s
    PIL" r: z2 X6 x( \6 b0 }
    from torchvision.transforms.functional import to_tensor, to_pil_image
    3 h5 E; U4 h/ V  |+ K1 Sfrom PIL import Image
    4 Z" o1 r: m, b. i0 N6 ?import torch
    , b' V' r: x8 `% O: K/ w2 ?( vimport time, h) ^% x+ \5 C' h% z. g

    % `2 J, E- ~) k  ?
    8 C0 t8 C3 Q8 l. M; \4 Fdef mean_square_loss(a_ts, b_ts):
      Z+ y, Z& h3 h( x" V% N    # print(a_ts.shape)
    : e* K" A- M) L+ w0 j3 H( g    # print(b_ts)* m. ~; F0 E: b
        sl = (a_ts - b_ts) ** 24 d3 w; ~  C& [* t0 B" f" h; z
        return sl.sum()
      h! T+ Z/ c& X8 g: X3 L  m/ Z( \' l! {" I2 c

    9 k# f% s/ l  i; l8 @8 l2 jdef change_red2blue(origin_png, result_png):; K# [, s$ a! {  v0 z
        src = Image.open(origin_png)
    & _6 v- b0 x. @' c2 a4 u8 i    src = to_tensor(src)
    % p) T& _) L7 h6 }% d    # print(src.shape)  # torch.Size([3, 800, 600])) n' S" T% ]- K
        # channel: (R, G, B) / 255
    ) H5 m. s5 k6 X    h, w = src.shape[1], src.shape[2]
    . a2 H2 Z1 U0 b# ^( n' F& ?: d( W" {; i
        pha = torch.ones(h, w, 3)
    ; }0 k# p" o$ n+ }
    : R5 C+ U* Z1 K# ]    bg = torch.tensor([168,36,32]) / 255
    % ?% _2 k7 }) C% i6 P7 x    target_bg = torch.tensor([19,122,171]) / 255
    % a( |* E/ F) }4 K9 ~
    3 z4 x4 l! B2 s! i. c& x: }    # C, H, W -> H, W, C8 n$ v% s4 C3 Z+ k# `$ g
        src = src.permute(1, 2, 0)
    ' V: c  y( |% {8 B3 G4 \    for i in range(h):! X  E% ?( ]9 {& o5 W) a' R
            for j in range(w):
    1 ]- L. E, K5 F& b; \  \            if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数
    2 X: J: m/ ?( O, W2 F5 R% h$ Z                pha[j] = torch.tensor([0.0, 0.0, 0.0])6 h2 P3 u# [( I& [5 C8 W
    * y+ R  M$ u7 w* Y2 F
        # H, W, C -> C, H, W4 J- B; p- _% O4 K  [+ w
        src = src.permute(2, 0, 1)
    % h  B6 z5 i9 M5 X* s    pha = pha.permute(2, 0, 1)  L4 k( J/ C& p1 ~( z& \
        com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)
    " _' j- P9 f$ T! i0 ~, U    to_pil_image(com).save(result_png)
    % U- L4 c5 N! s  m2 V" v  _$ i8 J5 y9 L4 S2 a
    / k  j' a) U6 S/ Y/ Z1 T
    if __name__ == '__main__':; ?. d2 J) y: F9 @# o. Y
        origin_png = 'origin_png/person.jpg'0 o1 l, u# F- B, E
        result_png = 'result_png/com.png'
    2 I$ F- ]2 |0 t2 W3 _! p; a    start_time = time.time()7 ~5 [* ~$ V. s3 c3 p
        change_red2blue(origin_png, result_png)# _6 [+ _3 U$ m* U* ^
        spend_time = round(time.time() - start_time, 2)2 s# K! x7 U4 }: W
        print('生成成功,共花了 {} 秒'.format(spend_time))* l1 U+ ~/ Q( D" }
    1
    : A# p- K: t! Q2 X' A: I2
    0 @* ~% ~6 U1 O( f, U! R3
    ) B8 o  t+ n4 w2 b  t$ o! L4: }9 ~' h0 u8 s; o( Z4 @
    51 u1 h8 I- P* S
    6  Q) f2 L- I3 t2 Y2 y
    77 P- g2 f3 j- @4 T
    80 X. A. g8 Q: C% T) G2 U
    9
    % E" j# P: Z+ m9 ~7 f" V10# f" Y5 M5 H# K$ |3 b
    11
    4 r6 l, t& |: ?3 h* ~6 C6 F124 j6 F- S# Y/ `2 F& `7 ?' k* w+ e
    13
    : L0 T+ M, l6 _" ^142 Z& A. i  C# R* B
    15- x* E  X( y' h3 t0 u
    16
      t4 @: l; \2 ]/ Y, p17
    " Q4 L6 u- @' a. E& K18) W5 Z$ i. O0 J) `) m0 g3 X
    19% l2 `# c* _* R4 r7 I
    20
    6 k: K5 n9 V3 U  Q, R6 F# ~212 g% j- {/ u6 x, x$ q8 {5 N
    222 ~) ~* ?2 }+ i' \
    238 q6 h# V* e9 g5 L) `3 M& a/ ]
    24  l  ^) U. {0 x; O
    25; \3 B) {4 \( k# l$ z
    26
    3 P9 Q) ?- Y9 U2 A0 L27
    ) k$ P) G( T! q28
    4 n9 S0 Z% n5 k7 P299 q- u& ~1 C# j, N" d. ?( K
    30
    3 v9 j9 b3 J2 ~5 S0 K317 m$ O. ~" z) |
    325 h3 C4 K8 u4 T! _: L( G; e
    33: C5 R% q" K8 n9 O
    34
    ; m; Y) X5 P% M: L- `) ^357 |' U9 }  x' ~" F2 I
    36# J$ o- d: k0 S+ o
    37
    . b0 X, C$ X8 f389 S; u! l3 K2 b, \+ ]
    39
    3 x2 B4 `  h1 O4 K/ r! T' a40
    6 c- Y0 F  F/ o! c; I  Q3 m( |411 E2 E; E8 ^' d; {# i3 f8 W
    42+ s% ]% Y+ q9 ]2 p
    43
    + P, H& |/ I. |5 D0 b6 C2 j44, Q& f  J8 E" o* m4 l
    454 C. ?( f9 X2 a  ]1 o9 E; C
    46' J5 o& ^: H8 g4 c6 [8 C2 r
    该方法质量较好,但一张图片大概需要12秒。
    . h5 O% Z1 X$ c: ]6 H' ~; x
    ( h0 U6 p" c1 C! }& n: o% }
    0 D: K& D7 S/ R& r
    0 j( o5 F  S9 ]方法四: Background MattingV2( H! r' _! R8 ~" n( v
    Real-Time High-Resolution Background Matting$ i# X% X" X% P5 `" N
    CVPR 2021 oral
    ( i: `) z: A: {5 [5 p. P8 ]" b2 G
    . z9 g, e5 T( J论文:https://arxiv.org/abs/2012.078103 f7 W$ b; |* H1 I: [$ `3 w
    代码:https://github.com/PeterL1n/BackgroundMattingV2
    * c' n# E$ \0 ?: b& v$ V. \8 B( D8 l1 h4 h
    github的readme.md有inference的colab链接,可以用那个跑
    ( Y3 X* J7 k' d; I2 N+ [3 ?4 i# c& e$ T* R) M5 \+ ]& ?+ j6 f
    由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。$ E  e# ?9 \' X% L
    * G: `/ b0 V, ^- x2 g1 u- Q8 [: w
    于是这里我需要生成一个背景图片。
    4 p7 V6 |2 v$ J# L# f7 q3 ?. k& o( ^首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。* e4 N' ~5 U. N$ q9 R& Q% F2 J
    & L( a" x7 z6 s- _+ `; u) A3 F
    然后生成一个背景图片。
    6 w/ Y' @6 o9 H) J9 {/ G/ f' F) k/ Q% |
    import cv2
    3 n9 L2 P, R9 Fimport numpy as np- p0 m7 B. ~) f( X% X! S$ Z

    # P( u8 z8 r/ f; ]; L' b" g, n9 r5 s1 h. t
    image = cv2.imread("origin_png/person.jpg")( X3 @1 p: z' x. |
    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
    , m9 }4 W% J+ @' u3 {0 ~origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])) @9 W4 x! y- }# c$ h) m! O
    image[:, :] = origin_bgr
      G0 T' O7 D6 f" K, d& A# K
    5 J2 b+ k5 @3 pcv2.imwrite("mask/bg.png", image)% L& [* }$ i, f  L$ e' H7 V
    1
    * R2 d3 R) o  _) E# w2
    8 O4 P# }" |; A3% x, I) p" {* O4 P7 W! ?
    4  i& \/ q/ h+ p
    5
    ( n, U& b+ G" X; t6# H) T% p' d2 q5 s5 r7 l4 J
    7* J  J: n& H& H) x- ^) b8 W3 j0 \: u
    8% p4 }) I) P' ~, F  b. B& \, U( _1 W7 u
    9
    5 o( x0 t: S1 y10
    % m: f# X' m' @
    4 }2 t/ b9 b6 ^- S需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码
    : @! I. D5 m1 b5 n& g  V
    2 b" _% S% _% v  m2 o- m+ \+ j+ g0 Esrc = Image.open('src.png')
    # |0 R6 T- L3 T! I$ Jbgr = Image.open('bgr.png')
    : z3 |) `& R4 Z2 O1 I/ a3 {# A1- w* w0 R1 U; E) p
    2
    # H3 a% i" J/ i6 }. T/ ^0 z另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155). v1 G; p7 e# U1 y4 L

    $ ]1 l8 x9 n0 o) jcom = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)
    ; H; }8 ?9 j8 `1
    # F" H1 q: V8 _* g$ n& `- f7 X4 M2 A
    那么加入我要换白底(255, 255, 255),就是, m. l. D2 ]0 W' [* M
    & Z$ R8 J8 u2 `. Z& h4 Q
    com = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)
    6 E3 x, I+ g& d; M8 j1
    7 ]; \; o$ O6 a( r+ C2 ~6 x
    5 g9 g- @( q2 T. F假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是
    # @; k4 z; p. z( D; Y" Y+ d" L. o7 V- H
    com = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1), W& f3 b2 M! y. ^( B' J) J
    1& e7 ?6 t0 m4 k% n$ t
    总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.4 K! Q6 M6 r0 }$ d" `: h
    # g' M" e- s6 Q! T* u
    然后就输出图片了。可以看到效果相当好。不愧是oral。# E6 g. H8 n; b; P# Q( \

    $ D9 h+ u# p  z
    2 e5 b1 R- P; R! ^  |. y原论文可以实现发丝级效果
    4 l# x; K: E4 q  h6 `- g
    % p$ w' O' b& X7 Q4 G2 r" X7 v7 T( L- ?: l# g1 w1 W
    0 S# P0 r# s+ Q+ Z" o  V

    ' E. B4 t# x0 e9 k2 B1 k+ F! |7 R- n* R
    报错解决方案5 F" ]  r, X8 q5 J$ ]/ A! O
    can’t divided by 4 / can’t divided by 16
    0 @$ m! a; D6 ?) _+ H+ W' P- i由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。, m% ^6 H* y# y" X
    这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize
    " C, r. E& d$ x4 i, T; {————————————————7 \6 ~" v" B. h% ]6 K
    版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。/ _7 E: I  I( |: \0 N/ G
    原文链接:https://blog.csdn.net/weixin_43850253/article/details/126376767. J$ o$ w# V; o0 |; K- O0 c9 T) D

    0 U4 n, R0 f' N% w
    " M: W% r  }$ q0 J
    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-10 17:05 , Processed in 0.363604 second(s), 51 queries .

    回顶部