QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2145|回复: 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将红底证件照转成蓝底' w5 w  |3 F! F. l6 s
    前言
    0 S- _  x7 [# g7 memmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。% d9 v7 J5 R& m$ b
    , w& Q. \  P+ |9 a- Y! F

    1 D4 s( N* ]6 L5 r9 n0 J. m' `. x$ A9 j+ y" d6 U

    . B5 j" g) w4 x: E- n方法一: lableme+ w$ N& I+ G6 k; i- p& ^
    lableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.6 @! w; E; H9 u8 C3 ^5 X

    9 Q1 T; b0 S; M# 代码来自 https://blog.csdn.net/hello_dear_you/article/details/120130155
    4 T: b, \2 [- ]' x' C% ximport json
    ; Y3 X" r1 {# A$ m! Uimport numpy as np5 W6 g5 t! g/ Z) h/ z
    import cv2
    5 ]4 G- U  r. o+ P; g# read json file3 t5 b  S# x  U# u5 O, ?# ^$ D) b
    with open("origin_json/mypic.json", "r") as f:
    ! P, m- g' `! }1 t: v- K& w    data = f.read()! N- e1 M& f3 t8 U

    # O; b2 ~3 k- u% \$ u# convert str to json objs) y7 ~  @$ f  Q& u% g# b/ u
    data = json.loads(data)0 g- ?3 V+ p5 k2 J) n& V2 P
    3 Y1 j& T8 l' X. S7 k
    # get the points , X8 U8 k( c# o' L2 n
    points = data["shapes"][0]["points"]3 Z8 Z" k6 J9 m9 d& `  H
    points = np.array(points, dtype=np.int32)   # tips: points location must be int32
    ) ?0 H, ~( K; {6 N
    ; L' M9 X) p% Q# read image to get shape/ M7 E# d9 M  U" K: T4 G
    image = cv2.imread("origin_png/person.jpg")
    8 r# {1 b: U/ U, ~' b' n3 H5 v5 U, ?. R: w8 L7 T! e
    # create a blank image& m* w: H* ~. D
    mask = np.zeros_like(image, dtype=np.uint8)
    3 G# {! M0 V9 i$ g
    4 Y. n5 t5 Z5 {+ Y! v6 c# fill the contour with 2559 }3 j; G6 Z; v
    cv2.fillPoly(mask, [points], (255, 255, 255))
    ; E! H* _' w2 P+ q3 I) `0 Y5 Y  k& U6 G& h. t% {3 z
    # save the mask $ [, F$ f  a' c# w+ }
    cv2.imwrite("mask/person_mask.png", mask)8 R1 @, M/ W: k" A" ?
    1
    ' l/ E$ B4 e. q0 b+ u6 y2
    % U5 _# n* L/ d% \. f; ]3
    ( y5 f$ E4 a, W- U4+ K* z4 \3 j' ]2 a% ]
    5- z; g/ D, H. N+ s7 f% f
    6
    . z9 P! x2 h/ r# ^  g! S71 ~9 n% l4 X8 R4 O9 K" F+ R  M- H
    8
    & N% }" {  q4 k1 H( L. X9
    6 o$ K1 P8 S6 K' [10
    - x' B; f  C% n+ A, `0 F11
    0 ?; s6 ]8 R, @" t12
    8 k$ t7 k  ^+ U% j13
    & S( ]4 w8 I" X8 {% m; @/ k+ f8 h14
    ; S% o1 w2 O4 i" j, {5 R! S15
    + k+ [, W2 \* i* Q7 e" t16
    ' O/ i; [5 `4 J+ H) @17
    8 Y) A: ?3 o8 f& `7 p18
    $ H+ J/ ^2 m8 e; P2 I  Y19' Q# i8 N- f  Z1 Q( F" \( o: x! C
    20$ m  {7 A# }& {' ]7 n: O; X
    21
    - F1 Y. z( Y: @. y( O: m, J5 z22( V9 w. ?3 {8 h/ o
    23
    9 i  L" K2 o. A0 e' g) W$ J7 k24/ ~0 k4 Y  ]" _- E& A7 d  l
    25. |* f7 b2 t8 O% w. `
    269 Y3 b; a& I" M& g6 P% O' g5 |
    大概是这样:1 m. {+ S4 w" }1 Z  E

    8 M' c& C% k& Q$ V' j: l4 n, e6 A, l  M2 O6 L* P- S2 A
    然后利用这个mask生成图片& N: ~; e5 j& \6 z) \
    / V) _$ W# C6 T% e  c  ?* |$ p
    # 参考自: https://www.jianshu.com/p/1961aa0c02ee9 Y/ {9 R6 J9 f# Z8 c, V7 Q
    import cv2( H! a9 [  l8 m1 Q6 A8 B! u+ Q
    import numpy as np6 T$ H$ o& w: l: y

    # H5 y2 _6 u5 D' u7 [0 R- B. A: N* q- |: p) [. s/ \
    origin_png = 'origin_png/person.jpg'+ z* v5 K% |: E1 P
    # maskPath = 'mask/person_mask.png'
    7 p# r  {' O* _+ a% D3 O3 omaskPath = 'mask/bmv2.png'( b' |3 ^& ?5 Z$ f  d
    result_png = 'result_png/result_png.png'  v: y% x2 t8 w/ {5 c9 ^

    * W& v/ v8 R, C  \' @. `/ \' v! r3 U& [( _
    maskImg = cv2.imread(maskPath)
      r1 o) l: A& ~' simg = cv2.imread(origin_png)
    ( M$ A1 i% E# y) ^7 f% ^  [assert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'
    ' {5 S% X; G9 u. a9 q) w3 P
    + {3 q$ S4 m3 ^! g* fh, w = img.shape[0], img.shape[1]
    4 ~/ p/ \! l/ N: {9 bprint('图片宽度: {}, 高度: {}'.format(h, w))
    2 D& f1 B5 U# X  _" F# Q' [. _/ P0 H' V2 `
    rgb = (19,122,171)
    + e' ~9 M3 V; z% D6 pbgr = (rgb[2], rgb[1], rgb[0])
      [; W4 }1 g  G" _7 y+ N7 \# (B, G, R)+ z1 ~" H4 p$ Y  _
    for i in range(h):
    4 z/ t$ i9 j* l% R. k/ O; f    for j in range(w):
    ( _# s6 o% i/ ~9 S        if (maskImg[i, j] == 0).all():+ `2 E. ?) A+ S5 c6 N3 k
                img[i, j] = bgr
    2 Y+ P% t9 @: k; T' Rcv2.imwrite(result_png, img)
    % f  @. w2 z7 [+ Dprint('图片写入 {} 成功'.format(result_png))6 Y# T+ [2 m- X9 Q* {' U1 k( M
    1
    7 j# b) e# E) T9 n1 T2
    1 s/ m2 N' O/ T3& E  o  P, x% e5 c2 U0 V8 l: e
    4
    ! u8 n9 h# U8 f5
      w' p; U- t- n( X. c' E# j) h! h6
    5 A) y% H% M! z3 W- [- u0 C: E7 `77 a- R/ }# H2 S
    8
    7 J. a1 Y+ ]; G6 e# @99 y& T$ S- \6 s+ i4 y2 e$ y
    106 C) h# M9 i8 i) P) C* Y
    11
    6 W) y+ @; p% U6 U  D! h* ^12; b  l' o+ r. F& R+ q! ?. {* A
    132 l. w0 F  P# P& N
    142 X  D7 {3 P9 y& I/ R8 _+ ~% D
    15) a& _" \( Q9 d
    167 B$ l* o* N% z, Y' a' u  K
    176 y/ F$ y2 E  @
    18
    * ]2 S' z, J- e8 m* C0 O( t19
    ! V+ e. Y& ]! T, h% S9 _/ g20+ k$ w0 d/ c6 z, C! ?" o' f/ t
    21! f5 |- n5 S8 d$ |+ B
    225 x8 _8 E# f4 I- C3 Y7 e
    23
    6 P9 A3 a6 b3 y9 w# p: M5 Z( l24
    7 |! r0 G. G" u" w& P  R25
    : U( |% W3 G* \+ g26$ v# l" L- R* n  b) u7 e
    27
    * B2 a+ y0 d. ?4 ~: [" {0 p由于人长得一般,就不放图了…2 v0 Q* k, J6 Y6 _- w
    ' U/ k0 ^" k/ M4 n
    缺点:
    8 r2 n! P5 p' T) X, f9 H* |* tlableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。# U! v0 y6 Q' K- |
    4 q0 v( i- k7 `7 n: l
    , a" T6 V9 v* h- q& a4 F
    % o/ V& `# B9 O0 U! L

    " X! C, E: [7 B/ B. D) ]6 _& O
    ' H( ]5 g1 L0 J3 N方法二: 阈值+ \& G! t, M7 U+ |/ D0 ^
    该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。
    ' N+ o; ]# e) V6 l! N' V8 x% b
    2 `) K' P4 L2 F. h8 POpencv* E0 E2 t3 j6 P  L. w* C/ j( i
    import cv2! y4 ~& |% x. ]$ o9 f8 {8 U% N1 [
    import numpy as np
    8 K* S9 ^) S! ?2 z6 o/ V+ @4 V5 t8 u( |) j

    ; u/ z! F* E: D* x, edef mean_square_loss(a_np, b_np):0 K* X( F4 h7 }) j- b" s) k
        sl = np.square(a_np - b_np)3 {$ I1 U1 D. @7 c+ m8 j
        return np.mean(sl)
    ) l" S- X4 }1 ^) A9 ~8 P
    $ z& b3 F* D( g, b
    0 V, |6 u( v, j7 ~4 ddef change_red2blue(origin_png, result_png):
    0 \# N1 [  q. D" q    img = cv2.imread(origin_png)
    ' J$ o1 B/ s6 _/ ?+ I! j/ ~9 w& J  ~* R+ @8 }2 [
        h, w = img.shape[0], img.shape[1]* U+ e) s0 O' S6 ~7 v* H
        print('图片宽度: {}, 高度: {}'.format(h, w))+ f, k% _2 i0 \; ]
    % C) ~$ h, g3 c5 l- m, h( ?: q
        origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
    " @9 j9 H3 i. e( |% ~    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    3 E4 y! }6 b# k9 K    target_rgb = (19,122,171) # 蓝底RBG
    ( ?/ f/ u' h* S# b5 Y: ]    target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])$ ]2 @9 n! F& ^7 R: k# B4 `

    ) V' [: H5 Q& C3 P% D! y& |& [) a) t    for i in range(h):
    $ a6 `% Y; B) D/ }) v        for j in range(w):
    4 k) g9 Y! M& N& N( f            # (B, G, R)" Z; g% c7 u3 _
                if mean_square_loss(img[i, j], origin_bgr) < 50:. w& v. f1 H3 [7 S1 U1 f
                    img[i, j] = target_bgr
    ; Z0 k! }/ B2 v" c8 h+ H0 a1 [8 N  E0 O/ Z# `- c
        cv2.imwrite(result_png, img)' v. O# y7 {5 V( a" p
        print('图片写入 {} 成功'.format(result_png))1 g$ h1 N" \4 k/ g$ c& L) h9 W

    , ^7 N  q% z7 E- M; C( I4 I4 M# O' S7 X' J$ b
    if __name__ == '__main__':! a0 S7 d8 i  c3 W. D" Y* N
        # origin_png = 'result_png/result_png.png'" {4 L3 s; t) T1 {
        origin_png = 'origin_png/person.jpg'
    5 f; {5 j- ]& b    result_png = 'result_png/result_refine.png'
    * n: D# }( K) g    change_red2blue(origin_png, result_png)* Z$ d  [; N" _6 [  ]4 C( f0 a
    1
    * a. _1 q) R2 I) ]8 k' q+ Q8 r2
    / ?; Z* ?! S3 l) @4 C7 \* P3
    . U# H9 n! h3 ^8 P4
    1 ]/ Q5 P1 K; ]0 _5 k2 ^5# V0 R! q, T% o1 _
    6
    6 f. Y. r1 x- i0 i7
    7 e3 T: Z: N; ~& g! t88 r. t4 F; s3 U8 ?& D
    9
    ; Q$ n- @. M2 P) H) p  x3 {/ W10
    7 j) |4 t/ a, m; N4 K. k/ O11% d; J: i( L" Y5 R- `
    12
    ; u$ e7 l" ~" d4 ?. a4 r: j13- N9 ]2 W( w. s
    14
    ' \" k5 |3 c5 k& j) Z8 K% {15/ P! j' j+ [% p$ D" S6 ~% A! z' |
    16* x& g* A8 h" k: c& @
    17
      ]+ X( j$ `7 u, U& m+ |2 ?. U18% g6 c" \4 y1 q
    191 j" {% K- V7 y+ B' }5 D# q# Y
    20( k: A8 i+ c- H3 `, F% l
    21
    4 p* ?) r% d; x, o22
    + c3 v' g& ~; l- e5 D6 O23" [5 `3 a; ^+ m. t
    24; b( H7 V) r! R* i7 ?1 B
    25% @+ o: U6 g9 g/ V2 |1 h
    26
    + K9 Q- J" ^  ?9 A3 D0 W27
    6 }( ~! h7 b; N: Q. Y8 a28
    6 o2 L3 D- H) W" h3 U4 O# n298 e4 W7 v  j: C
    30- S- r7 \( k7 \4 _
    31
    9 @7 Z; o8 b, r; I: [8 k32
    / U' e5 G( _  r33
    9 V+ ^: K/ y8 z" w( J6 Z4 S% A34
    4 n8 T& ~1 X: ~# x; L" S35
    2 x+ V  H8 N. q! \/ Y! i; z结果人与背景边缘仍会存在红色像素残留0 f2 m+ M+ N; o& @+ R, b
    / l- P) [6 U, Z* \4 q( a8 ]$ p, b

    / s7 Q! v# I0 l3 n
    0 |2 T3 x" ?  L9 x3 J/ n0 p) F
    $ d' u2 @4 }. T6 ?: u% i9 J( _1 Z6 |5 K8 B
    PIL& t4 S+ c/ @2 G! q2 f
    from torchvision.transforms.functional import to_tensor, to_pil_image8 x7 @4 f1 n( ^" l
    from PIL import Image  q' b  |9 T1 _9 ^, |
    import torch
    . h+ s! L- \! x$ Y5 ~import time- m/ {4 z: j1 F$ Y

    9 a+ H. q, h  l+ N( s4 P; G8 A% _9 i* y* E" z. |' k& N( ~" p
    def mean_square_loss(a_ts, b_ts):$ |0 L7 R) z% n7 D
        # print(a_ts.shape)
    6 D) z" O. T6 {/ L    # print(b_ts)- O8 @9 P4 E) _& d
        sl = (a_ts - b_ts) ** 2
    8 e1 Y+ b6 S% s" N4 L. k, r& D    return sl.sum()
      R) c% O) N1 C9 `' ]  U: n) ]8 ^0 @
    , ?9 _) G" N6 C5 ~8 r: s8 ~0 K) X, Q
    def change_red2blue(origin_png, result_png):
    1 T' Z/ W4 t- r4 E    src = Image.open(origin_png)
    4 M' s* l) k* A% V: ]9 p' S" F    src = to_tensor(src)
    : X* j7 t6 ~+ x6 U/ [+ o    # print(src.shape)  # torch.Size([3, 800, 600])* z0 g7 _  N  D2 t! V9 {/ r; S2 A
        # channel: (R, G, B) / 255% n$ M' i  R' w; V* }# k' E
        h, w = src.shape[1], src.shape[2]5 J4 R4 V( y; a4 u
    ' C5 I$ P: ?  |1 S; ?0 q
        pha = torch.ones(h, w, 3)
    6 n- n5 ~$ l+ h- ^- L5 \0 l! ^0 l9 @
    : o" A. ~$ f' V) d+ ^# j    bg = torch.tensor([168,36,32]) / 255
    2 S6 J: p. l5 u3 n! `    target_bg = torch.tensor([19,122,171]) / 255
    , b$ r8 ~% i: `( R4 H
    ' ~4 e- [' Z5 p0 P% Q. e* L    # C, H, W -> H, W, C
    0 i. Z- D3 b% Z$ G& T4 ~/ Z    src = src.permute(1, 2, 0)+ I+ i0 p' B3 R6 s& E% U
        for i in range(h):
    - v. q+ S9 }% e; r) C        for j in range(w):  S% d6 X7 y% W) O) `4 s
                if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数( L) a& A/ e! W3 r9 U5 x; [5 c% `
                    pha[j] = torch.tensor([0.0, 0.0, 0.0])
    8 a5 \: o* N4 ^8 a% r, y3 D, R
    / V! X5 a& R1 k% U3 G; D/ F6 g    # H, W, C -> C, H, W4 l% e1 E" J4 I! A5 D, p: k
        src = src.permute(2, 0, 1)  m/ L9 N3 `9 c0 s1 V) V$ f2 d7 i& W
        pha = pha.permute(2, 0, 1)
    " z; M( @# ?" L; `4 R" D    com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)1 X% p/ `+ k. ?( h. |. S
        to_pil_image(com).save(result_png)
    : E# i5 y/ o4 ?/ w3 j6 A9 A3 B2 f& ?  r' n6 Z+ l+ c6 I
    9 i' Y+ A$ r3 m! Y/ `3 Y
    if __name__ == '__main__':  [$ X/ ]: k/ t' B- H  e# c
        origin_png = 'origin_png/person.jpg'. L- w; e) K3 h& M% p
        result_png = 'result_png/com.png', ]& H$ @( }0 o7 X: G
        start_time = time.time()5 t5 G+ ^8 \% F1 c% r9 E2 {# e
        change_red2blue(origin_png, result_png)
    $ x6 c# \3 x& ^- W+ e. i    spend_time = round(time.time() - start_time, 2)1 [! [$ \: k& ~; i) L, m
        print('生成成功,共花了 {} 秒'.format(spend_time))( `9 U& D  Q" T; D- D/ R* `" D
    1
    . Q* [" m/ H/ c6 |8 ]6 D2
    7 h1 H( A# n$ z$ r, M3
    1 U7 l( c3 e. P4
    6 a4 _+ m$ p& y" ^( r3 r- B+ I5
    + h: d# `1 a, |6
    ! d( f; {) c$ O$ O9 O( D7
    , w& [& W) s& Y: m* }8
    , c4 \) {+ {2 E6 ]9; n) s1 I" k5 T) J
    108 F; J4 ^; Y9 F2 w& p
    114 ^5 y' l$ X' p! \  q  O
    12
    $ S( y+ S& g, R+ c2 T13
    ' T8 T, C! }, C14* c$ R8 L1 I* r' i. g) D4 F
    15
    / a% O" v' D$ @! _* w16
    . K/ S/ ^, z/ t  R( ^4 Y178 d$ S/ `5 E# g9 F) G3 b; j, t
    18# O: @( j4 S. s2 j, z- }1 H
    19
    . M. v; x4 ~8 F6 a, l7 k207 B% e) i: V& I- n2 H" V4 Q
    21
    ; J) R) C! b  u# x. x2 r- ?22
    8 H( E9 j/ @5 Z* o: S/ w6 }4 f$ t23
    . B. [3 m2 r& p0 n* \; [) L$ u24. v0 F3 v3 s1 ~& i5 M
    25
    1 b5 F# F& n3 `' v& B% A* O264 U' o0 F8 `8 |+ m+ }) b
    27
    # c- M9 p5 L: k8 w, p) A28
    " r- }+ Y' h6 H296 z  U; R1 J* W6 O) H) `9 |% g( ]
    308 t, U: F+ t! k& c2 W
    31( _5 `) U6 ^' [7 ]4 W8 ?
    325 _0 }+ l* \$ D! ^- j
    33
    * j3 V* W6 ^& k1 B8 A34' @* O8 z+ ]7 V2 A6 H+ I& B
    35- o* p6 V# e; |/ x
    36
    ; {' p6 \0 f; v! ^% @: r37
      p" U) f. [! d3 u3 W% T: N7 |- K& M+ T# m38( |2 O6 z3 v$ y& j3 E
    39/ X) |  c0 p$ M5 z# g; T$ p2 _
    40
    ' `3 D9 `/ a( }* ?0 Y! l" n41
    , y  U" x4 u  j$ ]$ h. q9 P. u42
    $ Q4 M; Z+ F2 _) o43. P8 C4 }. T2 _5 O8 \
    44- C; h0 p  g3 f- A2 w, l
    45$ X; D$ u0 T4 `) M; h* j
    46
    ; Y9 z# c% @5 |6 d4 B! T& l  j该方法质量较好,但一张图片大概需要12秒。! R3 o: G8 [4 Q! s; C

    ( \# ^2 m5 ^" g5 `. c, {# M( {2 N+ l! T3 ^( B, x, l

    3 O" c0 b6 U& v  d' w+ P; l! i% C方法四: Background MattingV21 p  e' C% K% U$ V# e5 u) L
    Real-Time High-Resolution Background Matting
    & Z& S9 n, D: K" QCVPR 2021 oral) G$ L' r: m- \' i  ^5 W

    ; i5 m# Q2 R: ~- L; J+ `+ h$ j论文:https://arxiv.org/abs/2012.078103 R" d! [# \! D3 {
    代码:https://github.com/PeterL1n/BackgroundMattingV2
      c+ o: P0 {3 C% f; y  e
    & U  J8 |/ k2 _! z0 Ggithub的readme.md有inference的colab链接,可以用那个跑; s  e# c- W+ I. Z  l5 `5 k
    . i" B: s/ L; M' N1 S8 y8 @
    由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。
    ! H& h4 b6 q- A6 g
    1 [5 b0 U) E  j于是这里我需要生成一个背景图片。0 F# C1 n8 L8 D* h) O' Z
    首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。
    7 I3 n8 P( C( t" [9 T; i& m) J# q
    9 d4 ^& T$ w0 \- ]* J3 K" r然后生成一个背景图片。
    : O8 ?; A% c1 @& Z# o
    ( e* m2 M  x% Y( D2 fimport cv2
    1 K& \  y+ W0 G; Z3 V: f8 s/ aimport numpy as np
    8 ], \( A3 }8 i) X9 A& e  y. D. K/ D
    ! g0 N# t! o4 {' t; E
    image = cv2.imread("origin_png/person.jpg")
    ( M& o( Z! ~  x1 [) r; Uorigin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值$ @" [" E* Z4 p7 a- X
    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    ' }; ^8 h  D3 ^2 o0 _. o9 x- f" Kimage[:, :] = origin_bgr8 {: }, K. L2 D% p* ~, z
    , ?7 e  I2 _: y0 t& j
    cv2.imwrite("mask/bg.png", image)7 O: o2 s# O/ P+ w4 L* i
    1
    2 ]& t- q2 M# C$ `, p6 ]$ ]' D2
      E8 O, v7 T) k3  \, {6 p5 S" E& ]( P% C
    4* ^8 R0 K5 }7 U+ w5 b; J' m
    5' E9 ~6 r4 ^* n3 V
    6
    4 Y9 q$ g4 p& v, y; Q# Q- M8 \7
    ; T$ e/ T3 T+ P4 h  H& o# c3 H8% ^6 J5 {* {7 O1 Y4 x
    98 E3 [' J) r- e  j7 g
    10, `2 x+ j) R. l4 S4 U" t! d" P1 K
    ) l) Q  d. A1 U% o6 x1 j7 X7 r
    需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码
    - M* y$ u7 ]! Q4 q, d6 g- p  ?: [5 }4 C  @' W: m
    src = Image.open('src.png')
    ! Z6 X6 }0 ]3 D4 abgr = Image.open('bgr.png')/ N! t  w  d2 X  Q; t% B" ~
    1% }/ O1 |8 H) E
    2* j' s; T! n! x9 b  _
    另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)- I4 w8 q' m. |0 ?3 V# V

    " D8 A# M3 \. H' zcom = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)9 B5 K4 `" J! {" R# K8 r3 b
    1
    8 x3 D9 Y' J( ]. [0 d4 y* M2 [
    , O; }% g6 G% @5 s那么加入我要换白底(255, 255, 255),就是
    0 v8 Y9 S/ X8 x; ^7 T& J) J2 |) ~, W9 s, x. ^4 _+ u# g: E1 n! v
    com = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)- a0 N1 _8 H( e2 G+ e1 c2 P# ?& ~1 C
    1
    0 Q. z5 |" I8 i- W) B. a  o" e0 S) p" ]' a' u% f0 N
    假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是
    ; }& G. B2 Z; H; v0 z) H/ I# c5 M6 S& a5 o
    com = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)
    ' u7 I9 q* y; f. v8 Z. M1  K2 J" x2 H7 S' |: o
    总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.1 i" j2 n. T9 F( B( z

    2 d& x4 s4 ?; e然后就输出图片了。可以看到效果相当好。不愧是oral。/ s0 n/ a& f+ z& A. ?* c

    ( w0 q) ?! v) t9 P8 O  J+ f0 n+ O6 [
    原论文可以实现发丝级效果
      U5 Q+ |& j+ |& I! L
    ) j: _9 u) `, O
    8 E, r8 e# ~0 O2 E& I* I8 o. d8 I3 c1 N( {6 _
    6 q1 m" J& x- r2 X
    ; @/ F/ }: t$ w- I& ?* o$ e
    报错解决方案  r  [) U( T. j' [
    can’t divided by 4 / can’t divided by 16* p! _* c( ]# D5 N% h3 z4 H+ u
    由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。; i% A5 R2 g4 R4 ?9 j/ a
    这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize' `/ H# u6 b7 k" Q3 P% i# P
    ————————————————( ]+ _- T! X8 @! V! p
    版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。/ u3 r8 r0 }" D$ R8 ?$ @$ z' I
    原文链接:https://blog.csdn.net/weixin_43850253/article/details/126376767
    , a5 R* q% M& d! \. ~/ Z
    4 w& P7 n2 U2 D. Y) T7 L8 R3 p! W5 e2 h2 u: g/ z/ ~% ]
    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-9-13 19:21 , Processed in 1.284479 second(s), 51 queries .

    回顶部