QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2162|回复: 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将红底证件照转成蓝底
    ( R4 j# x9 p/ N8 o  s前言
    ! l" U) l6 ?; N# Z0 x# F, ~& oemmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。
    1 B, q; v) s  M) {) S) E9 I: J6 a' Z

    " d$ m. k  d4 w1 B" _; N: l9 B) t) `1 Q: K& f3 d; F7 f; Y

    2 y) E) {( c5 Y" M' E$ W9 ]+ D4 a9 ?方法一: lableme
    9 [: E. r- \4 i# C2 Z) p" plableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.
    ; {' C2 U  f# {1 {: F! o; k6 [
    3 `) S7 q2 U" m$ I# 代码来自 https://blog.csdn.net/hello_dear_you/article/details/120130155
    - G! ~) g6 p% R) h+ ^7 t; w) A8 y5 aimport json
    8 }) A' L  P! F0 B* _* H' [3 s) N' simport numpy as np9 P& e4 G9 Z) ^' l- w. G5 I
    import cv2# o5 h( g( B9 o5 }' d
    # read json file
    9 s$ w* m) s- k) A' {9 u! Ewith open("origin_json/mypic.json", "r") as f:
    7 S; h# Y5 Z8 u    data = f.read()7 \8 s) p( H. Y. Y
    + Y+ Z! u3 w- X  Z$ }1 z& ^8 o
    # convert str to json objs
    0 _- N9 V  W, t1 _. H9 g8 xdata = json.loads(data)# T; w8 ?% P6 Q" B/ ~* I
    * g3 |4 f( d$ D
    # get the points 7 T; l% V- g" Y8 K" O
    points = data["shapes"][0]["points"]% P: _) {0 }# L, O. t
    points = np.array(points, dtype=np.int32)   # tips: points location must be int32/ }) J& B% w2 y

    * A9 p1 e+ l1 W3 x% s# read image to get shape7 u8 s% L! F; O4 u. Z
    image = cv2.imread("origin_png/person.jpg")
    0 M$ F# U2 n3 {' a4 u1 N5 ~
    , H3 L& J; y) r2 y3 w) n5 f# create a blank image
    5 Y( h" S. _6 z% W1 Cmask = np.zeros_like(image, dtype=np.uint8)
    ) q3 j5 J: s( h$ N
    7 a2 Q, |5 R$ b* K  a! z# fill the contour with 255
    $ W1 |4 c) E) w# ~" ?% e8 _cv2.fillPoly(mask, [points], (255, 255, 255))/ z" ~' y5 W3 s* b

    , U# c2 V  n1 y' Z' u# save the mask
    ( @  t; ~+ e5 @0 ~/ K! Qcv2.imwrite("mask/person_mask.png", mask)' }0 A3 \1 H: X8 c2 I
    1$ u" j, l( P& G7 p* H
    28 M' p2 @/ l! k: I& t
    3
    " @1 |1 x3 I6 u( C4 d5 Y# d48 j" ~  Q4 D' O' I& `+ m2 J
    5
    ( }& f9 A' y: k) {6/ u* p( r5 \" o/ T
    7# ~8 d0 D: k6 Q6 I6 ^( v8 X' H! [+ _$ Y2 Y
    8
    , w. p' V2 E2 g; j3 R9
    $ L5 x' f8 O  U5 k10$ g  R4 J, g- t$ t
    110 x, P; ?, L+ g5 k4 o* r! \8 ]. y
    12' U& r9 t7 k. G  _6 i. w7 l
    13  ^: a4 I1 ]8 P3 x0 ~% w! Y
    14! [( P* l) u1 I3 B0 {
    15
    . T5 ~( I1 t5 X/ s2 W( h16
    ' A% n# J' E# D$ }8 j3 g17
    1 w: w$ ]4 E( C" b18
    8 y0 `4 X& D0 Y9 n$ y! C; y19
    , l6 d3 @) `; p  _204 }/ z+ l( x3 m* N
    21
    % K6 \* p& F; t2 b" h224 k$ P1 l+ g7 o9 W" c
    23
    ( \3 S; I: F% P: V8 O5 q7 o) T249 v/ y. W( [/ B) w3 d6 N
    255 w: L* L) Q0 j. `8 h, [. D
    26: D7 ^8 U* A( e- |) Q) L9 e
    大概是这样:
    1 s, ^% H: O! R$ J6 A
    : i. Y  s7 K/ j2 h  y
    4 s6 r4 V* A: Q& [, ~5 l然后利用这个mask生成图片& e) i; k2 D+ ?2 b- i6 E

      E# ~  L, u/ u- A4 i; m# S2 |# 参考自: https://www.jianshu.com/p/1961aa0c02ee+ ?! p, N3 M' z7 Q5 f% ^: q7 [
    import cv2
    1 Z8 w6 K/ J+ `9 E% mimport numpy as np- K+ h* n4 g$ c' j  r" p* t+ g* U
    ( {' T1 U7 I1 I. Q% P
    4 J. s/ m3 t/ K1 J
    origin_png = 'origin_png/person.jpg'6 t4 b, q2 S4 Y
    # maskPath = 'mask/person_mask.png'
    ; D, `, q& [: ~! D$ n+ BmaskPath = 'mask/bmv2.png'
    + b+ Z# j' u" k1 J8 R+ m0 B* \result_png = 'result_png/result_png.png'
    ' t) P: I! p: j- Z$ {1 r
    ! `% P, f, s! z' E. a7 c) d; x3 }
    - e8 t! E  W/ a3 p4 p9 cmaskImg = cv2.imread(maskPath)
    4 m3 d% R1 ]) o' X9 M8 himg = cv2.imread(origin_png)
    0 c9 n8 y. I6 E: n- f- Rassert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'
    4 z2 z) N) v0 x9 T  U
      U7 v& m: q- m4 sh, w = img.shape[0], img.shape[1]8 W8 S/ s* T1 j7 |
    print('图片宽度: {}, 高度: {}'.format(h, w))0 P6 W& j: J* D3 }8 P! I" ]
    8 [2 o7 R" ?' `+ v  j  R8 s! g
    rgb = (19,122,171)
    ) w$ E. v- J9 m0 k" |/ i# i; ~bgr = (rgb[2], rgb[1], rgb[0]): \- o+ o) ^/ Y) |; Y
    # (B, G, R)
    : z: C6 q. r; N& C- g% e- Efor i in range(h):
    ) U6 e: Y) N5 n, ]# L0 A6 D    for j in range(w):" B) @4 P/ P5 o& |# l. w! X' p
            if (maskImg[i, j] == 0).all():
    + Q5 _$ p" y  x* y            img[i, j] = bgr
    & z* Y3 }7 K0 ?- M4 X+ ]' B4 lcv2.imwrite(result_png, img)
    , Q; u- k9 n& o1 Tprint('图片写入 {} 成功'.format(result_png))' a% W; }" `" }( G) I$ T* u
    1
    " P4 i  v* n, w2
    $ z# Q: Y0 Q/ H4 E3
    1 L+ d' z' }/ E3 }. D4( o8 x' [0 b8 Z2 ?' v
    5! f9 u7 y% l4 ?5 x. Z
    6* t* e8 p; C) V& Z7 R  K$ P2 H
    7
    1 O, @$ U3 W+ W8: V" g: L4 y, M* f3 E5 o' {
    9
    ; x# e; `& o$ h7 T0 Y100 V7 r# c3 o: `+ `
    11' Y1 `7 u* c+ S- p
    12
    & {7 _7 k  d! A- B1 J13
    " M- I5 s, U& w6 `! q+ e+ Z14+ N8 a- D4 p) M6 `0 q, Z
    15
    + W. m) d5 m& m167 q- E" `! S6 C- S& v
    17, I& L, m' z% z0 A( h. m: f1 k
    18
    ( u( L# e6 c+ r( r' E19
    & o+ i0 i. P& l* C! {# s20
    ! y) j* b7 T: W' N% s0 S% q8 P211 R# f# }* e, ?" D- c- {
    224 B4 \8 B4 q- t- {( X( G
    23
    # U# i! _: m) x9 u5 s, b248 J! P3 o; E, s
    25) w/ }. x" [3 B! U  e6 Y- l( a1 h6 |
    26
    " t) |# }1 q5 r6 q" p/ y2 O27* H0 U  r) C. {) i& A" _0 e
    由于人长得一般,就不放图了…
    , Q" ]4 B* I$ I+ o2 n" ?8 }  y& L- R" N  ~6 G$ `- e  J  D
    缺点:
    ) e- b( `- P6 a8 I. v( Ilableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。# K5 h! _1 n6 ^/ f& v1 G

    ! N! q! b4 Q* N" ~% |' s% N! g3 G, |
    5 l& d. o9 s5 d7 q! ?+ q4 u( S( \: k, P
    7 E9 T- ~1 M0 q$ E

    2 E) |; [* o! H- v% D方法二: 阈值
    ' s& s9 l1 B, E! ~  ]1 g+ I# G% r* ~. r该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。2 d* g, Z3 L: i
    $ \) i7 j; N+ p! [+ e; d/ M
    Opencv( _) V3 N* S/ S3 w
    import cv2
      @; N! I2 H3 ]import numpy as np0 O5 G# h9 e% o3 r- b1 W

    ! z- h  w0 v6 h: v, A
    # R8 _: b, x0 b9 y# o0 adef mean_square_loss(a_np, b_np):3 s( U. M: s4 `4 R% u9 i
        sl = np.square(a_np - b_np)
    ! L. T* U% h# _7 I$ Q    return np.mean(sl); P* e/ e, r& j+ p
    4 s4 M5 X$ r6 W. o; p" o

    3 i7 p/ ^" f1 T; z% Q% t: x: Ldef change_red2blue(origin_png, result_png):! o2 H. K+ J6 e1 ]7 T5 F8 l
        img = cv2.imread(origin_png)
    " m$ H: u/ D$ n
    8 a, o% v7 F' V' b! m    h, w = img.shape[0], img.shape[1]1 d' R" c3 Y, U" v
        print('图片宽度: {}, 高度: {}'.format(h, w))
    5 A! Q% ]% j( t7 V$ K
    5 U; f  ^8 r/ F    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
    9 t  t3 p. Q1 [( V; x+ e    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    / d( G) o5 }4 @9 t    target_rgb = (19,122,171) # 蓝底RBG
    5 g+ p+ d1 \  j$ q0 W: O$ M    target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])
      N5 ]$ {0 |* h" N1 i' G
    4 _- B, e7 r+ E  }6 B' V    for i in range(h):
    ; @; z6 _) x/ U% D3 F  A        for j in range(w):
    & e0 m2 u% w/ Q: o, j% B8 n            # (B, G, R)9 |( @8 c1 P" H# d% ?
                if mean_square_loss(img[i, j], origin_bgr) < 50:
    * i% W& x% w& L& H3 N                img[i, j] = target_bgr
      w) m. ?' [3 j  ~- x0 n- l  q2 b7 c' l( F- P/ L( }
        cv2.imwrite(result_png, img)
      R8 }7 W) p- s- v0 G! ~/ R. m    print('图片写入 {} 成功'.format(result_png))
    7 `1 ^& F8 q; e
    3 e- V9 d, _* {4 M& t7 o3 y- j, K, k$ v) I0 I
    if __name__ == '__main__':
    1 E8 E/ B- E: Q& q0 v    # origin_png = 'result_png/result_png.png'/ E7 g0 K4 z- X
        origin_png = 'origin_png/person.jpg'& E3 }1 v8 I4 f- n4 l% ]' X
        result_png = 'result_png/result_refine.png'
    / j) s4 M# R% r1 o0 f! q8 t    change_red2blue(origin_png, result_png)
    6 V$ g, z  r+ d- T$ r; T16 L! f5 R+ q. M
    2
    * |5 I$ k- I/ E3 t3
    4 F, ?7 O1 k! V$ ~3 q1 ~# f4
    , M2 I0 L( F2 N$ O1 V5. G+ s1 E# q) \" m
    63 t; e4 B$ M, x/ E( e/ o6 k
    7
    ) ~; h; O5 ?; _( @8
      B0 W  `: W0 H  y5 O, h3 h( ]( M9
    1 Y! k6 y# ?* m* t0 [10
    4 [0 A7 P1 p2 \11
    / |# ]$ q* @/ w" d! |9 T) l* Q- Z12+ U; p1 [6 h$ g
    13
    9 b* f, I. ~  K# |+ ]. h14
    6 S9 E6 h' C( V2 ^5 q15) c# n, U. y% M# ]& F$ Y
    16
    , _  u! R$ O# n7 o2 n) ]  j176 y2 c3 {# k( H1 O" c9 X3 i
    18
    5 A; e" I4 n& N# o& _9 d" e19
    & ~. s2 p; H7 Z) J20
    ; h& ?7 n5 x" F+ x0 `" k! J3 P21
    ; Y1 _' e. M$ e+ w8 m- y& t2 k225 h5 q% ~7 X. R( r9 m
    23" l" L8 o' Z" P2 |  t3 M
    24
    . \3 |9 \* g* J: P8 `( T25
    3 R, O# d' b" f; d3 t26
    7 v+ E5 R0 j3 F5 c7 o27
    5 c. ]& I( ^) ^28
    $ a0 d4 ~( g! I! l; [2 q29
    ! x. {/ I, T# \7 A( x4 P30: G+ a# O% A- Q; }" K
    31
    4 p# M6 P- k, }. T0 G. p32, q$ I9 A% k1 S' `, g/ o/ ^) k
    33
    4 y! j3 q+ `* Q4 s: F34
    $ U2 o. J- g* ]8 j6 P* z35
    $ y$ u3 S* }  {) ?' t0 C1 h3 m结果人与背景边缘仍会存在红色像素残留4 m4 d& ?9 L' l7 |# F6 {) R6 C
    3 c$ r( K* |0 E% E* [1 x1 w
    - ^) c+ i+ }' n& {% e1 o8 J0 K- w

    8 [1 \0 l) B% ?0 v9 P2 N
    $ D6 m3 W! O7 X5 V: W$ p# {
    1 W; d) {3 w- s+ i" U5 _PIL
    / ?: R: j  r# g5 Gfrom torchvision.transforms.functional import to_tensor, to_pil_image- |: @+ A: L8 J! Z: W
    from PIL import Image  j4 X, I- b. V5 Z
    import torch/ X7 U1 G. E0 u) j# X
    import time
    9 W, w( g  {7 x5 V
    3 O! _8 R2 q" x( |3 a5 r3 Z! C
    , B8 b/ i- K0 s5 X7 P& Kdef mean_square_loss(a_ts, b_ts):
    , p9 K! x' J  G! N, ?0 H8 }6 F    # print(a_ts.shape)& N; D1 u7 E8 b' w5 I
        # print(b_ts)% L! a) l$ \5 }7 h9 \# {  \
        sl = (a_ts - b_ts) ** 2# {/ [0 _+ _6 y, U0 @0 p
        return sl.sum()- ]( v% F: i/ r2 U# K5 G) [8 X

    ' V& i9 _- _0 g, ~. P9 H# Q! M1 ^" h8 \. y7 [
    def change_red2blue(origin_png, result_png):
    1 k* v- z0 Y6 _; C8 k2 |" f    src = Image.open(origin_png)% V2 q; a7 y% _( }9 G$ Y* P
        src = to_tensor(src)4 s, I5 }* u8 j- w/ n8 l( \  M
        # print(src.shape)  # torch.Size([3, 800, 600])
    % s* g# H+ p8 L" ^1 S+ x/ y* N    # channel: (R, G, B) / 255: n7 b$ z' v+ F3 `
        h, w = src.shape[1], src.shape[2]
    8 D9 h% M( r7 f; C
    : s  l0 J+ W4 Z( v" i2 t0 U    pha = torch.ones(h, w, 3)
    9 Q9 s/ k2 y( P6 Z
    % E, ~( Z2 u. B' D& W) f    bg = torch.tensor([168,36,32]) / 255
    8 h9 u# G$ q$ f    target_bg = torch.tensor([19,122,171]) / 255
    , x- C, X6 ?& Z7 t- i! f5 E* f0 a: Y. J8 O$ N6 E7 J
        # C, H, W -> H, W, C
    8 d# ?1 ~' m& C! }3 D  v+ n$ l    src = src.permute(1, 2, 0)
    * x. C( O7 q( y    for i in range(h):
    ' W, D  k8 P) R* f/ `/ x+ C        for j in range(w):* x3 U  ]2 ?+ w: w. W' A$ p/ Q/ v
                if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数
    5 Y  T7 |9 f" K; I2 Y( z& L: p+ s                pha[j] = torch.tensor([0.0, 0.0, 0.0])
    : L  v( J) U$ F" |0 W7 [  F: a  m) ~7 H! d6 t
        # H, W, C -> C, H, W) ~+ ^# H, Z6 C+ ~
        src = src.permute(2, 0, 1)
    ( Z. t3 G6 F' |    pha = pha.permute(2, 0, 1)
    7 g2 w) \7 c# i* N7 y4 g, h5 `8 a    com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)' u* ^/ d/ G( {; [% k+ G
        to_pil_image(com).save(result_png)
    * H( O4 {# E; R; p' d3 t" w7 g' |1 F+ m1 n" p6 Q. F9 i

    / u5 V5 g1 L, Y' xif __name__ == '__main__':
    8 r4 X/ r4 e9 h2 _7 z" g    origin_png = 'origin_png/person.jpg'8 i- g- t: L; v" d9 ?
        result_png = 'result_png/com.png'
    6 v6 n. o; x. d  k) ^! M2 P7 P. v    start_time = time.time()
    % \7 ]( h- i* |+ E- S' n( }  d    change_red2blue(origin_png, result_png)4 o$ e- d+ `3 U' T8 Q$ j5 b8 f' h
        spend_time = round(time.time() - start_time, 2)% r) d3 g! G) _  M
        print('生成成功,共花了 {} 秒'.format(spend_time))
    0 V7 b/ j) y1 c8 O4 L8 B" Y. b1
    6 C) g' u9 R* s6 B23 y% X) H! E0 T* q
    34 S3 v/ D: R0 i( L( Y
    46 C: O9 D8 u" H- t- u- G: d
    5
    4 m" m+ m7 X1 s9 C% I3 m4 v6
    ! r6 r, c) f* d9 ~% M7
    / L* M1 e) @* v/ r: y* ~8+ R5 o0 x! p# h9 l+ H
    9% Z1 ?# T% m' g$ O6 X
    10" c" x5 k' l$ B" V) J% e6 I. a. J  `* ~
    11
    5 {. j7 f8 n' x- }. m0 p12  ^: C1 V/ S# ]* b" ]5 R3 [( c! B
    13
    / W0 Q* u9 w, C# _* T14
    - k) |/ y6 _! z1 E, X15/ F1 v" \) R1 ]: r/ m5 D
    16( o( `6 x$ d- p1 x9 H; @4 K' j' w$ M
    17
    3 ~1 R4 b+ v% m0 c7 c$ S, T182 p  E7 m) n9 q# |* f6 a; P% N
    19
    & k- ?* x1 E1 e7 n208 M; X; v! @* B; w: `
    21
    . `# I9 |" c0 Q) y- h22
    ' N9 x: g1 D: M/ A23( ]4 v+ l7 B: [5 \
    245 s. \& y) H; g5 V5 f$ R
    255 c( ]" K/ R& B) r1 s- T
    26
    4 l+ z2 s+ f$ k7 W# j+ ?27
    ! I. y- Y1 }5 z% d28- d5 P8 w# X) P3 w9 V5 g. G7 w0 _
    29
    & X2 O# }# w) l5 s1 s# r30
    - y) W7 z2 \# c$ q( b31
    ( z1 U# i, H. T# {% {6 t32$ [4 R# L3 n4 d7 x: y0 c$ w
    33
    % ^; ~, T+ d; s- @4 \$ a5 ~, ]34' m6 V5 S; J4 M* r& {5 ]
    35
    . r. f) i. @( F8 g, B$ y9 n6 p36
    8 y1 g, R3 N* n* O$ e- P6 P7 c7 c37  @6 \1 [4 L. x  Y. y
    383 I$ x  E% `3 V# `: B  H
    39: t' W" T# \  L' n) z
    40
    ) \+ L3 C: c" i1 |, F41& U- z0 P) p+ H% N5 n
    420 M, U9 ~+ n. t* ^
    437 Q- Q7 @5 k; P. X
    441 _9 x4 w/ c" A7 c: x5 q
    45
    8 \( ^4 k( _; o- f+ Z46  Z' U# F# W5 J1 \( t
    该方法质量较好,但一张图片大概需要12秒。$ \' `  o* L# G0 B& O8 B
    ' x3 u# }: A* ?' k; ?

    3 I6 y! Q+ P( f
    1 @6 f" ~7 j! z$ U! F' c! I方法四: Background MattingV27 K  N$ c% G  }7 B4 Q
    Real-Time High-Resolution Background Matting
    + Y! I1 A) o* g  tCVPR 2021 oral; [( R5 X) m4 Y% N

    % A( q: d, c" r6 y" G( {论文:https://arxiv.org/abs/2012.078107 m0 X5 u8 p& ~/ k* \
    代码:https://github.com/PeterL1n/BackgroundMattingV22 e+ O9 M  J9 ^6 @  t
    * {; A# L' T0 S+ T0 K: d0 B
    github的readme.md有inference的colab链接,可以用那个跑7 r4 k$ f$ R- U/ O& j8 v
    : L$ Y' d4 B( h* U9 B$ \. a) [
    由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。
    # B6 ~* N4 q7 _2 |3 M  A# {1 S( Y+ a  P1 x' c
    于是这里我需要生成一个背景图片。
    4 V1 X/ w* J# M3 n2 C5 h$ i! i1 P首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。: y; p9 E0 v3 o/ h

    ( \  J4 m% r0 w# w# }1 R6 {: P然后生成一个背景图片。' l* C. V6 m9 F- n: a
    3 m7 m6 z! C6 ?) O' c  u
    import cv2
    3 w' \% V+ D- Z+ Qimport numpy as np
    & V/ ~1 A' o7 O, a1 S, K
    5 A* q& w* X6 a& P. Q
    4 d6 M1 A& x5 T3 g( Q% |9 F3 aimage = cv2.imread("origin_png/person.jpg")8 y2 i; F# ?" \* w8 m& p  F
    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
    $ J' a* g/ V6 n) eorigin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    ( U& k3 C6 ]$ E. l( b' D4 \image[:, :] = origin_bgr4 h% l2 J: Q2 b+ k; }
    ' c, c, L6 @# {7 j' a# v
    cv2.imwrite("mask/bg.png", image)
    4 x" l4 N9 ]1 x2 l. e1! h) g' J1 f3 |; r
    2* [( H" P5 T& v9 D% T. y6 j
    3
    " Q& T  ^% b7 m2 F4
    " w: y: U8 z* J5! z5 W* U% C! q* ^; K* q# ^$ N  v
    6" g' t, I) [- k
    7
    6 ?! q+ ]5 U3 r+ l8 f$ ~8
    7 V7 s+ n4 {, A7 Y5 y" e9
    ' k- S$ Z% T1 P: y% Z/ n& I10% r3 h% V+ `/ i9 J7 {$ ~
    9 b' \% P) t) T; r% e; h% _# o
    需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码5 N2 ?/ Q0 F/ |; J
    0 n1 V! E! o8 J) h' Q. J
    src = Image.open('src.png')
      _6 j: s* ~6 Gbgr = Image.open('bgr.png'): ^" ~, O: c0 F2 ^3 b+ x/ j
    1
    6 u& T( z" }4 ~+ k, r9 J2
    / `# F2 l0 X* N4 C) d! Q/ `另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)5 Z' b7 q' V9 t+ s# S$ M& w- n
    ) |( y' x- c5 a3 U& n7 C$ a' a
    com = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)
    % d, W& t4 I! T* N2 d( s" ]1
    / t0 P: u% q6 i0 i# a1 T( ?9 a% Z7 I) a& K7 z& G" \
    那么加入我要换白底(255, 255, 255),就是
    / T8 q9 I! t; A; x5 w
    ) ]% G0 Z9 E& fcom = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)  B& i! h7 c2 I& m4 U' ?" ]
    16 A0 ]$ c3 I2 X. x4 l

    5 y5 e1 h1 J! S, g0 `1 i6 W假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是5 [3 g  I% t2 C, R

    # U" s* \$ q2 T. @2 e  o, Icom = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)
    ' ~' I+ q/ D4 N1
    7 e8 A& V" c! |, M总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.
    7 P. t$ U/ `3 t2 `' h: X! [  p6 C6 B; {; o4 E
    然后就输出图片了。可以看到效果相当好。不愧是oral。
    : C5 b( k4 ~8 T* X6 Y/ ]
    0 t% i! q$ L5 N+ ^2 F4 s
    + ^" L' I' p+ _0 ]4 y1 z原论文可以实现发丝级效果  O' B1 k$ z: J# Z
    ' c1 T* f& f: M" S( s4 b! T
    & B& l* k5 f* p$ V
    , B4 _6 Q* t0 _! W( r/ v

    * U& S! Y5 c% B, J1 J# G
    ; W% W- D8 d5 _& Z; Z0 ]报错解决方案- B% [1 i  ?  z* }2 `  Z% ~& w8 I
    can’t divided by 4 / can’t divided by 16
    " u) Q/ m- L5 N8 r, V; u! H由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。4 ]# M' s9 H8 x' `
    这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize
    $ o# a3 H+ s, T8 p  m2 M9 L————————————————1 y( A* x2 B. Z$ F" b# T' P
    版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    : M' a( g: T0 X  @- ?7 `, w+ i原文链接:https://blog.csdn.net/weixin_43850253/article/details/126376767' s! C, G* g1 l& A4 Y! I. U
    ; [" b3 E9 u* x& l* P& x# q

    $ K% ~4 X" `! x& x$ T, h
    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-24 19:36 , Processed in 0.729749 second(s), 51 queries .

    回顶部