QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2087|回复: 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将红底证件照转成蓝底2 B+ I& g0 i6 t
    前言0 G4 b8 f, w- `
    emmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。
    - t- }2 F( x' R3 n; l6 j
    5 }5 j5 y, _! u4 u& p) K, `" k5 j
    % L" R' w, A; H4 X
    ( G5 I8 a9 R3 h5 b0 Y' V3 ]6 {+ y8 |& C) e( k, d- q9 ], s
    方法一: lableme
    * W7 c: T; b: e4 x3 Z! q) |lableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.
    3 X" Z) [6 ^7 M3 N
    # ^& w. ?& A0 w6 x# j# 代码来自 https://blog.csdn.net/hello_dear_you/article/details/1201301555 d1 J/ D: A( t
    import json
    / Y* t6 q7 |' @import numpy as np6 ^- i) Y$ z9 m
    import cv2$ \: c0 d% |( \2 Z$ @- w
    # read json file; }5 L0 `( Y+ A$ M8 T/ r2 j9 R2 ]
    with open("origin_json/mypic.json", "r") as f:
    * r; Z3 }6 d) H6 m    data = f.read()
    & K" v$ y8 r$ P: F& R8 C( {
    ! e" ?* {% _$ n; X; V4 B# convert str to json objs; C& k& ]3 |% z: z
    data = json.loads(data)2 R; W. |7 i4 m, |
    8 q5 a5 n& e( x' F
    # get the points
    7 c9 B6 W; c  N1 ?3 J8 N6 ppoints = data["shapes"][0]["points"]' P8 ]( @2 j3 L% n/ s4 ]
    points = np.array(points, dtype=np.int32)   # tips: points location must be int32# o3 M  N: J# I; |

    # q8 t# h7 @5 A1 a( q# read image to get shape0 j! B$ L! s( m( _6 F; Q; i
    image = cv2.imread("origin_png/person.jpg"): B5 e) ?" X6 T, t

    & V1 Z1 ^& ^- N+ i& }2 \# create a blank image, Y3 }0 t8 ]% n% r
    mask = np.zeros_like(image, dtype=np.uint8)
    7 \2 \- w7 N/ {5 K* }3 R
    4 m- J" x* d& x; f) @3 z# fill the contour with 2551 ?7 t; g1 h4 L3 n6 G2 G- r. ]
    cv2.fillPoly(mask, [points], (255, 255, 255))! R! R" j" d' l% G" @2 |
    ( B4 A7 d$ h4 P7 H
    # save the mask
    ( d4 f9 D. Z$ @3 N) ^cv2.imwrite("mask/person_mask.png", mask)
    * H/ F2 x- F# }) L, _% u$ Y9 E1
    2 e; F" H0 z' {% A- J( H# l2( }1 b5 _9 H$ ^0 N! \' k* r
    3
    : o- v6 `0 \: b4
    ) q5 S7 ]% [! B5
    * v* s7 {# L. q; F68 V% b; X( E! Z: k  x
    7
    8 ^5 }9 ]% p; o$ `8
    $ _( L/ K' W' R0 S9( m) V2 @; W1 h% ]) E3 k
    10
    & }" W3 @( D" {7 w% {; V. Y8 B11" N8 y. V; N5 t7 W: I
    12
    : i% |- x+ q7 ]! @, v' H13
    + @$ [7 K1 n4 c; w14
    2 L- A. S. Q1 n: S# x; M- \15
    " D3 e3 A$ R  @7 |0 W7 f166 a6 J9 n8 e1 c+ a* `0 K
    17
    9 [4 x! X' x: s; Z5 {. y* y/ j4 D18' y7 _& Q3 k& t6 c0 a* J& w' P  s
    19
    + K3 g0 t0 V5 ?) L6 n20  L0 g* A6 E" |* {7 d( w
    21
    4 v* n& w% ^( U9 M! G22
    : `1 B0 P' T2 L" f! w% {8 K238 t, o* r; z- c  g6 b: S6 V
    24
    $ t2 q* n  T# o257 f) S* f4 j& K/ s7 q- }; q
    26* F! ?6 p1 r5 n5 k/ n) d1 U9 f
    大概是这样:: V5 D8 o4 g, ~$ g
    ! l2 a0 w0 f8 ?" V. I1 [# U- c
    ( S) l; v9 l, g5 P- F% Z: U# Q
    然后利用这个mask生成图片& L+ K3 E, a! q+ ~: U" I9 u# D
    1 N; {  t/ R$ ?8 A/ \# f
    # 参考自: https://www.jianshu.com/p/1961aa0c02ee# ~6 K' e% o% S4 x
    import cv2: A! w" [3 A. {2 r0 h  C
    import numpy as np
    + d$ E; _; d3 W& S9 B6 O% T+ T/ ?& G+ p
    0 e' D3 M$ a0 C; o
    origin_png = 'origin_png/person.jpg'. B1 z8 v& s) h9 I
    # maskPath = 'mask/person_mask.png'# n& b$ T7 O9 l2 S4 @8 C
    maskPath = 'mask/bmv2.png'0 T+ P( j. Q7 X# F6 T3 {2 v) `% n
    result_png = 'result_png/result_png.png'9 M. u% U6 y* A) E8 h. l
    . {" c4 W) F$ w
    4 v' ~: ^3 ^: P$ M  j4 Q
    maskImg = cv2.imread(maskPath)' x* G! ~4 y; N' e" ~+ X3 F% j% Q; V
    img = cv2.imread(origin_png)
    : S0 w7 V. I  {' w3 F0 Bassert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'$ }& |. k% ?5 x( Z
    $ P' O/ f4 ]" X  `+ I, u
    h, w = img.shape[0], img.shape[1]0 s7 g) m$ Q; v, ]" a* a: Q
    print('图片宽度: {}, 高度: {}'.format(h, w))3 F7 q" [9 I  m$ {4 t7 ^
    ; J1 e* z' q8 h# j
    rgb = (19,122,171)
    4 K; ^& k) E& g$ g- nbgr = (rgb[2], rgb[1], rgb[0])
    0 _/ m" E9 k6 }3 |( D  Z# (B, G, R)
    ! G( ?/ ^5 J$ x% O' ~, Xfor i in range(h):: B' z  O6 o( I, M
        for j in range(w):
    0 J# M. o; K; k* N; i3 R8 P        if (maskImg[i, j] == 0).all():' ~# r; K, @/ w& _' ^* y
                img[i, j] = bgr$ L7 ^5 I. F. U" O+ ~; Q# q
    cv2.imwrite(result_png, img)
    0 i( {- o9 E0 ^: a9 _, \% a# {print('图片写入 {} 成功'.format(result_png))
    , Z" A, F4 [! @0 Y1
    1 m. {# K2 c) F  r2
    4 d1 V1 m: R, }3! d3 J  ^3 |% j' C- ~( k
    4
    0 s& H5 K- V( `' _& r# j5
    - m7 J8 ?' D- U, ^8 o0 L6 L6$ K0 S4 M. a2 Y" ]0 j
    7
    + }0 N; n7 h/ ~  _- K! a3 o5 _* O, `82 @5 U$ I. F( J+ u! @6 ^
    9
    + w; h8 A5 |& k9 B, o* y" M. v10" A9 z2 Y3 g  l1 }! K* B
    114 Q( V+ D5 j+ U8 }
    12
    5 i! e8 I. I0 E& Z1 c13( @+ ]% B  j. ^& J3 M
    14; }# y2 A8 v% ^
    15
    . W3 Y% @7 z! R3 v! ~16
    8 Z$ e7 a4 ~+ U- ]; ]/ u; z$ V* @17" h2 U. u" _7 V
    180 a0 E: f0 l: t3 m/ d1 N
    19- w/ ~# F4 m% u1 ~. e
    20
    8 z- ?4 W6 M7 V; k' M. h21
    # e. v2 Z! O+ R; v0 w222 D5 u6 |& s# B$ p# m9 @0 K( T
    233 e. [# j4 E! L0 K- @
    24
    ) |% M/ E& p0 C7 d: f$ x25
    # B" q- E( c7 g6 d26$ x0 r& C/ C1 a' {5 X  X
    277 N+ }- X* O; {- Y& W& o
    由于人长得一般,就不放图了…( m! I  ^# a' a" ^

    0 V3 m2 j/ L+ I, w9 p9 _缺点:( ?( d) [& k1 W) v3 Y" L3 y
    lableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。5 S% r8 }; q5 `+ D1 j. E1 s
    + V* A: L5 P  p  [# P" Q$ i% m
    $ R" W6 ]! y: E6 T& Q2 V& F

    1 j, S* U& F. G/ A9 N% s5 w- m4 Z$ }7 l2 [; t$ G% X& T
    : Z3 \. ?- H6 ?
    方法二: 阈值; i1 l5 _5 }! f" Z; F" [& E; F% p0 D
    该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。+ d& }/ T' H& k% p

    1 k5 c5 H* m, WOpencv$ t: M. n7 r* B
    import cv27 d1 `+ R: h! V7 q  a. y
    import numpy as np. ~; Z2 i  U. ]& n2 \& u

    5 H- |" \# u1 A1 W1 S, j) A  F- z( r% j; Q0 t! ^
    def mean_square_loss(a_np, b_np):4 F! p' z3 b5 H* v
        sl = np.square(a_np - b_np)% R! D4 j6 k8 h5 D
        return np.mean(sl)
    / J0 Y; z% J' X% S
    5 }9 b* \& p+ U3 g, S" i5 {2 C* v- M! a/ k) b! ~- x4 D/ w
    def change_red2blue(origin_png, result_png):
      `" A! z2 [. ]- Y/ i    img = cv2.imread(origin_png)
    9 e8 r7 L; X/ T( H
    ' r% N( E, V5 \- m7 U    h, w = img.shape[0], img.shape[1]
    2 t% P/ |+ e2 c/ t# K    print('图片宽度: {}, 高度: {}'.format(h, w))
    ( c" {- b& ^  X8 K9 }! Y
    - D& r+ T# ]( [7 G4 E! b  ~    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
    & D2 b( p& f: J3 m8 z    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])9 E( l9 ~. a% |0 g' Y  x
        target_rgb = (19,122,171) # 蓝底RBG! K3 ^- O# s* O& D
        target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])2 _9 h, Y# {' k0 }

    0 n( [) z3 C* a. E1 }  r    for i in range(h):+ t. g$ Z9 O4 y. \0 _/ z+ Y+ n% x+ y
            for j in range(w):
    9 O0 h' H- W$ f% e0 q' j            # (B, G, R)( `$ i8 n; c3 I$ ~% l1 A8 a
                if mean_square_loss(img[i, j], origin_bgr) < 50:) S& |6 {& q+ \% \
                    img[i, j] = target_bgr * h. z0 G4 Z3 M. @
    ; p; e- }* |8 r% x3 Y* d9 u* [
        cv2.imwrite(result_png, img). J$ ]1 u- j6 C2 v0 `% x" b; s
        print('图片写入 {} 成功'.format(result_png))
    ! C6 N% C* \, l% ^% s# I9 R! S+ p& G6 K1 d& c5 Y0 i3 K
    " e6 [' Q( z4 x' o, \
    if __name__ == '__main__':
    : E1 Q: Q. P# ?. Y    # origin_png = 'result_png/result_png.png'" s1 q6 z9 T0 U9 I5 W$ k& Y
        origin_png = 'origin_png/person.jpg'
    : w- e: |7 Q* u0 N$ J    result_png = 'result_png/result_refine.png'6 Z/ x# H# V8 J5 N/ J9 V
        change_red2blue(origin_png, result_png)
    ! S; Z9 Q7 @) _$ g% O10 q+ `0 V6 c4 E9 t, U
    23 q+ {& z% r% g+ Z) x8 ?
    3
    & L1 l( C0 n' `1 S4
    ) H" E% Y+ C+ n5
    6 W3 m. H+ {7 b* f6
    2 I6 Q& g4 w6 d0 y7: M* x1 x/ n2 `5 I$ x
    8- V+ F' j$ V2 ~: [8 e
    9
    - i" B  x3 Y+ z7 O' I10( `. c; V: P3 m* O
    110 ]- Z6 h7 a9 [2 N7 d0 U5 h8 p
    12
    4 W8 r7 R, e) B5 f- I8 J8 N135 a$ }' h) _" I, Z' y
    14; c$ w% Z' f+ X, y
    15
    9 t. A; r7 M" N. U5 l6 I; r16; y* B5 g" B# }5 ^9 t- H
    176 p* O; k- \' O1 L7 b) p# \  h: J2 n
    18. y' V; ]! u$ g/ H' p# l2 q" ]
    19
    9 Q- o+ t5 P" j8 X207 L1 v2 }( t- E
    215 P6 ^, `% W/ P9 ]% a% g" v
    229 }) X) z% ^0 ~; u# Q! i
    23
    9 [9 W) y' B; A. x/ B24
    3 A+ x& ]; G# u6 R% B25# l  z! w1 y- Q) E& f4 e! e
    263 W8 U9 p9 r& F9 a5 m
    272 Y$ F  s5 c/ U0 a4 o( J; m) T
    28
    / k0 O" ?" b1 K1 A" D. w, x1 E29& T$ j& E* z2 a. c
    30
    5 n0 _. l+ a( ^! M" ?31
    , A5 m# z$ u1 `4 q' A  _32
    . h: @6 F" z6 U7 e" y/ }33
    ' a& N  G! h: C. K8 t34
    - i* H7 n0 P2 A# F( v- I35& m2 ^+ A2 I5 |8 U) W
    结果人与背景边缘仍会存在红色像素残留
    & a4 H; t) c. X/ Z. g& a
    ; h$ H: F9 r5 c; J; a7 B3 q/ M8 Z; j! v; v+ t
    0 E1 ?3 |* l7 Y" r  L

    9 K$ J, a- A; d" b  t1 v* m
    / x5 b7 u; @5 t0 D) s8 [$ fPIL
    5 w2 J7 i0 b8 j7 Afrom torchvision.transforms.functional import to_tensor, to_pil_image
    : L; U) T3 J/ T1 |/ v* X: S! Yfrom PIL import Image$ V) R; U! T8 W6 Y( A4 A
    import torch6 q8 B5 t7 P- `8 a. j# ?. t$ A1 h
    import time
    . {. N+ R6 E  j5 w1 _
    7 S, t6 K$ ~% ?' M) n6 f# c9 ^7 i) v$ {, F: O/ F( j+ C
    def mean_square_loss(a_ts, b_ts):
    , _( n6 S* y0 ^6 m: O    # print(a_ts.shape)+ I! O7 e$ J7 D
        # print(b_ts)' f5 i) w( U( l+ k
        sl = (a_ts - b_ts) ** 2" M' b5 Y" F9 m/ T; [: S
        return sl.sum()
    0 ^3 d/ [# f. I( m
    ) N3 [" ^) |8 t6 E
    9 A8 ]( T. o( n9 t* Qdef change_red2blue(origin_png, result_png):
    1 C  U% F  ?- S: I    src = Image.open(origin_png)
    $ m9 c4 |4 I; [+ F, D$ ~1 ]    src = to_tensor(src)
    . z  @/ q5 u6 B6 a( z    # print(src.shape)  # torch.Size([3, 800, 600])8 @- u9 V) P$ V$ j
        # channel: (R, G, B) / 2555 `; Q  k* Y$ K5 O, _
        h, w = src.shape[1], src.shape[2]
    4 Z; R' ~* k+ ^' j( @3 g3 j
    1 `: _/ P) X; C. t) Z    pha = torch.ones(h, w, 3)
    8 N6 `# K2 Y2 a: \# ~% q
    ' I7 D8 f* I. V6 q# M, @" O    bg = torch.tensor([168,36,32]) / 2559 b( P# b9 P, e8 Z' z8 O
        target_bg = torch.tensor([19,122,171]) / 2551 [: g- @* N) L
    : m0 ~: r" s3 t6 v1 Q
        # C, H, W -> H, W, C
    : b$ v( U: C, j- |    src = src.permute(1, 2, 0)$ k1 U: K; E! P
        for i in range(h):
    ) i  M0 r$ [# Q. V# D        for j in range(w):
    7 M! A- Y9 @6 T9 `) C: H! j% j            if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数
    8 N' N% M  h' W$ `2 k1 P) e1 P2 m0 Q0 O                pha[j] = torch.tensor([0.0, 0.0, 0.0])1 S6 {% C# P0 |9 I# V
    # Z  M$ U/ U8 L  h3 J3 U9 P
        # H, W, C -> C, H, W3 O5 e$ O8 c6 s& C
        src = src.permute(2, 0, 1). c, c. k5 C9 a- z9 F- X
        pha = pha.permute(2, 0, 1)' c7 I3 G# L& K/ ]1 w( \( z( R
        com = pha * src + (1 - pha) * target_bg.view(3, 1, 1), z7 K, ~9 s. G) z+ \( C3 j
        to_pil_image(com).save(result_png)
    ' B9 S% x/ t3 z8 S; h
    3 Y4 |) g8 z: B& {: m! }  o9 y1 Y& ~* J4 p* Z3 N4 P
    if __name__ == '__main__':: _* y7 P- [: A9 w* P" r
        origin_png = 'origin_png/person.jpg') W# y  ~$ r6 g' I
        result_png = 'result_png/com.png'! q) Q# t7 M  A
        start_time = time.time()8 M3 v% l0 A" L: T" r1 S0 K
        change_red2blue(origin_png, result_png)
    + d% q$ O& {5 ^8 _1 D& ^    spend_time = round(time.time() - start_time, 2): H, G3 ?% p, z% t2 Y  b& L8 l8 f
        print('生成成功,共花了 {} 秒'.format(spend_time))
    $ v; p( F6 @8 ]13 w4 K5 ]$ J4 e
    2
    3 Z" i% M+ Q: ?8 V) R5 ]3
    # A6 k4 S# X0 ^# _$ W4
      O. i3 {! w- c# a) O6 R  B5
    2 [0 S/ o( @9 ?1 {6
    : E5 t* k& Z8 c7 g9 \& B& k6 [4 x7
    + ?7 m0 h7 R4 @- H3 @/ }8 F8
    7 R, ?8 L( q4 h5 G6 F$ c9
    - s) s7 L+ o+ N) }  v10
    % B' n4 j6 V# h/ ^, }. n. J11& k* T- p. o+ J# n! W* G
    127 V" N3 ?; N6 o6 ~  t
    13
    0 }4 B3 n- e6 z5 I142 D" R+ E& d# H0 n
    15* \0 y& [  F' t0 I# l3 b
    16
    2 M7 W% Z; ~% [0 Y  A5 g17
    % z; M% b5 @$ c5 e, w7 U# G18
    # V: n. U; _7 M) K. P! C; E# L# k( b, Y19% `# o& W( p4 {9 A
    20
    2 F( J' X0 I( p" a# G  ~218 [( Y- h8 z+ i; N# ~
    22/ l1 W5 d  _3 n% {2 E! ^; d
    23! V; \0 A. X2 h: f  g7 @
    24  z6 P! U" I8 U1 A; R
    25' ?: p$ B8 U3 q# r, `! h2 _2 `! L0 y3 G
    26* H. T, Y6 m; `
    275 I2 ]+ ~4 r( ~8 u
    287 T% Q* C8 @1 z+ i
    29% x. A9 _+ f! e
    30
    ' f2 G$ j, [4 P  T6 A31/ ?  y) a7 A6 Y3 x
    32$ h- D3 H: [7 z
    33- j! x  B, K( n. U
    34
    ' m! ]9 e" e7 V. i/ T% X& L& M35. y6 d6 {/ ]" J, `- F
    36
    " E( i9 o) C  o+ f- F: g374 @) B' d: z. p. b4 q
    38: y1 Q  {& x2 V+ n* w
    39: L/ C2 H% R' ?) A/ R& [
    40
    0 A5 f% Y. V/ A( ^# f# t7 d41
    ( a* F! {/ A: K* q423 U4 u) a4 w2 @3 \% C
    43& k8 m0 a, p! ?1 i' l
    44# _" Q$ v. ]; W' q/ A6 w
    45$ N+ D6 _' w+ ^+ Z
    46: c1 M. R% s, N0 f/ L2 S. |
    该方法质量较好,但一张图片大概需要12秒。
    % T- z& s' _" @# W) A$ I( r
    ( A- o7 l( b2 P: ^3 U' H
    9 x+ @) ?- u# N2 I
    & \' o5 Y& j# z4 L8 v' l方法四: Background MattingV2
    . S5 Q$ J7 J: cReal-Time High-Resolution Background Matting
    * I3 g, s7 w1 h( o5 L, a% xCVPR 2021 oral+ }8 [- ]+ `- ?& `% Z

    / i/ K4 O% _  \. Z论文:https://arxiv.org/abs/2012.07810
    ( p2 r! _) ^' q( D6 T, h代码:https://github.com/PeterL1n/BackgroundMattingV2
    ! j0 H1 D) ?! |2 e" f8 [8 V2 E
    2 c5 t' A, _3 w6 E, R. d0 Ngithub的readme.md有inference的colab链接,可以用那个跑
    5 G* }+ u# F4 {" s$ l# H" C/ |/ U- n9 b+ t  w5 d" j
    由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。1 p! r3 c% R8 ~1 e- J3 A6 U/ z4 a
    4 C) f; w. a; z! b
    于是这里我需要生成一个背景图片。$ u" K# s. x- o# A7 t. [
    首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。: F( J4 f6 Z3 X- r+ W7 H

    5 u) D6 X! d4 J然后生成一个背景图片。
    4 I. }' \( I) _  X+ U+ p  n7 i3 Q5 E2 b
    import cv2
    - E" L5 T' w$ P# c0 i* Y" _# \import numpy as np
    ; _8 F/ N+ a2 p  s) I, e: L  B! U" ]! i+ f$ v

    ) t; i% I0 B; k% q# Kimage = cv2.imread("origin_png/person.jpg")
    3 O, I8 C, ^# Yorigin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值1 E  S$ S$ G0 u) ~5 _3 [: u* {& A
    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    ' |5 \' J9 ]* G: s4 yimage[:, :] = origin_bgr
    5 v% \, W, E" ]) z0 t  I- K
    6 Y  I# `0 f$ x0 F: lcv2.imwrite("mask/bg.png", image)1 `+ p3 K5 \" z
    1
    + r& M1 T. A1 K1 ?8 @2
    ( ~3 A. F7 B- {8 E3  z% @7 ^% t7 Q/ V3 ^4 \4 [
    4
    ) q- F" V! R* z& s5
    3 e0 `! J- m3 G# `7 T" c' U6; I$ C, m' ^9 A
    7
    + g3 D" K9 a3 S! [/ c# d' c/ Q  V) [8
    ' U  x: x7 n( p% H8 b+ W/ H9
    . O8 t- _* q) w; G, O10
    $ v8 g$ R8 g0 ^3 e. J  m" E7 w/ v6 ^' W* z$ ]4 @. N% [
    需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码/ m9 w- M  o. z/ U- M
    / F! z) Q+ S  L; m
    src = Image.open('src.png')! ^  h. b( F2 U$ y$ ~& ~
    bgr = Image.open('bgr.png')
    ' X2 M; L+ a% g0 Q( q- M) a- ^1
    7 C0 ?: U" `' y2" ?1 ]$ ~. R$ K% Z
    另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)# Q: u( k) e: `% @

    2 c  a# a! M6 O& Scom = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)
    ! Z, ], q- p% |; D1 o1
    2 ^7 g- I. r9 \; d; F* Y9 c! S+ s3 J+ \9 p3 {: M5 }: w& L% S
    那么加入我要换白底(255, 255, 255),就是! n* t4 f  {7 c3 Y4 m+ @, Z  @
    5 @2 G$ y( l+ W2 Y1 u
    com = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)
    ; ~& y; O3 X- ~: s" b11 w: j4 ~1 h$ _" }' S6 X7 g
    ( D# O, e! G; R8 J. l
    假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是
    5 ]5 j" n8 R! `* ]& H8 t4 R
    2 B7 G% ]6 }/ ccom = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)
    . G0 |# _9 m# p1
    * D  T5 k+ h3 i* F& T# E7 M1 e" }总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.
    , b) z0 X# n" V$ _8 @4 }2 w- Z+ P- W/ R
    然后就输出图片了。可以看到效果相当好。不愧是oral。
    , F$ A. M+ C% t/ A) t2 ?* [' q4 z1 _( O

      D0 D! a" m" q8 F$ b/ R5 z原论文可以实现发丝级效果6 p) P( `. q. O4 m, A

      ?5 ]0 f: m9 t- T
    ' L# m; X3 }' P; y# f
    + M8 L8 ^# o6 j4 o& ^, a; f
    . L' u1 z3 k* ~" ^# s3 Y5 {3 E
    ' x) y, S) f8 ~  H6 Y报错解决方案
    $ T" H- R, M5 xcan’t divided by 4 / can’t divided by 16
    2 G) ?( {* Z5 X0 J0 X1 P3 C由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。/ ~; W* o! N/ s( b/ ]  `5 X( Y
    这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize- u6 o# d; t. c9 ^
    ————————————————' C3 i  Y! }2 r8 b
    版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。: v8 B0 j/ A. d' _
    原文链接:https://blog.csdn.net/weixin_43850253/article/details/126376767" K& Z7 J. {5 C
    ( y, `9 K( B, w+ q9 X
    ' w  k& f) ?$ b$ ?7 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-4-10 17:26 , Processed in 0.604371 second(s), 51 queries .

    回顶部