QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2107|回复: 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将红底证件照转成蓝底: e  [$ ~! |  f& Q8 K- n/ s" Y
    前言. l5 n8 n9 t6 S% P2 E
    emmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。; J1 `( {1 t: J1 o2 \
    . Z! y! n3 w5 j. a
    ! ?( h  b: D! v8 f, p& O% v& @* h

    * k  Y0 V* e/ q# t
    1 h. ~& [0 i6 C. l! r' Y8 T方法一: lableme
    " a% B' b% F4 B( ?6 l4 p' glableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.
    5 i& e$ A3 F2 ^5 X3 ]& B/ L- P- }- c" ~4 e
    # 代码来自 https://blog.csdn.net/hello_dear_you/article/details/120130155
    - h# M+ D$ T. ]- g/ H  O4 iimport json
    + N$ _: X; D) z9 {; `# Nimport numpy as np1 [0 x  W1 ^! i6 w. G
    import cv2
    + I2 D! E+ N) f2 c2 Q8 u# read json file, B- E9 R) {1 P! q
    with open("origin_json/mypic.json", "r") as f:
    9 E9 Q1 F. P$ W3 t4 d/ q    data = f.read()7 f: d5 `2 _4 V7 o  a- j
    2 }% B5 ]- P8 _% W# T% M# Y' C
    # convert str to json objs
    8 w4 ^) z8 d* n; cdata = json.loads(data)' o  u2 H) E" g+ c
    ) i0 k# r9 [4 t4 s6 l/ @
    # get the points
    1 h4 j. [& F/ G2 P0 fpoints = data["shapes"][0]["points"]
    ) g9 d: [! h3 d9 }& X' p3 g- apoints = np.array(points, dtype=np.int32)   # tips: points location must be int32
    # w3 d& t8 P' B0 R3 Y+ A
    " P0 e% z: ]2 d- P' p# read image to get shape
    ' B$ i  Y: e4 e2 k+ zimage = cv2.imread("origin_png/person.jpg")
    & a. S+ @2 Q5 }' C
    . I# N" w' H) p$ R4 _6 k, e- G, W# create a blank image  R$ ^6 x; \6 f/ A
    mask = np.zeros_like(image, dtype=np.uint8): t+ N0 }4 U( |) Y

    , r" d2 Y7 I4 y! z' _. Z/ G" j0 g# fill the contour with 2557 U. r" u! c9 ]
    cv2.fillPoly(mask, [points], (255, 255, 255))
    " E1 A0 r  e* w$ v6 r
    # F; }0 H$ l& |+ H+ i. J# save the mask 2 c6 B1 z. E# c# a1 E
    cv2.imwrite("mask/person_mask.png", mask)
    ; r' K# _2 I/ u0 j$ i. W9 w! [1
    ' l. o3 {% U- ?; w# m2
    , |: ]) ]# ^- ~- p: X- D3
    * P. B& v; ^: L( e1 o4, K8 ~& H1 N( p7 A, s& k
    5* B7 g% t* `$ `. ~7 h5 _
    60 i) [; ~1 V+ [, z' @) z7 m
    75 Z( a7 N4 [2 y8 P$ w
    8* P+ {" `* y, V- a( T) B3 f9 M
    9
    $ l- k) }4 u/ Y2 e" l4 b$ m104 ]+ C7 v  S5 _8 O3 T; N! v- g( j5 F
    11# f- v1 e. N# i5 G4 E
    124 X7 a1 u* C0 v
    13/ |' y: q! y( ?9 y+ b+ d( B5 n  a
    14
    ( U9 u3 r3 Y1 J$ y/ T151 P+ t3 n, U2 B# u( G! \
    161 |& ]: g/ [" o2 o6 c
    17
    # Q( z/ n6 H& U# {7 a, E: Q) r18# c* x! ^+ ~/ q' u' n
    19
    " t* L: w) K% A20$ F; S5 z! g& Y, s
    21: O  R4 v4 t$ j0 M% ~5 c
    22& I& e. O6 O. T" y6 ]8 F8 X7 A4 \
    23
    1 Q: u9 A7 y+ b3 t- E24
    ; j3 ~$ g' ?" H3 r25
    & y# f4 o9 Y1 F$ a9 g9 |26' L. H; K) x/ |. T2 k' h4 S: |
    大概是这样:
    2 T4 Q  a3 T/ t* u% J$ d% e  J0 F" v7 }

    - u" L+ v( x) W4 O# {然后利用这个mask生成图片% ~" u3 K2 p% k. c3 J* h( F

    2 F  P0 @. g9 \# 参考自: https://www.jianshu.com/p/1961aa0c02ee& @7 v5 V5 x  z0 X
    import cv2
    $ e+ ~1 [5 u4 T) Dimport numpy as np
    " B7 t# K; Q2 u6 y' f" q* y5 j9 m+ a/ q3 ]% v2 L

      D  H, Q" g$ ~1 Morigin_png = 'origin_png/person.jpg'
    & f  r: U% w$ T8 O/ K$ M# maskPath = 'mask/person_mask.png'+ H' q" E) n, h' V& Q/ n
    maskPath = 'mask/bmv2.png'
      _* O1 ?" T5 r' u& nresult_png = 'result_png/result_png.png'" t& q, @$ F- T+ p- z
    ' ^# R& ?( k% u6 n* @, a

    6 [( W0 J1 P' Z2 C  ?maskImg = cv2.imread(maskPath)4 _7 U6 O, e9 q! r9 g4 }$ F
    img = cv2.imread(origin_png)
      R! @/ e7 b. F! f* massert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'
    8 \. m! N& K# P8 G% @. |4 u4 W1 p+ v( ?
    h, w = img.shape[0], img.shape[1], m# k. _! d( S* t: Q2 j, ]/ p, @
    print('图片宽度: {}, 高度: {}'.format(h, w))/ [  n* T+ h3 _) Q3 _5 T) V* o4 m
    * ~+ {% Q- P3 [6 I
    rgb = (19,122,171)% Z; }( ]0 _% n5 t: @! r! H1 C
    bgr = (rgb[2], rgb[1], rgb[0])
    - C" q* {( q" m3 ?# (B, G, R)
    4 Y, x& h4 H) A4 o& Q+ A  Hfor i in range(h):
    9 T* l" {* {  \0 [    for j in range(w):
    ) [1 B. D1 C& }( b6 ^        if (maskImg[i, j] == 0).all():5 |7 q6 R* _. v) D/ O! t$ Y
                img[i, j] = bgr. }0 n) W  W1 n- E( B' q7 Y& k
    cv2.imwrite(result_png, img)
    8 a7 |, ?4 s: ~5 G; ~+ t9 s0 kprint('图片写入 {} 成功'.format(result_png))
    ' s+ _, ^3 ^# B9 `' b& {' x1
    / A# Q. @2 R' N2
    / i& ~% X3 p* f. r9 A3; u/ @) g, c! d6 v
    4& g# ]- h, B$ }: x8 f+ U+ P
    57 Z: ?: L* r7 D  `
    6
    3 R( S+ ]7 J% ~! H/ A5 R6 q7- M# c3 Q( |7 v, ~
    8
    " R7 o5 C2 W, `' e! [! @9
    , A( U' z  f; ]9 c10) r- ^1 D. ?4 B) \% y
    11
    " J" L/ p( |* b2 o$ ]! ?# Q/ H12, \" ]' g" n6 B: `3 B
    13; @6 e: b6 Z# |2 q/ E7 S/ J6 |; V
    14
    1 S* R2 B1 r/ L1 V- F6 \15. ?  y% X- p0 a2 g, L0 q4 q0 A
    16
    / T" g# p! Z- g6 Q3 [* k5 {; C17/ }6 W# y. n; X9 A7 k
    184 i! L7 ~# g% ]$ Y! j8 x8 H. ]
    19' ~5 ]' K, [) b6 k4 \
    20
    : b2 R; M& K4 N21
    0 o0 O8 F. ]3 ]3 o! W" O22" Y4 _) B4 Y% A- ~/ y0 p2 B
    23
      @* l, T! b8 l0 b24* b8 d3 _* M; G' |2 m
    25
    : }, O7 d" Y# W" r26/ P: M# K# v6 R1 O# N7 N
    27! i) j( i; X3 D& d7 v
    由于人长得一般,就不放图了…
    ; c0 x4 l/ F* `, o
    $ g- \# V6 R+ h2 e  n2 J缺点:; d1 w; ?5 Y. k: e! r4 A1 F
    lableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。
    : K, S& Y) B+ k3 e' q' N
    ) s  Z6 w$ Y+ a7 |3 |) I" e6 `( h* K" L# w7 w
    1 b* Q5 X% ~8 x  C
    + t1 [: E4 _# v& R8 o* }" L9 {
    5 |: Y1 P( Z. R/ T1 g* r2 ~6 S) b
    方法二: 阈值
    / I  @' r: f& A+ A. U( m该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。$ {' J! C* X3 V  d0 j. W8 V6 h
    ) {7 m8 g; Y# f1 W
    Opencv
    7 S1 E8 f- k* {8 R! J, i2 yimport cv2! w- P" e% B+ H
    import numpy as np9 x6 \* Z' o  T; T
    / \+ F3 L& l9 g: i

    ' u9 o5 @. s4 Z% j; J: Y8 m( Edef mean_square_loss(a_np, b_np):. [+ z  x( n7 k, w
        sl = np.square(a_np - b_np)1 V! i) b! J* S5 |+ K3 R; M
        return np.mean(sl)
    + j5 n  `% b$ V1 `( d5 i" s
    : i' v' l+ H3 C! E/ |" j2 ?7 z: s( |
    : B) A; N1 T' p+ t8 [def change_red2blue(origin_png, result_png):( ]& h% z, W7 J9 R8 c8 n5 ^: O
        img = cv2.imread(origin_png)
    2 J% u2 g, k/ x' e' w6 B1 g- j
    $ Z+ I6 b; ?8 d& o  y    h, w = img.shape[0], img.shape[1]7 ?- b4 C( \5 k" `9 C
        print('图片宽度: {}, 高度: {}'.format(h, w))
    / b* Q5 A$ `# }* q1 [& k7 u  C8 A% d4 [6 N, A. ~5 e
        origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值7 @1 D& X6 k0 w. _/ [9 D/ [
        origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    . L! k' l* s' `$ @5 {    target_rgb = (19,122,171) # 蓝底RBG9 C' ~2 ^+ V" R7 V: J# k
        target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])
    : Q" N% k2 g, w1 c) ^* q! j& u; F2 I7 q0 o" M2 ~( X
        for i in range(h):) x( g# g* w4 h& v, r8 ]1 [1 _
            for j in range(w):
    - C9 V$ ?$ D5 k! K            # (B, G, R)4 ^0 @1 p3 M/ {2 j" n8 N8 x
                if mean_square_loss(img[i, j], origin_bgr) < 50:
    7 w" S# e/ z: K2 j& K                img[i, j] = target_bgr
    5 C% W2 V5 }# _& [: N/ O' J) q: X4 R  r  T
        cv2.imwrite(result_png, img)
    , h$ w5 l/ [( S    print('图片写入 {} 成功'.format(result_png))
    ' t) h% X$ k8 x% H6 f0 _
    # ]! H5 l) s+ _- G* H
    # N0 Z% g* l) Cif __name__ == '__main__':
    $ o2 V5 I# ]% M8 }/ C" E: L    # origin_png = 'result_png/result_png.png'
    ) f+ S2 m* e$ W6 ?& L* I2 d    origin_png = 'origin_png/person.jpg'1 g; f) O6 Z& u( M
        result_png = 'result_png/result_refine.png'
    ; I8 P4 w" O$ H. `- ^    change_red2blue(origin_png, result_png)
    1 ]$ J0 I2 @3 w! E' J13 M3 B0 ~* U1 a! a5 ~
    2
    8 l! G, L; q* G1 a8 a$ H& J" B3
    " t: G  J. [5 r  }4
    $ x* E5 \7 M3 D' U( Q' p3 K50 h3 U- q& B  G6 e" M- V4 U; D# _  N
    61 s9 _% K" d$ ]$ z
    7
    * U5 y# x0 x/ O& K0 ?0 l89 {2 D8 |- E  V6 A# M' W4 W
    9
    * s  A, ?; d7 l8 e1 C/ B: ?. C10
    ( ]3 o8 |# [9 i% F1 L11
    4 N2 a& v. h) ]6 e( s( |121 \, y+ `9 C6 _% S2 J* I! v
    13
    7 j& i) I7 h4 s# B, ^, `! I" q14
    3 W+ ?4 @# d1 U0 M2 y8 F9 I- @4 v15: ^; x# n3 j1 y; Y  O* {
    16. S% o: n* y& d% b: m6 Z
    17; n' I( K: R7 k2 Q% o  X0 e5 ~
    189 b) {1 e! i; b8 R$ R/ n
    19
    / S/ j5 G; {/ Z8 E: Y+ v: }* H20
    0 u# t# L+ A) U- @8 v. m3 `21& R7 \0 @/ w3 ~( M1 y3 |4 ]7 p# M
    22
    ) z' \% f/ m: _3 R23# @6 u" Z) H( z6 b9 {) V
    24
    ; W+ q" O+ i' U3 c6 R252 T8 J1 P3 P' o
    26
    & S2 k8 k8 Z; k8 k$ W/ x1 v0 k27- P! F- n+ e  b  s2 u9 N1 W$ d7 a; ~
    28. V1 q0 H4 X( ^) h$ ~1 O7 X: b; }
    294 V9 T, Z$ O0 n2 Z! n
    303 x, n. H" r8 O4 ?) B4 ^) h2 T
    31& c" B. e, ^# \4 T" b7 c* ?
    32
    & y8 }5 D& ^* X  s: ~2 N& N3 h33, \3 ]) \5 d+ x- d* R
    341 U/ t/ A. @! l- e8 G' o% `/ F
    359 W$ m) W9 V! k
    结果人与背景边缘仍会存在红色像素残留4 _. f. c% {0 Y
    : O, Q5 t) }9 o+ @$ W

    / q5 M  v$ h. |. o0 H  E8 N7 c4 h+ m% R0 e* X. F

    7 u  V7 d3 ~" d2 P0 S6 S* @5 ~" a& n6 E+ ^
    PIL" M: \: u6 `4 X
    from torchvision.transforms.functional import to_tensor, to_pil_image9 |4 l3 ?* i/ z6 Z& ?0 y" p9 h
    from PIL import Image# `+ v  Z* \3 j
    import torch& Y1 `- w! m( T. f: F2 f4 `( n4 b
    import time
    1 p/ h, h6 u3 q; A; Y
    / f1 I; ~( v4 b( x
    # g0 M3 e- T4 v4 zdef mean_square_loss(a_ts, b_ts):( g% E: T& B5 X1 O
        # print(a_ts.shape)3 q5 U- X3 t% [# s  [; o
        # print(b_ts)" y* N4 T- B0 D" S
        sl = (a_ts - b_ts) ** 2) D# E  b# M( t% X  F
        return sl.sum()
      z) ?( |* i. f
    3 c! _/ ]0 s2 j  _- x
    8 q7 L5 g+ n1 ?0 q% n" ]; Ydef change_red2blue(origin_png, result_png):' \6 L2 ~. G5 ^" q1 Z
        src = Image.open(origin_png)( u( U2 b$ q' E3 x8 P8 x8 `( c# J- t
        src = to_tensor(src). ~! X1 J: O% a; @: ~' `; `
        # print(src.shape)  # torch.Size([3, 800, 600])
    5 ?, e( S1 @3 ]& v. t) h    # channel: (R, G, B) / 255- _3 _. N+ G  @+ Q
        h, w = src.shape[1], src.shape[2]
    : q) K! _6 B- Z! B
    : \# P8 W7 I! T+ \  {    pha = torch.ones(h, w, 3)6 ^8 Z. w! f" [5 z

    % u% I2 p  Q& N! N3 ~    bg = torch.tensor([168,36,32]) / 255
    4 {8 q& v% q" A) }    target_bg = torch.tensor([19,122,171]) / 2552 H5 H- [  ]6 L. M. b# ~: F5 J/ _
    5 l* x) Y8 K0 L4 c: Z
        # C, H, W -> H, W, C: M# I7 G& d) W3 N1 Y" x5 F% Z
        src = src.permute(1, 2, 0); f9 E9 o+ \/ }% Z
        for i in range(h):
    ; B1 \: F& E- v1 f8 g  k3 ~, n        for j in range(w):0 g! ?/ q0 m* Y6 P9 S
                if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数
    % X1 l0 d4 o) M2 F) k8 j) Z7 ~% w                pha[j] = torch.tensor([0.0, 0.0, 0.0])
    ) M3 ^# i! i7 m% D, g  n# i& J% p$ y
    ( Q- A0 O" a/ n# G  L' S7 V    # H, W, C -> C, H, W
    - T( h" d9 L+ z$ n    src = src.permute(2, 0, 1)1 C  |3 o$ @+ S) d
        pha = pha.permute(2, 0, 1)  i3 ~6 y3 T, A' S: t/ f
        com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)
    2 q$ ^/ u# D! E7 `3 b6 y3 f6 i8 w    to_pil_image(com).save(result_png)6 z+ n4 b8 [+ j: n# |8 H& A& F) s
    + X1 j6 U- ^( a6 e! R" o# i

    8 l- ?  q) A5 c1 rif __name__ == '__main__':
    2 y: X2 k- b- N; t# g    origin_png = 'origin_png/person.jpg'4 E6 m# t2 E3 Z1 a" s7 {
        result_png = 'result_png/com.png'
    $ R: d; M4 r$ |1 P+ `- }* J- @- P    start_time = time.time()
    6 E' Y" D% M  Q8 u# Z    change_red2blue(origin_png, result_png)$ C9 `" g$ U' V
        spend_time = round(time.time() - start_time, 2)
    8 S/ W; E& p5 H6 ~! y5 ~    print('生成成功,共花了 {} 秒'.format(spend_time))  C; Z6 {. x+ H4 R* G( C
    1
    : e' s7 N( c" y3 O( Q* Q2
    * H3 U3 ~* Q, `3. {1 g- M+ V6 r' H/ n
    4% I4 H' ^- R% i; d6 P- h
    5
    1 Y. t7 w' p3 r5 v6
    4 t) L$ [& p8 ^$ g& _7: V) k- `; }$ p& p. ~4 E
    8& U& D. h* N/ f9 Z  P, d
    99 s" r- Q+ [3 K/ r
    100 b; }8 |1 ^' C1 A4 {1 o
    116 P. p* V% `" y! [3 I# R) \
    12
    * T# R9 v1 `  X13
    # B+ M! B; t( v$ V  a1 ^; M144 R+ g; U# S. r$ H4 t; ^9 r
    15
    6 n: {' d, |) D% [* o( p/ u4 T169 E7 u! K( @, `& }' E0 ?
    17
    5 z, w% \; Q8 q- D18% j$ j9 O  S  b2 S% `
    19
    ; j+ n3 \6 \( i. H; i+ J! u8 s20+ `" k# Q' }: G! o/ D0 _& H6 J
    21) H2 g9 \8 f7 u- v
    225 w+ P! k0 M0 A9 _5 D
    23
    9 j( F4 Q& M" b& h24
    ' K, A/ f" o7 j$ z" E* d25* B* Z0 ^0 E5 Z: W
    26
    ! m2 j4 j5 }% O' n7 I) H1 z' @27) W* p( M% q6 D! O! m
    285 C! s; v/ K& Y' Y
    299 T# }0 {: _0 L) F4 [
    30
    7 p* L  _# F. M* X8 A; Q4 p( ~31
    2 d6 `& [3 ?: r  e: m5 i32
    $ y. r9 o5 A, M. i; d2 u33
    2 f3 H" b! d' J/ D34
    ! P4 b+ q/ ?" a) `35
    ; K/ P& g/ }7 p36% r8 J/ N9 ^% [$ d9 _, H2 G0 D
    37
    ( h4 Z. H4 W4 p" y6 m1 x4 _38
    5 r/ v3 e2 h  r! }% a39
    8 z1 P7 B) V+ M, K3 @40# O' y' M. ?1 n& w2 O
    414 y2 m# v) ~+ ^
    42, f8 y$ ^+ w; Q
    434 o* U, ~  b- Q9 e% `* Z( N
    44* f& ~. u  r, c! M! ]2 G
    454 J, K8 I( M4 k! t, t
    462 j4 I( {1 L, D' l3 f& @8 J/ x' _7 q
    该方法质量较好,但一张图片大概需要12秒。" Y: C8 \0 A# S# U* W. ]
    6 [- q9 F" @% {/ j2 D8 k

    ! v# f2 [0 _- X2 X0 k; l. _- s: j" A: q0 r( I1 ?, G9 E
    方法四: Background MattingV28 i7 \, V, l0 s" y8 @7 W& I
    Real-Time High-Resolution Background Matting# o! S' `" A- y% V' k8 j" [
    CVPR 2021 oral
    4 h; t4 o+ u+ d: D, \8 Y  \( u: x+ _6 Y4 `
    论文:https://arxiv.org/abs/2012.07810& O% b% @4 e; S* H9 q
    代码:https://github.com/PeterL1n/BackgroundMattingV2( H9 P' [5 X% q

    $ v6 p5 o" j; m9 Vgithub的readme.md有inference的colab链接,可以用那个跑+ W  a! C; @1 S- [
    7 h6 r# S8 c* s4 \! i7 I0 k
    由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。
    + f+ g9 b: X% G  b9 m+ `( L# ]& N% M' j( O. U% f
    于是这里我需要生成一个背景图片。
    ' O1 E- B$ A9 u' g' \首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。4 \/ M- W2 x1 U. _( R! _/ X

    # e  x) |" [; Z0 @( m* P, D然后生成一个背景图片。5 {+ p! `1 A( c
    ; g& X0 m5 C) v1 T$ q9 z
    import cv2
    + ^; N0 m. O, b$ yimport numpy as np
    1 v% {* T* |5 T  N  G9 ]7 ]" T+ Q- e, L$ J. B+ \  {
    + q$ C; e1 k9 L. \
    image = cv2.imread("origin_png/person.jpg")
    * N' e& c5 C3 s1 D1 Z1 z7 Vorigin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值& U" ^3 ^$ a1 K: R
    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    8 e+ C: z9 O; @6 I1 \1 p2 eimage[:, :] = origin_bgr
    ) N4 T9 U% K3 {$ {. m8 t. `1 E
    + O8 O% v7 K  b+ B% K8 ]+ A+ X' ?1 u( mcv2.imwrite("mask/bg.png", image)
    3 v0 G& k/ c2 m3 k$ |- S/ r9 y+ U1( h# G6 \1 f. I) z0 G0 F4 B$ o
    2
    8 ?6 Z7 H" P9 k+ ^5 Z3
    5 }2 L# E: ~' F4
    0 O, z2 H3 r' _. Z, ?+ ]5
    $ b: K# e/ n1 O( B9 a, k* N% L6# I" X4 p8 @1 U0 M  X" D
    7  {6 p1 i4 _7 `# b, g
    8% v+ f: }1 A+ V/ ~& ^* N* A& d
    9
    7 l7 w$ Q  G7 m2 `, O) M+ z# v10
    * @' y7 r8 x/ a( k, U0 k6 m, W0 V9 _, k% A3 n
    需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码
    5 I) w* V; o5 E! F$ {) i+ [9 Q! [
    src = Image.open('src.png')2 N* {( Y% a0 N* X# `  D
    bgr = Image.open('bgr.png')
    * w  Q- a- Z* A& V2 H  V1$ T$ \% O8 H/ x
    2
    5 _; O  a6 M! e. c, l; }另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)
    . ?- t. t  D. w+ p5 F1 w; f
    9 U& s# w3 a" e3 ~1 ^com = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)% t* Y5 H% ~9 ~, ]3 b4 s7 r8 Y: I5 L
    19 j; N* w3 s+ O6 Q8 B# q/ V& _- b
    - i! L) X& K( d  n# ?2 `3 }" }
    那么加入我要换白底(255, 255, 255),就是
    % m2 ~3 b: C3 `; K. j. u7 u1 C6 d4 |6 J1 k* @3 z: _
    com = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)
    ! y- p/ @6 p( I9 E; p3 o! a. ]* w13 @5 i; x* ]( _, c7 U& D
    % X& R: H3 M" v- e- d6 C$ I# Z
    假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是9 f6 j" K! A: D5 U8 C

    * q2 W! }; v& @  z, bcom = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)7 M1 ?2 Y7 s; z) x
    1/ H. _& o( v$ z! r6 @0 v; }4 q
    总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.& e6 ~! D* }6 s9 j- `
    $ z' ?5 a' r# S2 z5 |8 N; @
    然后就输出图片了。可以看到效果相当好。不愧是oral。5 A: b! A0 {4 j( Z" o) |1 _
    ) g3 E3 v, I" j: c0 U

    0 U7 h# m, b, Z- N% d2 A原论文可以实现发丝级效果( c& z' ?2 E5 S* X

    + X. g, s6 P4 ?1 d7 |
    ' h+ l$ N  x9 f& A1 [
    ( R& W2 p. W& z2 w3 k' C9 D
    * }* I+ f9 J2 P7 M
    8 [- O( Y# Y+ r3 w- l报错解决方案
    & p! G$ a0 U# I2 z! \) s5 Kcan’t divided by 4 / can’t divided by 160 O" @5 H( D# p7 h8 Z  x
    由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。
    & d/ d* l8 k7 Y5 G这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize
    . _: ^* f4 L' l2 a* n" V6 B————————————————
    ' m/ Y$ ^% G3 X  t' b% u) O/ X版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ) @& [' L* M. F8 E4 F原文链接:https://blog.csdn.net/weixin_43850253/article/details/126376767
    8 p4 B$ c( }+ I* s1 N7 C- E- S# s; {8 J

    " H; G8 \& e" `) G# ?4 P8 S
    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 06:32 , Processed in 0.288868 second(s), 50 queries .

    回顶部