QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2106|回复: 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将红底证件照转成蓝底7 \9 K' n7 p4 d& b  J* j* _/ K
    前言! p; E1 ?- {. ^/ U/ r# I5 ?3 B4 y
    emmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。; [# F, l, {% V, b( F

    8 j7 x$ F. U- V" c) Y  }2 V4 @
    . K" l) M6 o1 C( ?9 d: _+ ?( a0 C: N! N, q" v5 b/ O

    " L( S% p* U& l方法一: lableme
    . j& R& c; }, V# z4 {) |lableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.! T3 f8 l1 N, g" }; X* J
    - T  k4 E; ~5 d( N7 f9 J
    # 代码来自 https://blog.csdn.net/hello_dear_you/article/details/120130155
    / x/ Z/ J. ~/ @0 b& N7 cimport json7 Q4 m7 e3 f9 z% Q, R2 }8 X
    import numpy as np& M- z0 X. Q: W3 i8 }3 f
    import cv2# \1 M  l0 N7 k9 S! }
    # read json file# h( q7 \+ ]2 d5 g5 r) ?
    with open("origin_json/mypic.json", "r") as f:
    * @( N( t0 N; p0 a- D    data = f.read()- p" N/ K" k& Q$ q
    4 X2 e. k  J2 @" H, s  V1 U1 f
    # convert str to json objs& E' ^. h3 x/ D
    data = json.loads(data)
    # P, _  r, \5 z% X9 w* o. D, F( {$ i, y: A/ w
    # get the points
    0 f4 N& K! g/ Y+ C5 G/ Cpoints = data["shapes"][0]["points"]
    ' w% _! N9 x1 O7 l- o* |' opoints = np.array(points, dtype=np.int32)   # tips: points location must be int32
    3 M4 M  B& e" S' n. f4 P5 N
    % F! E9 Z5 O7 o  t' C/ }# read image to get shape
    " ?; e7 E$ R- d% D8 n7 ~image = cv2.imread("origin_png/person.jpg")3 O/ D3 s% z; U) E+ y

    # P6 i9 [" b' c, G) b3 A/ |/ L# create a blank image  `' S% [* r1 w& `6 D7 ~
    mask = np.zeros_like(image, dtype=np.uint8)
    # y. a+ Y" [, a) Q6 X' p$ i6 ~) d. ?) C
    # fill the contour with 255% C$ g5 `2 Q1 H' ]3 k* T9 x* T0 R
    cv2.fillPoly(mask, [points], (255, 255, 255)); I) V! |$ l  l  F' R  `

    6 g) q9 R9 j* L0 B7 d) T9 y# save the mask 4 b; i2 T4 Z; @/ J
    cv2.imwrite("mask/person_mask.png", mask)
    5 _% l* Z  B! X  _! Z1
    2 o6 {0 D' m) ?2
    4 X+ g$ X% l  F% J. b3
    % ]$ u+ y: G+ L! U5 h, `! b4
    . y' D4 T# ?6 m* O5
    % X  ?! [4 g# W/ V0 {6
    # S  a9 s! D; G5 @: f, E! F7" E1 H" ?2 ^7 n/ a7 q
    81 c: P/ Y5 N+ Y; P% `* d
    9+ F) q5 u: m+ z6 u
    10" a9 y% j: {# w  D* g3 i. G7 ~
    11+ K3 ~7 j, a5 m" h7 n2 g3 T
    12% t* b  v/ o) x+ b+ b2 k& t
    13
    9 J4 ^( K0 q1 t* M# a; y; m7 y14* {5 a0 M: F3 h" V1 ]
    15# _- W" K+ m" }5 Q, R, `1 ?8 I0 G
    16- F; y/ X6 M  O# w! e; `% I
    17
    1 C+ o( S" j% O0 J18
    3 B* j6 O; F# b9 p& H3 }/ r19
    / d( u, g5 V, o2 ^8 s$ }* i' l20
    5 g: t7 E) E; u% `" ?5 Y( F21
    # ]( N$ {* `0 E/ N0 P222 h+ p$ x' t  H# P9 @2 A. f
    23! g( Z, ?6 J8 {( c
    24
    # V/ g# s9 o3 d  _* C8 q6 ^6 H9 y: R25
    3 z, K5 Z1 q1 z: i4 p+ r264 {9 L/ C% N" j
    大概是这样:
    6 v9 W' g, a" y: `) t* q8 d- V6 L1 F- }

    - C& ^% t  d7 S0 M$ Y: }然后利用这个mask生成图片
    - T! V" d  U0 t# y% ~0 |  P1 X0 }+ P
    # 参考自: https://www.jianshu.com/p/1961aa0c02ee
    ! l# t! @4 `4 @$ A4 x4 Fimport cv2, n; V& R: g, u- P8 N  a6 K
    import numpy as np
    : ]. c+ ]! V8 h, ^( c2 _
    / ]' D9 d  X- \: i/ r8 v4 k1 X6 b3 q
    ' C( b  A& I- c& @: iorigin_png = 'origin_png/person.jpg'( I+ g+ [4 Q/ `7 T/ t
    # maskPath = 'mask/person_mask.png'
    : f1 p& t6 Z4 P  amaskPath = 'mask/bmv2.png'
    , B1 y1 L5 ]; X$ o  ~result_png = 'result_png/result_png.png'
    : ~# E! W6 ~) S9 O( m! d4 Z  p) U  M  U
    . q2 I7 c8 u4 U$ E$ l5 _* w# \; ^% U, e3 x+ ?( G
    maskImg = cv2.imread(maskPath); W$ b$ K& g! D. h: h) s& }
    img = cv2.imread(origin_png)
    7 T9 h( P' d. \" x' a" Y6 hassert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'
    & U6 j9 [- I/ t1 j* U; B, T4 F+ ]+ _, \" y# ^9 R
    h, w = img.shape[0], img.shape[1]% v% Q9 z* m. Q0 w- k- ~5 f4 n4 S. }# N
    print('图片宽度: {}, 高度: {}'.format(h, w))
    : r+ F3 V! L) \. U% Z. h/ Q2 R  I6 t+ n6 L
    rgb = (19,122,171)' A9 q, f6 b0 X. L) `% f
    bgr = (rgb[2], rgb[1], rgb[0])
    1 [: ^6 I6 }& W; X" N* ~# j! F' p# (B, G, R)$ G% Q% h% r5 i+ O
    for i in range(h):  r- V: C! Z: ^# r0 W
        for j in range(w):
    5 f/ Z; V/ y9 p* R0 I        if (maskImg[i, j] == 0).all():4 S: S: D8 V& ^; @, D! m; L$ s$ b, Y3 t
                img[i, j] = bgr  \  P: }& g  Q$ l$ J7 Q5 M
    cv2.imwrite(result_png, img)# _# G# o: }* x$ T) g
    print('图片写入 {} 成功'.format(result_png))
    0 B: L" Y1 }/ q1' @6 |4 B& E- ]4 Y, a, e
    2& K: f# q- V; M8 G5 O4 F
    3
    2 }* N- R# p1 [0 w; h* Q4
    * p' s, o8 r9 u8 u5
    ) w% r% _7 M, {1 {6
    - s. E  s$ J! L6 M0 n7 [7
    / h4 W# v- p" X7 G: a  N8& S! X! g6 \0 L' L
    9
    : X$ V4 |2 M4 ~, k) d10
    5 r& P# _0 L) ?- [11
    4 ?5 n. v9 F) e  w) t. g/ s! v12
    7 O- n. g! A) I* ?- W: h% @13! W4 u8 x) b1 Z$ Z
    14% f9 x+ s; I6 G8 S9 ]2 Z# v: S$ ]
    15
    * w- l. H  F/ i: w. F16( H7 C' ~4 N5 ?* r6 w/ {4 Z
    171 j) H4 W! Q7 a3 B+ M  v% w
    184 l3 ^- a' t3 g! k" C
    19
    1 q2 S( P$ k  ~# G20
    7 Y3 F0 ~; p' K6 c3 e. B21
    + m' |9 _+ p1 D% b22
      }2 n  `' E/ b% n23
    ' V, o: g) [/ u) M" ?3 m! m4 I24
    $ h8 O1 Z7 H& B& d25
    ( v: C' N1 U2 |( W. A6 \6 X26
    ! y1 k8 O$ }" _& d27) c2 W4 V' V, T- D! D  }; a$ j
    由于人长得一般,就不放图了…8 a2 u. B! ]: u+ G- }
    / k( z, z- s2 t1 T5 K5 g3 I
    缺点:$ m6 _) R4 l' v% a0 ~0 B
    lableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。
    3 j. ~9 C/ v; M) G2 r0 V! p5 y; a' w- w7 s7 C0 @" S; g/ j: A

    3 R: a& R, M6 u- L8 S9 D0 J4 w
    0 s3 M$ O: |* p/ H% \
    . K9 g  |3 h) w  P/ W; ]# ^' O' k0 c9 y* v! y
    方法二: 阈值
    : x0 s! z: n2 C$ u- t" M( J9 u该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。  `0 u' j! i4 o7 I% X
    & j9 b* m/ c& I2 Y8 ]0 [4 F. M5 c# e
    Opencv
    ( }0 V3 l/ x/ f) A3 Aimport cv25 r+ T: e1 h8 N2 M+ Z$ m
    import numpy as np
    ( ], W+ n5 e/ B; U) B6 |7 w4 b1 Z& R3 _# Z2 |
    / H% m! t4 u( A( \+ u9 [* s
    def mean_square_loss(a_np, b_np):. p# O6 H) Z3 B
        sl = np.square(a_np - b_np)5 z3 I# Q  d4 I' k
        return np.mean(sl)$ M3 v1 t. R3 u$ x8 R
    2 ?" c1 ^2 v# \% g2 [

    9 v3 c: c  Y5 b1 edef change_red2blue(origin_png, result_png):
    1 A5 P, n, i3 j. N8 D1 W    img = cv2.imread(origin_png)
    * E: F; X- K' v4 c2 R, k, \" ~
    0 Q( ^0 ~( n. e  x    h, w = img.shape[0], img.shape[1]
    6 ^! B$ r- z2 J) U0 K- ^    print('图片宽度: {}, 高度: {}'.format(h, w))
    . u+ ~$ f& B. N6 Z. f' o% c4 X1 |/ j$ L* u# G8 u$ e2 M" `
        origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
    ) l7 k) y1 q# z1 ^' B    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])- T/ R/ A% T7 Y
        target_rgb = (19,122,171) # 蓝底RBG
    ; S; ]$ L! l8 d( }    target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])
    9 ]9 l8 j8 u, i$ c% H# _- O8 r: {3 C. `
        for i in range(h):
    & O0 q' K3 o" F, N# T        for j in range(w):
    ) d& X0 x  [2 l" ~$ v$ K            # (B, G, R)
    + p9 L7 |$ R( |$ l- Y3 G            if mean_square_loss(img[i, j], origin_bgr) < 50:
    ) l+ a  w) N" H) i5 x$ G                img[i, j] = target_bgr 8 I+ ?! g  a# Q! S8 J0 V
    . F$ `/ |) @! _$ f
        cv2.imwrite(result_png, img); m1 i5 w' @  `
        print('图片写入 {} 成功'.format(result_png))3 W* J! R! B- n% B! C% }/ q" K$ r

    8 S6 A( k; \% f8 V9 t0 ]) M! r# A/ n/ |8 `5 n* e1 j
    if __name__ == '__main__':
      I3 v9 q; T' Q6 x+ |4 j+ y: I$ l    # origin_png = 'result_png/result_png.png'
    9 ?- z- \9 a  G; R+ C/ Y8 [" o  D    origin_png = 'origin_png/person.jpg'9 R; ^. t" y; p& O+ {; Y
        result_png = 'result_png/result_refine.png'* m! h% ^1 x0 I; s" L( w
        change_red2blue(origin_png, result_png). p9 m9 I" e* D2 i1 c3 M) ^
    1* p& ^. E7 x7 f- b/ E4 o7 Y
    2
    $ q& _7 r9 x2 ?( ]1 w3
    1 m# T$ k1 _9 [/ q, T4
    * E) k  r  W8 ?6 i- `  r, X; S5: y0 C8 W! G, ?
    60 k$ T, y# l% @; ?( U9 Z
    7
    # x: ^; v& v8 Q* ?" W8
    % v8 z; H; C- `6 `7 `9 K  {91 E8 l0 O, ?9 \: y& ~
    10
    3 T5 J# M" S/ {  Y- ^11; L  c5 B' H. h) D& o
    12- ]) q& w6 l; M! a
    13
    " d/ ^' c" C; m* m14
    & A# N2 B6 U! @. P- `) Z( n15
    9 G6 q& o9 E# L. m* l16* l% i* H( c) C) u# o# h2 k- c
    17
    # @) @: X3 h+ c/ A2 z  i) J18% o) b  t  J, O
    19
    3 I/ F8 {6 f8 q' d2 }20
    ) z/ {/ d  f) e$ R8 J: {21
    8 l; a& b0 R% F: ~$ a226 [; u' g* c8 y$ i3 m/ d8 {6 w
    23
    * w; i: d& A6 y: C3 E/ E4 v: P# i8 G$ G244 _9 S% H, `& b, d' d7 s. U
    25; W$ i" _5 {( @! K& o( R6 B9 ?
    26- N; ]. Q) U+ z# F
    27+ }. w' u2 P5 Q: q$ n' P, y# f/ a& g& n
    28; C) h8 R) i2 G
    29
    $ S* I6 g# X7 F+ j7 e  k0 O0 v30
    * y0 c- I% u3 E5 {; V8 ^31/ t4 o! f3 }1 }! T, z- U
    32
    ! F7 Q$ p4 V% a" b33
    6 H* p. c0 e6 D9 H) ]4 d& o34% d1 {! ]' K7 Y" S5 S  X. \
    358 Z6 [" s6 \9 I0 `: ]+ ~2 S
    结果人与背景边缘仍会存在红色像素残留
    - q0 m* ?0 D2 g3 V( B2 ?0 s7 t4 R6 w3 h3 j: S2 w5 ~
    ; T& E1 @- u8 S! E

    % }1 ^5 Q- e- t, |2 @' y( c+ ^' T; V. l" f* M
    5 W% L" M/ }+ v" |6 \+ ]
    PIL6 k4 v7 ^; \: E, P1 I5 x
    from torchvision.transforms.functional import to_tensor, to_pil_image( \) Q6 X0 r, i
    from PIL import Image
    - K  }% z5 [8 A# `* P( G( _import torch* v4 B$ n# t* I; v% @
    import time$ v# K$ o* c6 V, H( Y/ b

    & @! ^+ u" ?5 o5 r8 Z9 k' `# m6 C! x9 ?7 q$ B+ J8 u. S+ X
    def mean_square_loss(a_ts, b_ts):) ^2 a7 X7 Y& l1 n: U! W: h  \
        # print(a_ts.shape)
    , u# S& a9 [" P& I2 X  ]    # print(b_ts)! |% F1 P5 c, o4 L6 I" [# O
        sl = (a_ts - b_ts) ** 2+ {/ _, A$ n) z2 H5 I* y+ j
        return sl.sum()9 l* ?+ Q/ N% e5 V" B

    2 B+ a5 Q4 r* g, q9 O
    ; _" N2 ]- z# Q, F# w) Qdef change_red2blue(origin_png, result_png):
    - \' e9 a1 ?) X" O    src = Image.open(origin_png)* i+ _0 \% r3 P  P4 z9 I, h  q
        src = to_tensor(src)8 y8 ]6 A8 g& B. F6 \8 k
        # print(src.shape)  # torch.Size([3, 800, 600])1 J$ ?4 D( g' P+ P! o
        # channel: (R, G, B) / 255* T+ }& _  h1 `& d' T" i( r
        h, w = src.shape[1], src.shape[2]
    ! o+ a/ p8 V9 y# {- h; k& E1 A
    " M  L+ e/ W7 |6 S* m- O% C7 M- h2 F( h    pha = torch.ones(h, w, 3)
    5 h* w' C# J3 l% e& n" j% Y) c% g  U: s( P6 P
        bg = torch.tensor([168,36,32]) / 255, l5 b0 p6 f4 W3 p, v- S
        target_bg = torch.tensor([19,122,171]) / 255% G) J; J1 i: R9 a, e) P6 d
    : I& f1 x# S! p% p. |1 Y# k1 \
        # C, H, W -> H, W, C
    2 v) w1 j( k3 k0 W% l  M    src = src.permute(1, 2, 0)
    7 l, z/ Y  w6 f& \    for i in range(h):
    / t% K4 U  `6 D        for j in range(w):
      f% ]% ]+ }$ z5 g7 T! X            if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数
    ' k, b, R& d7 O0 Q; \* b' Q) w                pha[j] = torch.tensor([0.0, 0.0, 0.0])
    8 }' f% }: [& _. K* G. c) r2 R% {! |$ d* e: t- M
        # H, W, C -> C, H, W
    . Y" e( n- e5 ~, ~' O9 E    src = src.permute(2, 0, 1)
    3 P8 D8 t% p# r& {1 G9 q    pha = pha.permute(2, 0, 1)  v- c, j2 R* v7 d& c! t
        com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)
    % T7 x& T  c4 w- i8 H8 c    to_pil_image(com).save(result_png)* g8 V& S, i, g( j  W* i
    $ @2 r3 @4 A6 M

    ; u* P5 I: c+ L" eif __name__ == '__main__':3 i" k$ {$ M4 z, P6 i
        origin_png = 'origin_png/person.jpg'
    % \+ P# Z1 \* ]2 G' j% p, N1 [    result_png = 'result_png/com.png'6 n0 h! p8 j* p2 N
        start_time = time.time()
    " M, r0 Y. t: f0 k    change_red2blue(origin_png, result_png)
    9 H% Y. ]; \( D& ~, k    spend_time = round(time.time() - start_time, 2)
    8 s* A% a$ z/ m1 V6 j3 A    print('生成成功,共花了 {} 秒'.format(spend_time))
    ( }0 H& g9 h- L1
    % e: B, q0 v* k9 q  Z26 g5 i* Y. ~% G  p. U) g, h
    3
    ' {4 f, l6 t3 H( j/ D2 \7 q4 [4
    0 f  O7 t. Q  z9 Y1 x5, h; N+ I2 l0 W. |
    6* f* c/ s( N8 v+ P4 C
    7/ S1 g! `8 r0 A6 p+ }0 ]
    8
    # }2 }' ~& G8 D1 Z9/ m4 v! O1 X$ g; d  P
    10
    1 m# [5 {4 ?% r  x$ x) E! j; h# l11
    9 n, M+ }- s! G6 {2 l12
    % w& G) I' J1 P- P4 s$ M8 @13. O8 M) n' o( r2 E/ ]
    147 [$ g# [9 m6 h' Z. h' f1 H
    15% I! O+ F( a: \7 I5 l2 E! g
    16% f4 s4 ?) z7 I, B, c/ j
    17
      R! D0 A2 a, Y: Q' D18# o2 ^6 z$ ]& f# ~) E7 P! T( c
    19
    9 \. a, X- T  r8 \; w+ C20; z! M' L, k% K! P0 }3 b
    21" \' x2 ^% i. n" o/ }, E
    22- n6 Y1 [, t: }" d6 r
    23! B% w$ c  i1 t. a1 X9 O
    24
    : Y2 O/ L( U! f) B! E9 N( w25
    * z0 s7 G$ y4 h' E* s& a+ Z26
    7 _9 ?% Z; m* O: R) H6 m27! y& }' N: m0 C7 |9 H- \) \
    28) x) \& Y: J# H# y
    293 ]& H5 P: J6 J
    30
    8 ~% @6 F2 ?2 c5 @/ E" C" a. T31& q' H3 @0 P7 d2 a- f
    32
    . P/ A4 x( ~- z1 }/ Y8 y2 q33
    % s% u, Q" `6 p6 y4 Z- S9 j34
    ; j1 W+ e. [- A+ {35$ q, S6 Z; c( O) L' ]
    36- W: x9 a+ D; q
    37
    - ^: N3 A' A9 ]- ~3 Z38
    7 j  |# ?8 Z9 f' z1 ]7 R39
    , z4 \: U$ J0 b4 i8 U; h40" R6 Z# R% d( }3 j* ]) q6 w2 K
    415 l9 k! o; `! g+ m/ R
    426 D$ B2 [% g4 x; o/ ~6 o
    43) D" a2 t- k) p/ \
    44! k. W- T& }5 R+ y8 e2 s7 q  H
    45
    0 @0 h6 @2 q% a46
      K) c7 g( z7 ?该方法质量较好,但一张图片大概需要12秒。
    3 U* d$ A6 d1 B  c: ~% _7 S
    $ e/ _2 k; p4 x4 u! u. h
    3 K  L. G, t3 @4 N2 \; p) B5 _* P* o- C  t
    方法四: Background MattingV25 R5 L' M" G* W* j
    Real-Time High-Resolution Background Matting8 R4 \0 s; H, A& I9 Z4 i8 M
    CVPR 2021 oral
    5 O/ o( T5 L# m4 b& n1 p: o
    / R. }1 [  _1 c3 z论文:https://arxiv.org/abs/2012.07810" _( e* Y9 I7 w, M9 B
    代码:https://github.com/PeterL1n/BackgroundMattingV2& a% {- E) ~, d

    . X* Q+ o( x4 z9 {& Q4 @github的readme.md有inference的colab链接,可以用那个跑: p5 s& J( y4 R* Q& e9 h( C1 G; h% [
    % u* r  |6 }3 |! l  ^/ `
    由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。1 d6 U3 P- |  Y4 v1 s5 L) h$ C0 @. a

    0 n" }! ~( u- `6 \$ ~% K于是这里我需要生成一个背景图片。
    3 I& a: P& \! O. Q$ `. Y9 E: A首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。  u& ~2 V7 i: H
    " d7 V8 T4 t/ S+ C  ^' N; ]
    然后生成一个背景图片。8 X, ?# |0 O  f+ _7 f
    8 @9 E% W, v% r
    import cv2
    ' f$ [4 E* `" I! m0 ~% rimport numpy as np
    % c- r) y- D) K' u8 l7 }2 j" O5 a/ E
    6 H0 u: }- {& @# x# ?; w4 r% d" ?/ \6 d7 S2 U0 |
    image = cv2.imread("origin_png/person.jpg"); k2 a, T/ ~2 ]
    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值1 Z5 s# X: e5 A: y3 I
    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0]), s0 u0 D) U+ R& ^% @: ]
    image[:, :] = origin_bgr
    % u. C( p( D" X! Q3 e. o6 V6 T9 n: y
    cv2.imwrite("mask/bg.png", image)
    7 b) R. J  I' H0 B1
    * }9 b$ s- \2 ~2
    $ S3 ?; e; P! N34 |, U5 K6 m! B1 d
    4
    ; k$ R4 [* K5 G9 n+ [- I5 W0 a5
      ^* ?6 h  `/ H6 o0 k0 x, M6
    * J8 i; r* S, q' e+ I7 l. c7
    * b* w  c$ y' c# d9 C  n/ L$ B8
    5 u$ _9 p$ Q5 k: y9
    ) ]& V6 [7 a, }' }10
    ! a9 ]2 r8 l9 ~- O) w: r/ ~+ q8 Z  H$ |7 X0 `. [; u7 P, j
    需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码
    . u8 |6 N  T5 q" J: r0 w
    : }" C# ~- C. M' i* Isrc = Image.open('src.png')- h9 ~' g0 e2 B! w: s1 p
    bgr = Image.open('bgr.png')' I/ L1 R* U& Q
    1
    % Q: N/ S& @7 ?% p0 w* \& l: ~2 F6 f23 F% \5 @3 q8 b7 y* X6 v' l
    另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)* Y  i: U; D4 _. A  f
    : I+ m+ a% d! p& {9 R
    com = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)
    6 w+ s6 o# Y3 J, u/ z7 {1
    $ ]1 f% f% Z: o( C5 m$ e+ k6 A% z$ I5 ]
    那么加入我要换白底(255, 255, 255),就是& @$ q9 ]5 B6 p/ Q6 {

    - }& x: [4 @3 o* h6 s' B( Ccom = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)
    9 H8 x6 l! Q4 g1
    4 f1 l' P; D# \6 v0 ^
    $ u9 c  V" O& a' @- u2 B假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是
    1 O) Z! q# }: H8 I7 q
    ) R5 \3 ]1 i) M  h( ~com = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)
    # L! w; v( v6 E: f& O! L1" I. C. h2 X8 E0 w8 Y  y$ v  i
    总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.
    + s/ U5 w. ?$ k5 G' f/ w' \8 c7 N0 Z
    2 E8 C- @9 O' Z$ g/ n然后就输出图片了。可以看到效果相当好。不愧是oral。
    2 y: n4 |" o. P
    7 d0 k6 f3 T6 `2 _: x: ^9 b* c, _
    原论文可以实现发丝级效果
    ! o: W" j2 h0 C8 o1 t0 j, u- d3 T: }9 M( k  R
    % \$ H1 `5 p. J! K1 z' N% _% A

    5 q' V( G( R0 F/ j8 Y; Z5 b. O$ X4 o( h7 J

    3 N  w& U( {4 p4 e; [8 z9 n报错解决方案
    % \9 j, Z/ F/ E, M% W! i; ican’t divided by 4 / can’t divided by 16# f4 _$ N: d$ q2 T5 g' `
    由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。
    6 [6 s8 O( u7 r这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize8 U/ A: r( j4 R1 `& d" B
    ————————————————7 Q3 _1 p7 E( I  ]! B
    版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。/ F) o' J' B- c) k, a5 W' c( P/ h1 w" S
    原文链接:https://blog.csdn.net/weixin_43850253/article/details/126376767- X5 t/ i& U! ~! `7 o' n! [% k5 h

    : S) M. G2 N, B+ T5 V4 D2 G# V0 Q' T
    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-5-26 05:14 , Processed in 0.385151 second(s), 51 queries .

    回顶部