QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2127|回复: 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将红底证件照转成蓝底
    % Q/ ]2 i/ k: D前言4 H/ [/ y' d% m( [
    emmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。
    9 u6 W3 `) l0 o- d$ u4 X
    7 F8 q9 k' O# Y# [; |7 ^7 v5 T, O7 A1 H  q( A& z" ?

    " r; ?) K( n  y9 d9 L) A3 W7 {
    6 ~: Y. ~! z6 }$ ?" R  k' U方法一: lableme
    ' k7 L2 L. `  m) mlableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.
    , W( c- C( F1 {% |
    % O1 e% G6 h$ |) |# 代码来自 https://blog.csdn.net/hello_dear_you/article/details/120130155$ o9 W: q2 s* L* Y8 s2 c( m( ^" o9 l: }/ ~
    import json
    " t0 A9 h& s" e* _& A* z9 gimport numpy as np
    ! N' z9 G$ r1 ~, T  I( e. s2 |import cv2
    + j9 o5 w4 r1 a8 k5 Y  V1 _# read json file4 D% X; |: T6 m9 H$ V3 m+ a
    with open("origin_json/mypic.json", "r") as f:- ]& ?' A4 P6 p$ N6 [( n
        data = f.read()
    5 q/ H' q$ }" z- ^6 u% t7 W+ e
    0 a) x8 r( y$ H6 V3 a# convert str to json objs' G4 ^- Z" g7 Q: m& z3 z1 Q
    data = json.loads(data). v' o( _( Z% {7 {$ A6 o6 C3 H
    8 k) V0 \7 R+ f3 R$ c  t" I6 d4 J
    # get the points 7 G& \3 w0 @" |+ \+ t2 e/ Y5 z
    points = data["shapes"][0]["points"]  Z( ^+ a( w1 Z& ]" E+ a
    points = np.array(points, dtype=np.int32)   # tips: points location must be int32
    - i: l# H3 W5 c$ x( P
    5 P& M5 h  l" p. \% ?$ b& x8 C& ~# read image to get shape4 P1 a; J+ d2 Z" @8 e' P
    image = cv2.imread("origin_png/person.jpg")
    " U: ~' ]3 l; u  v- v3 C& f
    6 P, J- g$ n7 q: @) n# create a blank image" v" J7 B' }  j
    mask = np.zeros_like(image, dtype=np.uint8)
      c( ?" g9 z& F  A. z3 l- o: S! }
    / o  ~9 F/ M, {0 g3 @4 U# fill the contour with 255
    9 O$ `" z$ ]- G4 ?5 ~cv2.fillPoly(mask, [points], (255, 255, 255))4 G# |  b. ^* V: p
    ' [3 |) L: I$ v  ^8 _) I- S
    # save the mask
    ! E* D4 z2 z) V$ a6 I$ r* l4 Pcv2.imwrite("mask/person_mask.png", mask)
    ) l2 B8 J! g' ]8 @! Y* A& F1
    ! ?% d  K6 Y0 L/ {2
    : F; I4 q8 c3 P& E5 w$ I* T8 o3* l/ q/ ~( @# D+ E. a
    4+ J' U: |+ w  m3 Y. r1 e. \
    5
    $ h: d* d" y% t( p, u/ a  d6% U+ C0 H* B( _
    7
    $ c4 R" d3 r- J! U8
    % K. ]7 \$ U, e$ e' g" q. J9
    9 \' |0 S2 @" {* x' V  j% n10# r! V( N4 p. x: D5 L) \
    11
    ; m1 Z3 U1 I1 t5 o12! U* O4 {2 I$ y
    13; l0 i. u+ r, x1 e3 [0 U- m
    14
    * G2 Q8 B' O! v* J7 p15
    % [' U6 I8 ^+ r# t3 r7 K1 \7 I' e16
    % f" U. ?8 G  x) j$ f, [+ p175 b% l* Q: p" x. L/ R7 e
    18
    $ J1 j0 s& V" U# X9 F" M19- z" {3 J* I; v* J* G# K; z
    20
    " R$ p( q- C3 k' [) y+ z218 h; r/ b6 f& x1 M% W
    22
    0 W% X1 o& p8 `' [238 v+ W* Y% h! I* Z; L$ Z
    24( n8 e% g) X; i1 I
    254 |' s: o5 G% @6 g3 l5 ]
    26
    : x) j7 A! [8 e, T7 H; B大概是这样:/ S. n& z0 T% p
    : k/ B: o( N. @3 L  J& {! i$ D

    / u$ U) N$ c4 w; E& Z2 l$ [然后利用这个mask生成图片
    % y3 L0 z# F  a. E* s
    ( J* W) H9 T! H# 参考自: https://www.jianshu.com/p/1961aa0c02ee
    0 n; `1 M1 t. j2 W0 ]import cv2
    6 g# ]& B% R  P/ k, t7 u. zimport numpy as np6 y7 u& r& F' b
    ) V2 t/ ]! a1 J/ `! I) o6 Z' L& ?0 y6 b! J/ b
    ) j8 |! z; o/ z+ q2 e, x# D( b' m
    origin_png = 'origin_png/person.jpg'# c9 l$ q2 E. i8 N9 h1 ]
    # maskPath = 'mask/person_mask.png'
    . h8 U6 J: v! U3 m+ o. imaskPath = 'mask/bmv2.png'' l1 R2 F+ P, i0 z9 s9 E# J& |
    result_png = 'result_png/result_png.png'
    ) u0 a8 v- U! V; i! N: j: r
    , r% S5 P$ n! V5 Y
    5 c4 E1 V; W; }: m* F7 W' N$ ]maskImg = cv2.imread(maskPath)
    1 D6 R1 r9 y# L3 A6 J. nimg = cv2.imread(origin_png)$ q9 K6 K$ U: e: B/ C  y6 T3 _
    assert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'
    $ d2 U  O" I3 [, S$ Z& E. H) b- ~! A+ G: A- q7 A( q
    h, w = img.shape[0], img.shape[1]0 X- f5 b; C* o! ], w7 k
    print('图片宽度: {}, 高度: {}'.format(h, w))1 ?4 n# M- R& @

    4 I' T  a8 j, e& S$ v/ brgb = (19,122,171)" k. R" p0 }; j, _- A
    bgr = (rgb[2], rgb[1], rgb[0])5 L* Y% T4 M* l9 }
    # (B, G, R)
    : F2 J# ]; \. U0 U* y* y& {7 j  vfor i in range(h):0 L5 A! u! e  x  `
        for j in range(w):
    2 z; I8 a: V- p  G! P        if (maskImg[i, j] == 0).all():9 Y3 X! h7 i9 z' t
                img[i, j] = bgr
    + m: P5 s7 R4 k( r. dcv2.imwrite(result_png, img)& d2 c, O/ K8 d5 D6 o9 U9 Q6 G
    print('图片写入 {} 成功'.format(result_png))' z$ }" A. S' n! s! K6 X1 ^
    1
    0 h4 F: y6 a9 j) p23 S& h4 Z! ^/ d" ?, v' i
    37 _* @- O$ t" {! U! _5 X' n: X
    4+ x1 @. |( E: F
    5
    0 j9 ~* @% Q2 p4 `6
    + t$ q: i, o) Y* u7
    ! n$ i3 |" i3 e  G% G8( v8 f7 d. Z9 n6 w7 i
    9# B- u% @3 E% @0 N* k) j; C! H4 r
    10, ^8 _' U6 ~$ Z: \$ ~
    11
    ' v, v4 }) @' @& e$ @+ i: i12
    5 Y& o. G, T1 }8 Q3 ]' \! q1 `, V: T13
    ( l0 ?5 w- i/ O( {5 ^! ^% N+ W14  J- q& {3 G; p8 y$ B$ G" U5 m3 Y
    15
    & }  y7 U/ o8 T) s16$ S) d' q. u0 \8 r1 n
    17+ e. \" F7 k; K& J3 k: ]
    18+ h& I9 u+ E& F4 h
    19. `' t0 I2 Z$ }; Z* f1 P
    20
    ; J. t3 L' m# r/ S21
    + L, T* @% }+ I22. R- J  |7 E9 q7 P& L
    238 a9 H  N" Z( O# i; I
    24
    9 X& ?+ q! h- R4 A25; M* d& i4 J. ^5 ]
    267 f2 J1 w% ^+ F% U) A
    27' S* l' K/ |" D& x. P
    由于人长得一般,就不放图了…3 E! u$ @) U2 h! n

    8 }6 c$ D3 e2 t- Q缺点:
    ) e3 V$ m* s( R0 s7 Glableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。/ Z) `; w3 |& S( R4 [
    ) S( d1 x5 Q* M
    , N  S' Q% p. e0 Q% B5 v& k
    $ k8 {$ ~6 A8 H/ y
    ) K( V) h3 B2 R6 l
    9 ?6 s  H- [" _( h! o' e  K4 r
    方法二: 阈值3 b8 Y5 a4 _! Y* _: q
    该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。
    , _& q! z. c3 }8 L. b. h& y& K' j; Z5 A+ }. v5 _6 ~: c
    Opencv
    : Q+ q5 R! w" L% E0 B. M$ ?) limport cv23 a: P7 l4 o; ^& L$ ?4 P4 G: ^. t
    import numpy as np4 d, j, W* Q: l4 Z" h
    , P7 _) p4 c/ {9 W  k/ r0 O

    0 x  _# ]" i  s3 t$ T9 E9 c& Ydef mean_square_loss(a_np, b_np):
    / z  b& t, B: ^7 F4 S6 Q    sl = np.square(a_np - b_np)# e1 g, ~3 G0 Q% b; b. @0 Z# a
        return np.mean(sl)+ ^, j& G+ m8 h( a$ Z/ r" b

    - [+ f0 J) J8 \2 P; S! E' p/ Z7 E1 N+ f& K+ Y1 T
    def change_red2blue(origin_png, result_png):
    5 _; w0 C" f7 R' W    img = cv2.imread(origin_png)
    9 p. Q$ n* ~# V  F9 l6 k5 n! }  H
    8 O( f8 k9 L/ N* D' Z: S7 W    h, w = img.shape[0], img.shape[1]
    * k% i1 }/ b  V    print('图片宽度: {}, 高度: {}'.format(h, w))
    9 E" J: {8 E) S
    " }/ I8 A7 g$ S$ u    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值# D5 D3 h2 p# m& v% V
        origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0]): G" j. c4 q$ H3 f+ ~. B" Y, Q; d2 y
        target_rgb = (19,122,171) # 蓝底RBG
    9 g' h) e2 N2 Y$ u7 u    target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])/ k' j/ m1 E1 E; y
    % Y  f5 |' m/ W8 |) ~
        for i in range(h):
    1 a  d- i; p% Z        for j in range(w):
    6 P+ Q4 N2 Q5 m# Y+ i4 @8 R            # (B, G, R)
    1 ^, r7 {; V. \; w* g            if mean_square_loss(img[i, j], origin_bgr) < 50:
    8 q2 [, r. G0 ^# b; L( Z2 X                img[i, j] = target_bgr $ F+ b4 B$ y# ^- [' \

    : r0 L* H2 |/ y    cv2.imwrite(result_png, img)+ ^( L, P$ U& a, l. p# P6 U
        print('图片写入 {} 成功'.format(result_png))
    $ |" h7 W6 z+ y1 j& v/ g6 U  M8 b) j! }( g( q

      y  W2 B; w1 N3 {* wif __name__ == '__main__':
    : y. w6 X! \4 E, `0 h& ?    # origin_png = 'result_png/result_png.png'
    # s6 G4 d0 h& `  H/ L# Y8 h5 T, A    origin_png = 'origin_png/person.jpg'
    ' f, ]+ o' a2 ]6 W, I" J    result_png = 'result_png/result_refine.png'! q1 N. V+ c5 i, M5 g* Z' Y! J
        change_red2blue(origin_png, result_png)- x( A7 ]9 K2 Y# P9 B: Q
    1
    1 ?3 X7 P3 Y9 D2  p" N% x1 a; I* F) B
    3
    # A& k- D) l8 n7 s4& ?- L1 G. A2 l4 n9 ]. b) u
    5
    , W) u) b, c4 ?6
    $ ^! y# w, b6 B5 F) t+ C- P: E- }& n76 V2 M# a' Y& ]; |, r% }( S. E
    8) X, `2 L( u4 W' j5 Z
    9
    $ d1 [' N" e8 A, n5 e- F2 d10! [& T& z3 n  |- K$ o
    11
    8 d& M; V) t( ?" H; e/ M3 I; i( A$ d12, `7 {8 V' N7 R0 k# F) K1 W3 R
    13+ `& j- E- s) A1 s# q
    14& O& u' v3 ^% J; b0 N$ J, n
    15
    , t# i6 t$ t2 {- S; X; [16( `0 K" r8 I4 Z: A
    17. w- k, R8 {9 Y
    18
    6 f7 V0 f7 f! @+ y19
    4 N0 \0 n! m$ k206 e3 ]" l! ^; u. h5 |
    214 h1 u: C  P# ]3 U  N9 z$ i1 `" R
    22
    & r8 G5 }0 r3 r0 u& m9 C23, f+ \  [& c! [4 A$ I
    249 O* O8 s% G9 o
    254 Q! d& ~5 _/ g- V# |+ Q2 x
    26
    ) K6 l2 ~" {" w& `27
    ( T( b* L! ]) g& s% [28
    9 `3 i5 b: q/ {$ G0 [( v# I29
    1 U4 H5 `: @9 t* w' I: Z5 R5 h+ o7 A301 h1 }; g2 L6 \2 P9 `, M
    31
    9 C* v4 S" q, q, e, r( P, ?32
    ) y+ @3 d8 V' L4 h339 g% t2 Q% `$ {/ s! O8 `7 n% b
    34
    5 m5 v2 x3 z) n35
    $ k- M0 j" g" c+ J结果人与背景边缘仍会存在红色像素残留
    7 @- v. c5 G( H' c9 j2 O' z5 E5 D* ]. u: f2 @
    ' X( J. x6 l9 i$ P- R* T1 M

    # T" h( @( p! J$ q( y9 ^
      V( y1 R( C0 x4 e$ N7 m7 T6 P6 b- Y7 V2 Y
    PIL4 p7 i- R1 R2 n! h1 z
    from torchvision.transforms.functional import to_tensor, to_pil_image
    " ]6 N5 Y) T( `: Lfrom PIL import Image) [3 W$ c6 K7 H% A* K; e# i' T9 U
    import torch+ u5 V; q2 ?6 `0 p( h3 \& s! i& t
    import time
    1 O" K! {; P0 _5 |
    ; H% H/ t* ?- ~7 i" K0 E8 F1 y6 r- W
    def mean_square_loss(a_ts, b_ts):
      p) Q8 N) I0 y7 t# U6 d* f    # print(a_ts.shape)4 w8 ^$ V, C0 q" a" |  `
        # print(b_ts)! w) f: b) a5 L: U* t
        sl = (a_ts - b_ts) ** 2
    & X+ i& ^" t& e% Z3 e% L0 Z    return sl.sum()* U2 I1 t/ o7 X

    . g8 s1 J" X, B  j# z8 l( g: f
    1 a4 n1 C3 u( r9 \def change_red2blue(origin_png, result_png):
    ( P- C( P% ~( m: w6 y( J    src = Image.open(origin_png): ~& W5 Y: E( p# _! Q# d
        src = to_tensor(src)( W1 a' T7 B# b1 |+ i, c
        # print(src.shape)  # torch.Size([3, 800, 600])
    - j3 ]4 R+ u/ B5 b3 i    # channel: (R, G, B) / 255% F: t  T0 }: B6 W0 L: |+ W
        h, w = src.shape[1], src.shape[2]9 E4 r, Q# D+ B! k

    . [6 {" z' v  g( o/ `' X    pha = torch.ones(h, w, 3)( j/ |' n2 A4 S) y9 f, Y) P
    * e9 W: x% i, J8 {  C; u) G
        bg = torch.tensor([168,36,32]) / 2550 X7 ]" N  a+ Z# A
        target_bg = torch.tensor([19,122,171]) / 255
    : h' L7 r/ L& P+ ], I) I8 h* }; X  d/ p+ {
        # C, H, W -> H, W, C
    ; k2 c( F( i) x. M- c    src = src.permute(1, 2, 0)
    # p0 u( q8 x: H8 I# R9 H    for i in range(h):% G% O+ d8 {7 ?" b) @0 l
            for j in range(w):
    # Y2 D3 _' u# d7 `7 v: y$ i            if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数/ ~$ U9 v1 Z3 |) C5 H3 }4 v" z
                    pha[j] = torch.tensor([0.0, 0.0, 0.0])
    . H. u, B- s2 V3 ~* X! i7 I' W4 n, j2 M; Z; \0 F
        # H, W, C -> C, H, W
    + u( B4 n3 z& U! d    src = src.permute(2, 0, 1)4 d2 ?$ V5 m7 q6 _9 Z
        pha = pha.permute(2, 0, 1)
      ^6 _" Z& s5 t    com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)
    1 Z) G. a9 X6 I. h" s2 e) G, \    to_pil_image(com).save(result_png)( G8 W1 y4 z" _7 E8 g

    . Z% R2 ~2 o& O  a6 _0 D
    ( H2 L" D/ u) ?3 K9 `0 oif __name__ == '__main__':
    6 m% h! r2 ?5 V% G    origin_png = 'origin_png/person.jpg'+ |* ?" p, J( P" w. ~* k
        result_png = 'result_png/com.png'
    6 I8 E0 d* \9 R! h) y8 u) p    start_time = time.time()$ y3 Y  d/ v0 _) X% y$ t1 y
        change_red2blue(origin_png, result_png). H8 S# u3 V, \/ [# s
        spend_time = round(time.time() - start_time, 2)$ v% L2 a, l8 t% E: M
        print('生成成功,共花了 {} 秒'.format(spend_time))# O; f9 K3 A5 w# p* p! K
    1
      z7 v7 z7 k/ `. g% c; K2+ d" p5 p8 E4 u/ H
    3& X" O7 G& u! ^
    42 b) {1 Z$ X) Y$ h
    5
    9 f) Q6 ]+ ^3 z1 m6% m: K9 k7 }& f0 w& k) m
    7
    . T8 r& A. a% I* l1 ]. G! C6 q! S8
    / X1 ^, g+ A5 V- @9
    3 F+ v( j" a/ U) G* Y1 k& a; u109 z/ E5 [+ E1 c8 G6 z
    11
    3 e7 u+ r/ f( Q2 K% b, L2 t+ e12
    7 B, B' a# q0 W' U* I13
    # H9 C! ?3 Z5 b144 ~" |/ E8 D5 r) i9 K5 Z
    15
    0 l& O) _4 u+ O7 N9 y6 I' l) @8 f16
    " |- w/ J; G% D7 J1 `) s17
    6 q% @4 m$ E! |( D18
    ; p: Y/ {9 D; J) M6 L19' J2 r+ I% j! p
    20+ Y$ ^- p" i2 M% q; {5 G2 g
    21
    ( r* n  }% f# S( r6 ~, e9 i220 b6 b& u; [+ X/ l/ L, X" L
    23
    & d6 n5 N: i; z. z24
    1 e& v9 @6 k+ G6 L4 ?$ f( R$ P25
    , j" t: Q& b8 s6 n. e26* X9 \; ~) a! n) y; f+ p
    275 F0 {5 p+ q6 Y( W: r) ]3 H5 K
    28) U! H' C5 K9 o) E4 o" f$ G7 o
    29
    ! d" [, W3 o, m. D2 I3 d30
    3 E) K) @( \" k$ W/ |0 P31
    # N" \0 u9 ~* D0 z32
    ' g" N& H6 U: `7 v+ ~6 m$ O8 y33
    * R; e7 v  ^. p: U  W, r; `' |) J340 ?4 J" N" O2 T  G, [6 Q& W
    35' L* I$ c6 h( c* }( c. i
    367 \, |9 w8 D/ j6 t5 _; f$ J% p
    37
    # s% Z! r8 S6 V1 ]# p* i385 r7 o3 Y$ m) ~: N+ f4 C' l  d
    39
      W1 w: h: s! m& u' w4 h0 I40. t( s( v& @1 R) ]* S/ V
    41. n2 i  S3 ]. `- A& E# @
    42) u8 G0 M  S2 I3 _
    43
    & O6 ^) F( G  ]* X$ C. _44: k* P3 R; y5 y7 W- O8 g% ?5 P
    450 {0 e: _8 w& J' f- r5 C0 q3 K
    46# Y- |9 [4 p  @. F6 B8 d. B
    该方法质量较好,但一张图片大概需要12秒。
    ) }# j: d2 E  p8 d. `8 @2 z) p6 s/ C1 \5 C# c- D
    3 ^6 H) A% S: C3 g  ~, ]+ P
    5 U, J' q( T! w* @5 |" r: y
    方法四: Background MattingV2
    3 ~3 d0 H! N8 D) s- l- ?Real-Time High-Resolution Background Matting1 D- f5 t! A' |6 m3 B% A
    CVPR 2021 oral9 e7 U+ [% \' i6 x3 }" n& S# Y5 K
    / Y4 g7 U  j$ h# D; q7 m0 O# h  i
    论文:https://arxiv.org/abs/2012.07810
    4 |) A' v( o4 I1 b0 E( Y代码:https://github.com/PeterL1n/BackgroundMattingV2/ e. L/ A% |7 m. Z: V
    8 H8 K( g: I! O! B3 N5 X3 x
    github的readme.md有inference的colab链接,可以用那个跑
    5 N8 r/ X4 Y& S6 U
    0 U1 w  b6 P1 _由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。
    ( e: l3 l  u% x) y: x. X
    0 O( B' x2 z0 P# a% d  c$ z于是这里我需要生成一个背景图片。8 w  }: L1 W1 ]( ?
    首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。
    8 R! y, u7 a: J) Z. V0 D8 J
    6 H4 C# P/ x. j8 z0 S# S) U7 b6 q然后生成一个背景图片。
    0 C: ?  v: m1 V9 [" E# `) C$ h% Y0 u$ B* P5 v' Z
    import cv2
    ( v/ R& X5 V! X5 ]8 S7 eimport numpy as np; \% ~- Y+ x  I. D" C
      C9 a3 e4 I, P' V
    5 g2 D% S- v  c% Q
    image = cv2.imread("origin_png/person.jpg")
    % F$ h7 C9 s( y3 R, h/ A2 ^origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
    7 A; L/ h9 @0 _* zorigin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    % i; L8 U! A& {5 kimage[:, :] = origin_bgr8 y: P+ {8 ~5 |: C2 t5 V, \
    3 a1 _/ Y" ~3 S
    cv2.imwrite("mask/bg.png", image)
    . C: |" v- P! @9 N0 {" {6 J' \1
      v; ^5 U  k( p8 r/ C  k, D( h2
    7 p/ P+ D0 ^9 B) k1 `) m7 ?# n5 W3' l9 ?2 }5 x2 }  ?$ L. H' f
    4
    + x% w4 S, B3 O# G; u  j# H5
    " x. y0 t2 G6 J0 [8 r4 z. T% D6
    * h1 D# W3 Q* \6 A8 a  ?. ^7
    / C- W. Y4 c8 }/ c8/ B2 ^7 h! ~8 ]) g. [/ R/ p
    9" R6 V/ g! ]8 W/ e+ \  v7 y4 i2 z/ p
    104 n. r1 J8 M  h, l" ^

    4 \% L( y+ l; {3 ^$ W4 R需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码2 ~! E, w0 z( J' H8 p6 Q' `# d

    # P* H1 A* c& r$ x) Q, msrc = Image.open('src.png')
    & m7 o. p/ t. D$ C9 A5 U- Vbgr = Image.open('bgr.png')  V) Q( B' g& q7 U
    1& \7 Z; Q& f/ G  l$ w
    2
      e' L* r& P7 r" D! b另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)
    9 E3 R2 b8 G0 ^& e$ b& L7 S4 n
    # b6 |0 r5 `6 a' j4 Ncom = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)& \6 V" Q+ @" V5 D
    1" J' k5 S5 g+ z" S) W
    2 f7 E* m0 l1 n, W" E/ A
    那么加入我要换白底(255, 255, 255),就是5 v2 P9 s: i5 t
    : E# N6 _: F1 r2 \& C
    com = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)
    3 F3 ?% f( l. k3 m/ p; V. K+ c: e14 W* Y6 b# }$ o' T5 u

    6 Q; N% j$ F$ |! F1 k假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是1 p+ L) v. F4 u; r+ A

    1 U8 H1 i2 m7 w' n& ^5 wcom = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)4 c) I. k- k: E2 o
    1
    ; U) W0 f6 M# u2 C4 J; U  q+ ?总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.7 {( l+ g' d( [% J9 o& R: ^1 d+ }
    * K5 o" u3 j: |- B- `) ?
    然后就输出图片了。可以看到效果相当好。不愧是oral。
    * J' V; ?  n  v3 H
    8 D9 f8 S6 q5 ^! S+ a7 `' F9 |
    " }3 c9 R" N& N$ `5 ~; U0 R原论文可以实现发丝级效果' [0 O, v4 I4 R& o9 n8 o
    2 \4 `: n9 `- G7 h  p: D
    , a" w! R, e9 v8 r. q

    7 C7 m' t) S- b& \2 ]1 \" F8 W# E+ l. u
    8 N) `% L7 }, f- X1 j1 z- ?
    报错解决方案9 L9 o. F7 N$ t& g
    can’t divided by 4 / can’t divided by 169 y& p- j- R; Z% F) ~
    由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。- {7 [4 f3 |) r5 [+ O
    这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize9 L: q, D) e1 ]: v: ?
    ————————————————2 V2 w+ H  u" i* R7 i# j
    版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    9 {+ u+ h9 F  ]& b& ]原文链接:https://blog.csdn.net/weixin_43850253/article/details/126376767/ w, g9 u& d; c* ]9 V# j
    ' ?& L* c# I5 f. n6 G
    + z% \7 j* t* L- d% c" n2 }
    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-31 07:54 , Processed in 0.473927 second(s), 51 queries .

    回顶部