QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2124|回复: 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将红底证件照转成蓝底
    , z/ j' ~& M& Z) E- I7 a前言% K" K( F% i0 i& H) w
    emmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。
    * V6 P4 u2 m; V+ p# P' i" ?0 Y
    0 S, F1 N3 K& a2 U2 k9 S5 B  I% T$ ?4 ?

    * x6 o4 X' c, M( l
    # c9 ]; A  b) W- Y" D方法一: lableme
    ) R0 |; O8 y5 X. f7 R* j# A' Glableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.! |. m' M; X9 }7 c

    ( R4 O4 L) T+ S; k! G# 代码来自 https://blog.csdn.net/hello_dear_you/article/details/120130155
    ; J5 y5 b+ X7 s1 a4 rimport json6 L* G3 s. w" ~) W# W
    import numpy as np
    ( d% g, m/ i7 |% N, Cimport cv2
    / t  j& ~. g6 L' q# C1 h  y# read json file
    ) }8 F) r8 Z  ]# i8 mwith open("origin_json/mypic.json", "r") as f:
    ; l' }/ |6 D* \' y    data = f.read()
    . r" ]' _1 W9 y! N: x1 ]! B2 h" K# Y3 N" P( r
    # convert str to json objs/ U  r6 O0 \- J* e7 X( v; n
    data = json.loads(data)
      C: O* k" V2 K# n( y: ^: b2 o9 V6 M9 V% P/ r% d' X; l
    # get the points - D8 {* p* P; o2 q* L. I& h" G
    points = data["shapes"][0]["points"]
    ' }  J* r5 J9 G7 ~# ]" w6 ~# hpoints = np.array(points, dtype=np.int32)   # tips: points location must be int32
    8 E- D  [$ p) p
    2 y5 l3 S& ~* D) x/ I7 [# read image to get shape
    % @' O- p4 P6 s1 m' Z1 n. B- Y. Pimage = cv2.imread("origin_png/person.jpg")
    4 d: h3 y5 G/ `% z/ K3 [5 G/ x8 ]7 e' h! k! q5 v' ?% ]
    # create a blank image  M: M1 [4 ?" X: _4 }
    mask = np.zeros_like(image, dtype=np.uint8)
    % P' ]( D1 i( H' T: f" Y
    6 R( H' D4 D2 g% z& d# fill the contour with 2554 z0 O; s- r' d* u3 R9 @& h& j
    cv2.fillPoly(mask, [points], (255, 255, 255))4 A& @/ u4 x2 C& P+ i2 Y( k
    . ^% b+ F: K  k1 S7 d2 R0 E
    # save the mask
    ; _8 d+ W$ d( X5 S  N6 N1 z6 w9 _cv2.imwrite("mask/person_mask.png", mask)
    $ ~* R8 ^( h1 p: U4 y- D1
    * H+ H# f' j9 x3 s2' I; D* R" G! Y$ r7 ^
    3
    & x  \0 T, e. d$ _& V7 E$ T$ x4 J4) U' T4 G9 a# _, W4 {7 ]- E8 f2 t- O# }
    5# j! E, `; Y* D6 N9 l
    6) u" j* d; a/ |# I. ]! f5 I
    7
    ) S8 p/ X- h/ ?; ]87 n1 l5 L7 b# U9 a# j( r3 G
    96 x* z6 b: I# X3 v9 |! ]; k
    10
    0 U5 V! w5 _# b% z# |/ p: C11
    # [9 L( V3 w/ O  l) z+ H4 Q' W9 y12
    % t) N! U3 \! L! B13
      W: L: O* q& `7 b9 i14- O( X3 Q5 Q" h1 z
    15- v! |: D/ e* Q9 `9 F( D- f& R
    168 t! g5 _$ ^8 }; z
    17/ L8 X* A& [% Y
    18
    + l9 d& U2 O2 s191 a! o% U2 x. a. ~
    20" w& X2 p. B4 p) e3 N- l
    21
    8 `% M0 h2 ?$ D9 ~1 P22
    7 z2 C8 p, ?" b$ \! q23- ^% d( ^, E& L% i  \4 M  U
    24
    7 O1 R1 M  A! Z25( p& t" c" ?- z( S- g
    26
    1 R8 J6 ^7 C+ x7 s  D; a4 A# p大概是这样:" q: P2 s+ A$ o" I) u% j
    . }. ]* g7 M, u6 p
    4 l8 ?# e+ O, ^; I6 x% |' ^
    然后利用这个mask生成图片, c0 G. v4 ~( R8 ]6 c

    $ }1 c; a) u$ q4 R# 参考自: https://www.jianshu.com/p/1961aa0c02ee
    ! n! T  Z" [8 J' \import cv2
    # t4 Y0 T/ f" S; n. oimport numpy as np
    : a/ |4 q" [% \* T) e, i; q/ ]+ H$ V* a, C( H" \/ A) h# m0 Q
    4 ?' b! f5 `1 N* h
    origin_png = 'origin_png/person.jpg'
    . Z; [3 [0 k! ^  z5 W: u& e: F# maskPath = 'mask/person_mask.png'2 o- {% W) f" ]3 t$ O
    maskPath = 'mask/bmv2.png': N0 D( `' L* j8 {  E+ \6 A
    result_png = 'result_png/result_png.png'
    / G. b' y& d+ N# O0 ?- g9 K5 f# z  {2 f$ C! w* |  L- q

      R; u& P  F5 W6 X. ZmaskImg = cv2.imread(maskPath)( X- f7 s' J# W7 t, e
    img = cv2.imread(origin_png)
    $ i* S5 s: {2 L5 L# Iassert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'
    # T& ^8 u. i. O$ @$ o3 i& ?# }
    4 U5 {+ A9 m( o' P' Z8 {h, w = img.shape[0], img.shape[1]5 [/ s+ F2 w6 ?
    print('图片宽度: {}, 高度: {}'.format(h, w))
    # Y) U% h% e! E0 ?# {2 V4 V
    / m0 m# Z* _- N) Brgb = (19,122,171)0 S" U' O- k2 d3 r4 V% P2 z
    bgr = (rgb[2], rgb[1], rgb[0])
    & R. g# }+ R9 \" k. o0 g% @: ~# (B, G, R)
    ; {2 I% ]/ b) g8 ~( Bfor i in range(h):
      S7 K' Q1 Q; P    for j in range(w):
    0 U* P* `$ v# e        if (maskImg[i, j] == 0).all():
    3 _7 ]! w5 y) V) k3 d$ X' n            img[i, j] = bgr, O/ D+ w! A; ?6 |/ O+ E1 [
    cv2.imwrite(result_png, img)& l: ]6 m1 `2 Z, a6 {& T
    print('图片写入 {} 成功'.format(result_png))9 L. M3 W5 b  R3 d8 K
    1$ z9 W& ?2 z* @7 D9 {, m4 b
    23 n5 E& o! k6 d! ?+ g  ]
    3
    0 O# M& b% ~& x' [4
    * e. G, U8 z: n4 F9 C9 M) [5# n2 n& R: \' E  p3 S
    62 T8 ?5 K5 r! k2 d
    7$ \0 A- K7 c& n+ \7 C: L
    8! v/ |1 `, \8 t& U) L
    9- F! o" Z& J  I, G! R9 z+ f
    10. Y% T8 {! r$ n  h- E0 W
    11+ ~% N; \' p0 M
    12
    * y" ]" ]3 L8 F( d13
    4 J9 y7 F  N: c4 X9 ]14
    & ]' N5 V. }0 C) C# J) z) q2 F' A0 s! R! P15
    5 n! a# @2 @# l/ _/ v2 _6 E16
    8 c3 D. r  M6 J! C: L17- N% N* R+ o2 y0 J! q) K8 h
    182 S% K7 R  j6 G; d+ d
    19: F1 J7 F% v# O$ i$ m( P5 o' F
    20# G* L9 Q2 _2 D9 W: U- d
    21
      M; u# N9 O. N9 |1 K" V22
    & Z. r6 a9 a. Z9 b/ @. Q9 S23- B; P' ]4 t- I2 k, Z9 e$ J' \
    24
    / X+ y' s4 E% c. b) ^25" x/ i8 y& N; i3 t. j
    262 H" O3 O6 H- s+ `1 z
    27
    - c* ~- }! G% ^! G, e由于人长得一般,就不放图了…- p& n, T  e* @4 N  @

    + Z7 A. d0 K% Z1 R, I, y缺点:
    3 ]- w! R* Z: S  [( _lableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。
    0 i- C9 W3 Y2 `7 s& G) _# G' O0 _: I9 q, l7 P+ S4 [1 G4 ]

    1 d6 h7 ~- K! i& S8 m, z
    , {7 b% H) k! R" g& F. X' N* x* q9 h" A1 {8 O" V8 l. l

    / S! ]3 k4 W  {2 m& W- C, G方法二: 阈值" i" I0 n$ }. w9 L: R; u8 d
    该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。
    . |1 J" n+ R: n) m2 W* o6 O
    , p6 M, c0 A/ xOpencv
    ; ^& u' f8 z- E/ Timport cv2
    ' C! H( W+ k& Timport numpy as np# C: E" F0 p: r
    , n, b6 B0 E, d7 B& Y
    0 M9 W( B8 P0 s; \; w
    def mean_square_loss(a_np, b_np):5 m, _. C; ^1 i4 M6 o
        sl = np.square(a_np - b_np)
    * ^6 D, t: L1 ^; R: R, _) J8 \% f    return np.mean(sl)
    3 |' n$ L0 G4 g# m" C- |% i$ H) D: ]  E9 E$ L% J! E

    ' g8 D; i' V' H* Sdef change_red2blue(origin_png, result_png):
    9 j6 F3 n, I7 B, K9 {; o, B    img = cv2.imread(origin_png)! @6 y: d9 }# X4 |

    8 ?8 m, ~# i2 |' c& l8 ^    h, w = img.shape[0], img.shape[1]
    6 L  U% W1 u  O3 Q1 A( v1 R2 i    print('图片宽度: {}, 高度: {}'.format(h, w))
    ( G' |$ A5 }9 r
    7 Z. x3 x" U2 R5 s6 I1 A7 F( B0 D/ k    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
    & J9 N7 Z. i8 Q- ~    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])3 g4 L" |  u: l0 U) h( B& @  [3 p
        target_rgb = (19,122,171) # 蓝底RBG# A' Y: w' {. A8 D! k9 k6 d
        target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0]), [) K" {7 `1 e3 I

    8 \& s* U/ q, I) }/ H9 a% H    for i in range(h):$ X! E, n% M8 o9 F, j
            for j in range(w):
    # z' F4 `( a) v- y" {            # (B, G, R)
    ! O- q: b* h0 M7 Q7 ]            if mean_square_loss(img[i, j], origin_bgr) < 50:- c" A  C9 e8 k' s" y
                    img[i, j] = target_bgr
      ^. `3 P" q5 B1 D  j' e: l4 @6 r' A
    + a/ ^8 d1 M% [( \# y, ]% d+ \& D* n    cv2.imwrite(result_png, img)0 ?; h1 X3 c3 ]& Y+ Y! e% B
        print('图片写入 {} 成功'.format(result_png))
    : P1 ^  G9 n5 F  x2 j5 u. Q/ T$ J7 ]& k0 S4 U' ?0 u' k- w

      g# X* ]0 }% o. w+ q( I" iif __name__ == '__main__':( W9 L, J( p7 f: z. z
        # origin_png = 'result_png/result_png.png'
      Q* [& v7 z" P    origin_png = 'origin_png/person.jpg'7 o- T$ g, X& b
        result_png = 'result_png/result_refine.png'
    9 y- h, c5 m3 P+ g' I  ?    change_red2blue(origin_png, result_png)
    0 m5 E# @9 _' m+ E) R) x6 |1
    6 H' B/ @8 l. q5 D; K2 V0 O28 q, O; l; O  ~0 k% G5 U6 o) k5 y
    3  {' ~1 ~/ D% o! r* e) g6 v
    46 s; ]9 J; `/ p; @. S% q7 J
    5. s8 ?6 q" l$ j: T3 V8 }3 S5 l
    6
    & S2 S% @) G( X! r$ \7- Z1 f: y, D! S7 o
    8$ g$ D! g! M) k6 u% t
    9
    7 s* {; `; W  ^- c( Z& `6 t* R10
    . @5 K4 h4 U' G- }118 v! b. e( k! {
    12
    7 y( G2 Q+ _3 U7 W+ m) n# N" H13
    + v1 c2 s' \8 W3 G& [- l14' k! q* l" J- d1 c2 Y5 o" X
    15# ~5 g4 g6 N3 `  D
    16; u! [8 l: q9 I2 A6 L0 T- P
    17
    2 T9 w( Y1 _& c$ n! @4 ^- d18/ r5 p' u5 R) f6 H# X3 J
    19) `; }, b  \& H, B1 N9 w) {
    20
    & Q; {+ ?& a) S: A- Q& |21
    - G4 Y- n; M7 [22
    7 K5 z% G: k7 s7 d23
    1 `- p, h0 i7 |* A# y4 k24
    * r$ g* p8 B% i' k. J/ [# v25' o% x; O& o1 v  x
    26; y1 r- `, [- ?6 a; M
    27
    0 N: t7 y' a, `  i/ j- b6 p2 u28
    0 K, X) \$ D( L# W4 Q29) B  o/ Z. t  E2 H1 N3 ?
    30
    # V: M1 c' m) L( j; e31
    . x8 N# I; R! \! z# j- @9 ~32+ b3 ?& [- C& J8 l% {1 G4 F
    333 B, Z  i$ g1 D5 W
    348 M/ @/ m0 l8 M" Y' T1 B
    35
    ; R, ~3 C3 \/ E结果人与背景边缘仍会存在红色像素残留/ o' \% g4 {! x1 H
    7 I2 i+ C: b. X
    7 I4 R- P2 P: C
    % g! L6 q! }) P
    0 G* C8 k8 M2 ^% y' o
    : L; p8 M2 ?3 y* J+ B
    PIL
    . m% d$ _! H& C" E1 Y. I1 Q1 xfrom torchvision.transforms.functional import to_tensor, to_pil_image1 G4 \1 z# [" C4 J
    from PIL import Image
      H5 h4 S( {, j9 x0 F+ aimport torch
    6 E- k6 J' S: G7 g. K1 N% Iimport time
    + u+ {1 _8 A& B3 y
    % o$ r9 [3 b2 d1 z/ `( E
    ; e; U. |8 w' M. [% A; H; d9 J  @def mean_square_loss(a_ts, b_ts):" i, {* }" i; s; u2 q9 q) q/ ]* b
        # print(a_ts.shape)0 ]: w- ^  C9 o: ?) m9 b+ ^" G
        # print(b_ts)7 R* ^4 k8 K& r- [
        sl = (a_ts - b_ts) ** 2
    ; N1 ~/ }2 m$ g5 y0 r    return sl.sum()/ I: H5 G/ u, T2 ?/ G- W0 h6 O

      u1 `; m  a& `3 Q8 X3 g/ X. S$ U& d3 D8 a
    def change_red2blue(origin_png, result_png):
    5 R6 Q  |9 N/ n  t    src = Image.open(origin_png)
    & q, f1 h2 ~" e+ t9 b: ~8 E/ z( p    src = to_tensor(src)
    , J4 ?3 K& q; M  _8 O) a    # print(src.shape)  # torch.Size([3, 800, 600])  d+ [; g! }; G3 i7 Y0 a
        # channel: (R, G, B) / 255
    $ ]% x( f% p9 o# _    h, w = src.shape[1], src.shape[2]
    5 Q4 R: J0 V, x' ^
    6 |9 k3 T! v% V% b. f    pha = torch.ones(h, w, 3), u7 T- ^8 y  ^
    , J2 Q. a" U' ]% T
        bg = torch.tensor([168,36,32]) / 255
    2 R3 E1 L. L  g: n$ ~* h( Y/ T    target_bg = torch.tensor([19,122,171]) / 255' ]7 [) y( Q9 K" F6 V7 `1 |( A9 z

    ; w+ A. l+ t" r( M0 y3 J    # C, H, W -> H, W, C
    7 s- T. X5 H$ N8 D/ o! X    src = src.permute(1, 2, 0)' Q& J/ I# g5 x* u: z( L( y$ m6 E
        for i in range(h):1 m4 i% n. ~0 b5 f3 Z$ f& E# v
            for j in range(w):
    0 _# ~  l2 _% t- \: z            if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数
    2 q  I7 Z* c( c2 d                pha[j] = torch.tensor([0.0, 0.0, 0.0])( i& |$ v, i4 j3 w* V0 ^6 r; a8 k/ |

    7 p& ~) i9 A7 G    # H, W, C -> C, H, W
    ) Y/ a; o$ ?' g. B    src = src.permute(2, 0, 1)" F. _% p  p3 L. M) F2 A4 ?
        pha = pha.permute(2, 0, 1)
    6 ~' W$ }7 l# J3 q$ w* s    com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)
    ( }8 Z2 q1 Z; {* b( T( \* w    to_pil_image(com).save(result_png)0 g4 S6 v5 r9 ~# S) [: V

    - M. o& ^$ b6 T1 B" x7 `, M. \& j1 t  g
    if __name__ == '__main__':3 f$ i% I, f/ B9 d, @) C: @6 p
        origin_png = 'origin_png/person.jpg'0 q# H- M$ m0 l! s* R
        result_png = 'result_png/com.png'
    2 ~6 D2 P2 s' Z- t. R    start_time = time.time()
    , y8 T& K& ]& v! ~, B' h6 b    change_red2blue(origin_png, result_png)
    - E) b! Z) u2 h9 V    spend_time = round(time.time() - start_time, 2)
    % L- {  U9 M8 \    print('生成成功,共花了 {} 秒'.format(spend_time))
    % z3 ^2 e! W6 F& L6 [1
      J& z- M" `- C1 h  d$ O8 J20 f$ S0 I$ k/ }% u+ N( c
    3
    4 s+ @2 i/ m! A. W+ k; v4% s3 J' x: W3 b- Q" k& z) B
    57 _$ h/ V; v5 I1 {) j* W. z) o9 k7 k0 ~
    6( [' P8 M3 y% l) R6 y9 l& W
    7
    . e& x0 T  k4 u" z1 w8
    % O. ]4 v1 h6 N2 U9
    ; I2 E$ P9 y# y  I* P. v10
    ( K7 D3 I+ s7 L  D11
    ! b6 y7 m8 N- ~8 `4 Q6 b$ u1 p12' |0 c) X: Q) H* [6 w
    13
    & c* m. l- X, |14) B- g5 U  O- W5 f2 D$ q
    15
    ! S3 s4 K9 c3 l+ X) F  Q166 K# t: \2 y9 W
    17' {$ I! o( ?2 E+ O% I
    18/ A  b# f3 ~. r6 _, j
    19
    . w. ?% Z7 G) t- Q% m+ _6 b20
    # C# e4 ]0 i0 |6 s1 Q; I+ i" H21
    8 B; o# A+ n; @1 s228 h0 y8 X- v' I9 q! X8 U$ U
    235 Y( h8 C' V( a1 g2 w
    24
    $ W3 B$ I: K: V1 c6 M25
    ! H+ N/ S2 X) j  Q; m* \$ y9 N: l! Z8 h26
    # N+ G# G/ J/ z27# @5 R7 Y+ U3 c9 c. P8 l
    28
    # L8 Y6 I) p" c8 G- T0 J; j29
    1 {7 O- ]; n  @4 ^5 }7 o4 G30( h' g/ C0 Z, H9 z- @! e% \1 |
    31
    & i3 r; Z5 N/ W  S5 v+ T32) R) I9 ]9 F6 J; e4 J  J" d
    33
    0 a8 T& r4 M0 w7 ^342 T% S* m. Z1 M
    35
    9 w0 r: l  x- C9 \; x0 g2 K. f, S. e36
    5 @4 |# J( b( q3 T37- T+ Y- p1 _- P7 s% p
    38( M5 p" U+ z3 g2 O9 Y8 R
    39
    6 ^8 m8 _5 o5 ]* U40
    ' t' s3 I0 h# b: C. V" J/ h41, f! Z3 L) F! j1 A3 o; @4 r2 \
    42
    , _; b5 h- ?% _5 x43) b8 X: k  ~+ L* M2 W( y- ?
    44) B8 `! M5 n( [. N# s6 {
    45
    ' B9 O! F8 q5 A7 V# G467 u5 U: v& l* N3 T
    该方法质量较好,但一张图片大概需要12秒。# X" N( j" I, `1 [; A. q$ a
    6 C: @. f$ X1 k% @  `' M/ |

    4 J* C4 P# V5 S8 S
    8 j& o" s* Q- }方法四: Background MattingV24 J. X& F# s& G. ^& H9 K  j
    Real-Time High-Resolution Background Matting. Z7 S5 _' s( n+ @
    CVPR 2021 oral
    9 Q5 N) W6 m. C4 p+ t2 @; Q- I& R9 S& j
    . ]2 u2 {9 r& F) I0 p3 P: U- ^论文:https://arxiv.org/abs/2012.07810
    9 [  \8 f0 a+ F8 D代码:https://github.com/PeterL1n/BackgroundMattingV25 _/ B: c. G* T7 |8 K& k

    " T$ X2 [9 L5 b* Ggithub的readme.md有inference的colab链接,可以用那个跑) E  `$ Q. ^0 @

      f: Y* ^+ Z( A3 E由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。# a% j& p& f/ Y' V: N& [2 t
    # x; A+ m* ^. A
    于是这里我需要生成一个背景图片。
    ) g; h7 J, M! h/ ~  B/ ~, `首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。
    + P  F, D6 N; h3 i$ v5 G" @) N- N2 n; h* v. t. X
    然后生成一个背景图片。' _5 }, _- v2 u) T! b6 s

    # F& Z. g! Q) W- N9 c5 s, zimport cv26 r3 x/ X0 _3 k' l# ?
    import numpy as np2 j' f# g9 v2 h4 k& U1 A  ?! e9 |

    ; [% r1 O" V: }2 E% n& {
    ! |  u; E- |. \$ v2 _0 m" dimage = cv2.imread("origin_png/person.jpg")
    ; h, ^3 L" D/ V. @origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值  ~4 S$ h8 [$ u% P5 g
    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    ! l7 T% T, Z7 o8 L+ C2 S2 ~$ Bimage[:, :] = origin_bgr, x+ g# a9 ], K% O* F! w
    6 k  b- c8 V1 s3 q1 }' n4 K# x
    cv2.imwrite("mask/bg.png", image)
    5 k0 [6 _3 c. u3 i' e0 D+ @1
    , z* Y8 u5 `$ u0 K1 v3 i3 ?$ X2
    / \8 }! @' O! p7 }( m% |38 F0 ?9 A0 R0 q0 P2 F0 L
    41 l+ y* _' h4 }+ W, I
    5- C; o4 I7 F& R# @7 o
    6: G6 k9 V% q, u7 w9 P, k1 S
    7
    , ^! c8 x! X. I: E8
    6 W& r  g9 ^. @: S) f6 r9
    1 L0 y" f/ `' j- i104 B; Y  @! f' }+ \- T

    ! [7 _+ [* D+ T" e* p& z需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码
    ' V' p9 u& F$ Q1 j# {. m) b0 X% N% q: N$ U! n) }) s3 z" H
    src = Image.open('src.png')4 v$ A* G' B8 y1 ^9 Q" V
    bgr = Image.open('bgr.png')
    3 d! k6 r' N1 _! m/ A" F( ]1! \& @4 e7 q& q! n( e
    21 _# T: T# A% @5 O: ~5 {
    另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)
    3 v- ~5 U3 k  F5 c/ @. c  Y  Y1 F' B; G9 ]; _* A
    com = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)! |/ f  R/ G" o9 Q. W3 D% g
    1
    1 H6 ^1 v  n. u) b+ N  f  G5 j; T" l* u: d
    那么加入我要换白底(255, 255, 255),就是$ J  Y5 ^: {  o3 `/ I
    ( r; A" @+ q! T
    com = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)
    ) F& @0 I$ p( G6 K6 K1
    . V; h- A$ f: |+ k; |' H& `8 d' B: i: _
    " \. {- N7 L1 }" U7 c假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是
    9 h/ g. ^, d; o7 m' }$ r" ^4 K; L
    com = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1): X0 K- B, ^& o
    1% m- k! x9 h6 ^0 Z
    总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.1 q! y4 V) N, X
    , P$ R0 o- m) P9 [
    然后就输出图片了。可以看到效果相当好。不愧是oral。
    # i1 j- H6 D; l3 |1 t9 w; r4 h
    & @, ~! u3 m% E2 }1 A; u+ u0 F
    原论文可以实现发丝级效果+ \) I7 R) u2 ^" e5 h

      }. E' q( E( a2 Z6 ~
    8 _7 [# O) R( Q2 I0 }. c, j/ t
    $ B" L1 }6 w/ ^6 f* x4 G! Q  v! W' U7 w9 `; F- e; u

    - \1 ?1 _6 Y3 X" U4 Y7 B1 e报错解决方案
    + Z/ X! c7 D% A9 u  Ican’t divided by 4 / can’t divided by 16
    ! T, f! N2 _+ {# h0 A, F: k' N# ^* s由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。
    - I+ ?, }3 Q  V. x; E这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize- x$ Z. Y. ?, ?1 ^( {, Q( u3 m
    ————————————————
    % v; e) Y7 I5 u* l版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。; f* f' _7 e& x. v9 J4 K7 M
    原文链接:https://blog.csdn.net/weixin_43850253/article/details/1263767670 s8 A) R% D4 g" D

    , p& [  H% ~. h1 ^6 k, T- K
    - ~- }8 M4 ?; z- Q
    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-7-28 13:22 , Processed in 0.366815 second(s), 56 queries .

    回顶部