QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2165|回复: 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将红底证件照转成蓝底
    & u6 \7 u$ u, }3 `1 q前言+ [" z$ _5 u# M5 C8 [$ n
    emmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。4 R; F: b& V, e6 \2 y: |6 I

    8 M6 f, E: J  @+ R# w
    5 a' U; n' p2 M2 S2 ^* O0 ?+ U, I7 R& j; B! |
    / V# C( z+ E2 h6 s; P4 G+ c
    方法一: lableme
    7 a3 L" C& C) F" g  i, Ilableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.9 z7 i  J! O) F4 Z; M

    & [* i" e8 @/ T- F7 |" N+ y' W# 代码来自 https://blog.csdn.net/hello_dear_you/article/details/120130155: S  d# i6 _- O% f4 Q0 n3 Z
    import json: K, r0 a. e. z
    import numpy as np) O2 r" F- ~( G* z1 J6 V: |% ?9 @
    import cv2" j0 W- H- [4 U* D
    # read json file
    % Y' w$ D" \, E( Zwith open("origin_json/mypic.json", "r") as f:9 n9 z9 R3 [9 }* h! k, C
        data = f.read()
    % A* C# n$ N+ x) I
    8 E5 l' z+ f; r# convert str to json objs
    , g, D3 _: \8 P! d! J* idata = json.loads(data)* T/ Q. B5 A% E+ X6 P

    3 I( T8 _, b. {" m% ?# get the points
    6 S# j1 {6 N; n3 s  F( w; L, V$ o% G$ `- Upoints = data["shapes"][0]["points"]
    ! V, Z# ?  v; Y- s4 e9 H* e; Q: spoints = np.array(points, dtype=np.int32)   # tips: points location must be int32
    2 f1 X3 ^$ H- T: ?6 q% X$ V0 b# L4 K5 \! F3 J
    # read image to get shape
    - l- ]9 |6 |; n' K  F8 K$ i  Dimage = cv2.imread("origin_png/person.jpg")9 s1 E( i! a% L8 `2 [

    8 M3 x1 G5 l# \- h# create a blank image
    6 y% K4 x5 t& W3 k6 j9 {mask = np.zeros_like(image, dtype=np.uint8)
    0 Y; X9 @! `& h; q: O1 ]/ P$ C! R; S) y9 N4 g, \$ k2 b
    # fill the contour with 255" j1 @+ {! u% |: W& ]/ q$ T6 \
    cv2.fillPoly(mask, [points], (255, 255, 255))6 k0 t. K/ p- Z& q$ G; ?
    : ~5 \* h  l! x( E4 ]% N5 t
    # save the mask
    * C  A) h! X2 R3 i% \) jcv2.imwrite("mask/person_mask.png", mask)
    6 `0 n( [" {3 M1* x! Y7 M! r3 Q' W  g6 ^
    2( h) p1 `, f1 y+ e" M
    3! G9 l- p! D! i8 R
    4
    ' U4 M, J/ Q( `" W6 ]; S; H5. a9 u7 G* D9 @
    6# Z/ F* G- e! n6 v# j  p6 N
    7' J$ W/ i1 H1 q
    8
    4 q9 K; e. X( v; |- x6 K; D2 y( F98 |, f9 u% [5 V( b
    106 R9 Q8 r# A' o3 q/ C, G6 X
    11: X* W  H3 N: R; B2 T6 a  W. O
    12
    % l; U- @- {* e6 W5 i. {1 m134 m* y1 X6 D5 q8 y& Q
    14
    % h6 v' T' V0 O15# g  B% W: G8 c: i
    16" L- ^3 T5 v4 N
    17
    4 H1 e. e* n# g: L+ M0 w0 _( C1 F18
    6 h) ]* p- j* ?# S* I+ w19
    : |1 v  l5 Y+ a3 h; \& V# v204 O: S$ e, i0 n2 ~1 D9 v
    21/ a. ^8 i% O! L3 E3 J7 \$ N
    22$ D" Q6 y' j' i9 p
    23
    * H) W6 i  h! A24
    , y  J% H/ B3 n4 v9 b* g* A25* s, t1 h8 o  L, P8 `, _
    26# l6 ]% Q( G, N' f$ p9 T6 V
    大概是这样:
    ' d. `4 V$ _  G$ N! h( b# X. Q! x$ b$ f- p: [1 Y: Y
    9 J0 J$ S* @4 }' j7 o, v) G( C4 V
    然后利用这个mask生成图片
    $ H% }; Q$ I9 o7 z: {
    9 _+ t: n2 u3 }/ L2 k# 参考自: https://www.jianshu.com/p/1961aa0c02ee
    2 ^1 b& Z' m3 M8 s+ z" T& R" mimport cv26 @* r6 y( d# L  w. L4 I
    import numpy as np
    , _3 s; X( B! [! s% z1 v
    : {: `' g8 e: y! o: @8 s# I7 Q. |( `/ Q& t; D6 o& W! {* T3 @
    origin_png = 'origin_png/person.jpg'
    . r2 y1 F2 s0 x. d0 H$ t! `# maskPath = 'mask/person_mask.png'( C+ ^% c8 s0 Y
    maskPath = 'mask/bmv2.png'3 |" T( t: p7 z5 ^, ?0 O: j  A
    result_png = 'result_png/result_png.png'
    ( i) X1 Q4 z+ |2 k" j2 Z3 J; h' n9 @4 w
    : L5 w# Y  z0 ~$ `5 w( Q  f: ?
    maskImg = cv2.imread(maskPath)
    / U( x/ q; D0 W  [% Mimg = cv2.imread(origin_png)
    + z' c- D2 W# Q5 {7 kassert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'
    ) ~1 M" p* |4 R/ C& T$ r# @" P# ^
    , K2 Y1 H4 ^( @! x% R! ph, w = img.shape[0], img.shape[1]) [% q. E: a4 y- r" |
    print('图片宽度: {}, 高度: {}'.format(h, w))' n  e9 O: n( B' l
    3 p+ X: X6 }0 H* @9 i
    rgb = (19,122,171)+ a& `1 O1 u0 ]6 k( K% ^, v
    bgr = (rgb[2], rgb[1], rgb[0]), ]4 Q& a) q- _$ F. ^
    # (B, G, R), x4 |0 X1 j6 E3 E5 x! L6 G/ L
    for i in range(h):/ e1 j% r# n* E' L
        for j in range(w):! c( ?, |, m4 H$ a1 X3 ?2 b# _
            if (maskImg[i, j] == 0).all():4 Y$ y* v% Q! m  b
                img[i, j] = bgr
      A* I2 W! B, ~0 N1 Fcv2.imwrite(result_png, img)# B5 B9 s) l) t  @3 J
    print('图片写入 {} 成功'.format(result_png))) B( p' O3 m. t8 |
    1
    5 _, M% L0 B6 c6 x& T% g( P2* E" D8 V; N" t7 B- B. p/ k7 ^
    3" d* X, @/ U/ }& `( Y
    4
    & f7 O7 z8 r3 t4 m" Y7 S5
    / J. Y6 e. n6 G: k  {! B5 a- d) [6 Z/ r. D6
    $ H7 S' j% C' Y/ T7. L, y: R" N% }4 f
    8% Z! e( ^4 G& o' w& \8 K7 R+ Q( n
    9' Y, {0 H, y8 x+ |2 Q# `" ^3 G* [
    10
    ( n5 K+ }( ~5 ~! w, l$ h9 M( U11% X) E' t* C1 J# [
    129 Q+ u" d8 ~3 d3 w( u
    13
    7 r$ M/ x: \2 O8 ^  f" E$ `; C6 G14
    7 W/ U$ C" p% |) r0 L* s& ~5 X* C: U15
    : A+ Y6 I) E) U% {7 H16
    " ^6 H, P" K5 t17
    / R1 z' ~/ [% s# K18
    & N% x  m( j1 }19
    0 z) n  h& [. h; E+ ^& _; v# y20; p' C' N7 u7 Z2 m8 G
    21. m. v( R% ]% U) A- U
    226 h: }+ i9 I# w7 k0 S
    23
    5 J" i! J6 S3 o1 h  X24; \& m3 X; J6 T0 K
    25* o8 I* G( {, A, Z; b
    26) V& W7 w8 Z% Z* ~( ~
    27( G( B8 A6 q" C& ^
    由于人长得一般,就不放图了…1 M* h8 \. {- E3 X4 g, q

    ( Q2 L0 b3 [5 J) u2 Z' ^缺点:5 I9 _6 ?; f, @; K( X. `" Y. ~
    lableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。
    8 m5 y& ~- d( \7 N2 c& j5 `: E' G1 _/ e( d( x+ M9 Z6 N

    " y& n6 ?+ x4 Y4 {! s/ W$ |' Z) \0 f  p1 ]$ ^0 {

    . T$ J9 L" B5 Q" k9 `7 j  l1 g: V( y) a1 H2 S- p
    方法二: 阈值
      a" r/ B6 A: X2 T6 Z/ P该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。
    7 d9 a6 I4 l' Y/ H2 h$ X( J1 J# Z! {$ l6 h
    Opencv
    " x/ l6 O# ~, S- _8 Zimport cv22 ^! u7 B( U- r/ D9 d$ R1 ?6 |
    import numpy as np
    & ^4 X1 b  z) f, B, p1 M  k. a' L& C6 W5 B3 n' V, W+ g$ I

    9 z! t1 t1 d1 J/ K1 m$ D2 I. Wdef mean_square_loss(a_np, b_np):8 N7 f; Y* `/ U% Y5 x- ?$ D5 Q
        sl = np.square(a_np - b_np)
    / [9 t8 F( s: x. O    return np.mean(sl)
    , `, f8 o+ }* ~; A  w+ ^1 w6 W! A" o' s

    5 d; z3 s& D& ldef change_red2blue(origin_png, result_png):+ w$ j# i) {6 l, N, d
        img = cv2.imread(origin_png)6 j1 Y2 g' {9 I& _( ^* W  S4 d4 Y! J
    ( O+ |% l" q8 v1 \  ^/ M, L5 S& I
        h, w = img.shape[0], img.shape[1]& `! G; {! V' t* f
        print('图片宽度: {}, 高度: {}'.format(h, w))0 f1 F$ i1 V. n, o1 G# l; t

    , g3 C7 \/ {3 W& R( _    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值  q' r% e+ W! k, D0 |
        origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
      s& W) g6 A! a" `    target_rgb = (19,122,171) # 蓝底RBG
    3 w: Z% T0 o: K9 \2 y    target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])
    1 d# u. y+ E) ~$ r8 l, Z2 m/ ?9 M1 u/ D
        for i in range(h):
    * d% a+ U' v* {6 G  P/ ~  A        for j in range(w):
    + L6 I# g' S8 b% i7 z& }            # (B, G, R)
    ' g3 Z% P8 E# `; o6 Y6 A            if mean_square_loss(img[i, j], origin_bgr) < 50:4 {# |- D& q8 ^; F5 q, M& h
                    img[i, j] = target_bgr
    ' C( d/ \4 r( N" d, J  e7 S  f2 ?7 R# Y4 C3 ]' U/ ~4 d$ l6 ^
        cv2.imwrite(result_png, img)
    0 q( z3 T  G" J    print('图片写入 {} 成功'.format(result_png))
    % H: N* d3 R8 S
    $ y9 B) E  c/ {+ e/ o( Y) E0 R3 S( t( x. q2 G! W3 M2 s
    if __name__ == '__main__':
    $ Q6 V. g+ I  B* C1 V7 V    # origin_png = 'result_png/result_png.png'' t" ]% a( k# `- @+ @
        origin_png = 'origin_png/person.jpg'
    1 K; M  W8 g3 m1 ?9 d/ H6 a" C    result_png = 'result_png/result_refine.png'
    % R: J/ [/ J. @' r: V    change_red2blue(origin_png, result_png)
    8 Z8 @1 m' _. D- o1
    % t: ]0 X. C; p* a- S2
    ' D: J* W; H) A5 ]& N2 G3
    1 Y! j: |. |% b' q) S4 ^4
    2 c0 W" e. M2 j" I5
    4 j" j* r; e$ h% P/ K& I6% D' P* N, x* n6 k2 R- c
    7
    ) v. e5 D. ^9 p; b8
    ( u4 v1 [4 Y1 m: m* ^5 Q: j% C9
    , w% \- Z4 v' I7 @! h9 d10
    * J! X1 X! I" Y! k3 W3 e( B11
    & A" |$ g5 y9 U1 ~12
    % A$ d" E, G! S: y' y13
    # z- T% D+ r+ v& M14
    7 {$ z+ H& e/ l0 g8 X15
    $ n7 r( f1 k' _7 B0 V160 |2 ~; Z) x+ k" [
    17
    ' a9 P$ ?9 g$ p183 `0 R/ K; X1 `9 b0 P9 W, |! F
    19
    1 s$ {, U( s2 x20
    ! L2 Y2 _- {6 a. y219 n$ W. l/ ?: B- n& `. V
    22
    3 U9 a4 m- `) T235 b: _' P$ H$ ^- U0 ~
    24' E/ V9 s! s/ o! [! [
    25
    4 M6 b8 V: I9 g5 R  |+ ~  o$ @$ {$ X26
    $ F8 S* m8 h% K$ A& i; {27
    0 g3 l: X; E% P28* R& e: S% h1 ?* T
    29
    , }& R0 E+ e0 j( x  g. x30
    * m5 Q% f! U: x: `7 Q8 [7 A31" j6 s2 @. b  Z1 @  v3 s
    32
    # ?) m; ^! O4 [; f( ~33
    + o8 }4 g$ T! D- L8 q7 p, p2 b34: o  }1 X( p' H8 d6 x. ?
    35
    6 w7 ?2 }& D, L/ D结果人与背景边缘仍会存在红色像素残留
    8 m& l3 {$ |4 _, m2 B) u
    " t6 Q9 E3 W$ \9 g- l7 ]* w
    9 Z1 D- Q$ o8 v1 q7 @0 R( I9 Q7 b4 p2 A$ n2 @0 S$ I

    % C: \2 L& O1 H( o$ \# h' M. U  O! G& {7 {/ ?0 @9 n
    PIL
    : K, ^* Q: n; f  Q" Y  u: a+ afrom torchvision.transforms.functional import to_tensor, to_pil_image
    ! {0 ?5 Q0 v0 w& F0 ffrom PIL import Image
    ' x3 B2 l& }, ~3 x  Jimport torch
    3 O5 M. C7 c$ e# uimport time
    ; K8 e0 {/ Q/ }: ~: [- }9 k0 R. Q, E6 \2 Y( Z

    ! l) u2 ]6 Y8 b3 t4 Y* bdef mean_square_loss(a_ts, b_ts):
    ! {' o- \  u  j    # print(a_ts.shape)
    ! f8 O0 B7 \9 f1 F7 g    # print(b_ts)
    ( p4 }5 n! i4 Z- d4 N1 z5 `    sl = (a_ts - b_ts) ** 27 ]8 r$ d0 [- R' F7 D" m% v
        return sl.sum()- M) A5 \* l9 k; B, w" `
    0 T: p: {3 h6 P2 ^: M. z. m

    5 C/ `( t$ b% w& J  s: mdef change_red2blue(origin_png, result_png):
    : g" v3 G5 y3 o    src = Image.open(origin_png)
    . ]0 s* ^) U6 V1 _, R& v' W& d3 C    src = to_tensor(src)
    % f# _: J+ V3 T7 z* A8 Z    # print(src.shape)  # torch.Size([3, 800, 600])- k" H2 d! e5 w7 F  X, N+ n: k
        # channel: (R, G, B) / 255
    , C: G/ B* e9 X+ t- B' o    h, w = src.shape[1], src.shape[2]
    7 o, n; a0 @4 U4 u1 l6 K0 I# c0 ?5 f) ]! O
        pha = torch.ones(h, w, 3)" b" Q3 b: D' |0 m

    " ~! |& b' m$ f    bg = torch.tensor([168,36,32]) / 255
    9 x% V5 i) ~6 J2 `* `# D  _    target_bg = torch.tensor([19,122,171]) / 255+ ^% ?% {# y; ]5 g
    7 u/ L( `) t. b7 l5 j
        # C, H, W -> H, W, C
    % O# K, t: P6 J- ~# h$ g) M- l    src = src.permute(1, 2, 0)
    ( S( t1 A5 {7 e' |% j- Z! }    for i in range(h):8 _, t6 ?9 @6 q5 i+ Q" H) g
            for j in range(w):
    5 y0 w0 }; R: j. A2 s            if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数
    3 C' c/ G! P8 A% k. K* i                pha[j] = torch.tensor([0.0, 0.0, 0.0])
    3 Q5 j( c7 ]9 L+ L/ {1 \# z5 V( X9 T. i' K
        # H, W, C -> C, H, W" @  S* N4 B3 l+ S8 g
        src = src.permute(2, 0, 1)
    ' c9 I$ r9 H0 n2 a- [  _    pha = pha.permute(2, 0, 1)
    + o0 C7 ?" `5 }# p    com = pha * src + (1 - pha) * target_bg.view(3, 1, 1); z3 q# p+ A* A
        to_pil_image(com).save(result_png)% R2 R. G% y4 [8 J: s* m& l
    4 R8 m- e  `$ Y5 t; l
    - q( H" _: Q# s( P! R3 u0 y
    if __name__ == '__main__':0 H: J. p# Y8 u' Z9 h
        origin_png = 'origin_png/person.jpg'
    " {+ u4 Z$ n2 D! {    result_png = 'result_png/com.png'( e5 T  K$ L# u% K2 z
        start_time = time.time()* y: U, f9 w7 U& n3 H' U! Q
        change_red2blue(origin_png, result_png)2 i8 h! n5 H* Q+ Z) c! y* b
        spend_time = round(time.time() - start_time, 2)& a- d$ o; n3 v8 J, D: ?7 c
        print('生成成功,共花了 {} 秒'.format(spend_time))) o% R0 V+ \1 U7 L! n: e& s! x
    1
    3 n9 z. w0 i" x/ u; b2
    1 L, G3 t& l' n3
    ) L, Q- v- {$ V# Y! z9 V* z4
    ( K4 F! \$ J  c1 ?& T7 k52 y1 z2 H3 e  b8 }
    6
    * }  ^+ T' v" e: k2 ]7
    6 x, Z2 R+ h1 j- b8
    ' X: J% j9 g3 S2 b9 e4 I" l96 g# z0 H# }0 f( q
    10
    % u. _/ ?. S2 {3 W2 d1 b3 Z11- y6 u5 C* f+ @5 R
    122 c. F  L2 A; R6 j3 C# D" `; z
    13$ P1 H1 b- ~- {
    14+ Z& K6 z/ Y. |$ K4 V0 E. Q
    15! P! R. {$ p) @5 I' `4 f: y
    16
    3 d3 @5 q/ }( r% ?1 l17  H2 _5 W. r% ?9 R
    18+ s, W- N5 J6 k8 x# A" Q
    19
    + H8 J% W$ c0 F/ J; ]/ D' X8 B* r4 }20, p& w8 F" @2 r
    213 W+ N$ X; q' t/ A) j8 M" r% r
    22
    6 ~! {: K3 N! i) x! x23* n' ~4 R$ C4 b( A) v0 V
    24
    # c7 h+ L9 p! `2 O25
    - N% A3 U" t( c; e$ {# @! {26
    4 l. ?! ^/ j' b# A/ K+ S270 R( U. l3 U8 G  B5 O
    28
    ' G9 L1 _# A# L) p- v29! Y9 R5 C8 y9 p  c1 F, y' _" x! h
    30
    ! a+ i, E+ A" g31
    / O- q" T! Z+ q" D* E32
    ! c$ H2 M; w) O33# R$ i, h! |* l, W# c4 S* }2 l, h
    34
    5 K: {2 C1 _7 o35
    7 C. V# T5 K2 k& j' s# X6 }) J36
    + s" Z" n4 c8 Z& c  L& r; f7 I370 j+ M7 [5 h# {
    38
    8 R* a1 O/ ^5 X! A2 m39
    : W) U* M; k0 ~5 ^: |& l408 o" N# t( A5 Q+ e, I$ J
    41# ~! m! |5 g# L% R0 {! k* F2 p9 L
    42
    # w5 H9 N; h7 Y2 W% L. T431 j0 V5 x/ q  O5 a8 ^6 ~
    44
    2 l# \% ^' s4 A9 w450 |4 c9 ~5 l3 E4 u
    46
    0 J# O$ y* J4 {! s8 b7 E- X该方法质量较好,但一张图片大概需要12秒。
    . _" W; s! u/ W: D6 W8 G1 ?0 V, h/ ^! E6 n9 o, s6 j

    # K; Z; i& Q& L1 ]6 T, z  g$ H7 @5 K4 F* L1 h. c# m# O
    方法四: Background MattingV21 f2 v1 A7 Z5 y  @" _0 c) `
    Real-Time High-Resolution Background Matting
    5 ]; T* W( p# YCVPR 2021 oral
    6 ?9 g) P5 k, g  z$ [5 ]# E2 i( a5 o1 a' [. c+ ?9 B. i
    论文:https://arxiv.org/abs/2012.07810
    & h. d$ g* q7 J; S代码:https://github.com/PeterL1n/BackgroundMattingV2
    : w! q. m- y0 c0 I9 n1 H& \) w' E* Y6 H9 `# O, G  w
    github的readme.md有inference的colab链接,可以用那个跑
    , l: ]6 s6 y9 }1 U* Z$ S+ {
    8 q4 P7 _# m) K! a由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。$ t7 B- z) G1 J- q3 a

    2 H9 m6 f6 g7 Q3 J- D于是这里我需要生成一个背景图片。; t; K! n* F: E& W  ^5 A6 _& e
    首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。  s) @$ Y+ r- P* t* F
    + v6 R3 M+ w% `! i2 R8 U3 ]
    然后生成一个背景图片。2 H: D* Z4 f# ^! u9 D

    & F4 B6 `) s, x- J/ Vimport cv2
    7 l' k2 m* y4 L0 |0 p% R+ A- eimport numpy as np5 \. Q. z- J, b& |" B! U4 J6 U

    3 v; b* f* ?' a( C7 L, B
    0 G$ P3 L8 p$ zimage = cv2.imread("origin_png/person.jpg")& C! F2 G/ e5 v
    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
    9 L3 @8 |1 o" g' {" `origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])) t5 s+ v9 y3 r" w
    image[:, :] = origin_bgr) m( o% d- x1 \; ?1 r0 E7 [4 D

      P5 e% X  `2 N0 o/ t3 R2 p. ecv2.imwrite("mask/bg.png", image)) g6 ~+ K* j1 F% k
    1
    % O1 m) }7 J/ {2 K22 W. r' U( f# n0 K) \
    3% ^1 U8 U: }% [& |, }% M
    4
    / v6 ^$ x$ C! Q+ Q1 Q& f5* q& E* E. Q$ w
    67 {! x- f6 Z% s' o
    7
    $ B6 b; U. S) a83 ^4 [* |1 F1 m9 ~1 F" n; k  ?
    92 j. s& \' `+ M5 n3 ^2 V3 `
    10% i2 \7 L* }# G4 Z) t! D5 ]+ ~: j
      i0 A0 q1 o. M
    需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码
    , U# ~  ~0 Y1 M+ M& x3 ~! V
    ; ~/ B* ?0 b2 J9 m, x  Vsrc = Image.open('src.png'); B- O* |. K' b) [. b. A
    bgr = Image.open('bgr.png')
    $ n, Y! R: x2 {" L( b; L( s/ |& W1
    : x- {7 D& b9 k6 ?$ [) P  e2& N' j' k4 G' z- d5 A+ a% x
    另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)
    5 m$ y" _- A& k! F, V
    7 K& K0 V: S" V- b# m6 `com = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)
    ; X' @6 A. N9 ?4 D9 a9 Y1, j, N4 M6 o5 H* `( O6 N
    - Q- n# B1 U1 g9 C! N. l3 C9 B
    那么加入我要换白底(255, 255, 255),就是& j/ A8 O/ z. O

    7 @4 d8 P) i* [: r* S* tcom = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)
    0 O) y1 G9 n6 g5 F  M1
    + j; g2 ?8 ]% R1 c5 U9 C. L
    . E$ s: ?) u( D- U假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是7 G, w, S$ D* t7 a& Q
    9 z0 f) c2 Y) I) a
    com = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)8 t1 M# y; ~& g8 s+ }" @
    15 |/ g; G( H+ D# h# u- q$ ^
    总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.: z$ H6 E! f8 y; L# h  `. B6 s$ `

    - g6 _3 H% Q& f& O然后就输出图片了。可以看到效果相当好。不愧是oral。2 h8 ~/ c7 f: F

    / E/ u& e# W* |/ ~9 o' U% U8 {) G+ @0 b
    * |. {! C6 @: @8 O原论文可以实现发丝级效果
    . X, z6 M) t' R3 _# H) i/ l4 W
    & R7 @8 q7 l$ e. `
    $ |" e* b# j9 R/ _* d) a
    5 p# X4 r5 e+ Q2 U( E; H7 t( {3 b$ `) {

    % h1 \, C4 _( D! l8 ~. O报错解决方案8 t# A' a: D# F. O
    can’t divided by 4 / can’t divided by 16
    ) a/ K; T) w- b7 |由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。
    : U# L( \% [2 E5 H这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize* `" o; ]! j! K) ~% v5 ~2 E
    ————————————————  b( R* L( n2 U/ X4 T, x. M  ^
    版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ; m1 f2 }2 @' _% H. s. D3 y- S原文链接:https://blog.csdn.net/weixin_43850253/article/details/126376767
    3 E' S! x/ @8 `! Q1 a' |% U
    4 Z, _" t- ]1 D! M$ y6 I  o4 C  e7 @
    ! i# f1 N. D9 Q  D0 V* ]# {
    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-26 22:52 , Processed in 0.513538 second(s), 50 queries .

    回顶部