QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2090|回复: 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将红底证件照转成蓝底* q8 I% X! R5 R, C. y# L
    前言- s4 j  |( z' ~2 w; d, K
    emmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。
    & d' M( s9 j' a" Y0 `) I. w* S' |2 N/ {5 I* L8 S

    , q! {9 V% v) E$ W5 Y- ~8 f4 V" o. j4 \7 z! k0 r
    7 x3 ]; Q) F5 Z1 W9 h. [! b
    方法一: lableme2 ^% W# v% e2 A* B  D( z
    lableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.
    5 i- m; _9 U- `! }/ z( E# s% U3 i8 w. Z" L7 t- l+ \
    # 代码来自 https://blog.csdn.net/hello_dear_you/article/details/120130155
    - I! s$ _/ }( ?& F/ d) ?! `4 n- v* Cimport json3 P3 b5 I5 I9 S4 D9 L% _
    import numpy as np; y! C0 x- |* \: t) ~
    import cv27 ?- {" W* f+ g. t
    # read json file7 P3 O4 I1 p! `. X0 W+ V
    with open("origin_json/mypic.json", "r") as f:( E- J3 q5 x9 N5 F
        data = f.read()
    ! s; E& s9 l- t  f+ Y6 X# a+ s/ J" X3 l3 j# ^3 E6 k
    # convert str to json objs& ^: W$ B3 x0 |( ~: d
    data = json.loads(data)
    ) Q2 F6 J& B/ u) ?" Z
    - x& e3 Y' y( }# get the points
    , O/ m0 m2 v) z+ a0 m7 tpoints = data["shapes"][0]["points"]: Y  Z3 {4 `4 `* d
    points = np.array(points, dtype=np.int32)   # tips: points location must be int327 h5 n2 E( O7 @% M6 \8 \" [2 A

    # w# L1 U1 R$ i) d) l$ I& }" u# read image to get shape
    9 Y! {- |6 q) Y0 S. }' Y- D8 Aimage = cv2.imread("origin_png/person.jpg")
    8 L  v+ Y5 R6 ]& j9 ]7 H& L) `( V: N) p
    # create a blank image
    : _1 W! m/ g. O& x  g* d* Imask = np.zeros_like(image, dtype=np.uint8)
    4 ?9 Z$ y/ i9 C/ L6 _8 _2 m6 s$ p! e; j$ D2 j  w: l2 v
    # fill the contour with 255, \& @2 {' q+ Z. t+ o' ~
    cv2.fillPoly(mask, [points], (255, 255, 255))
    ; s0 N4 g/ s$ H  n5 ?- j, _6 k  ^
    . X2 {- ^: b( T. P' |' }( g# save the mask & B: x9 a5 {+ V  q, J; \8 S% p
    cv2.imwrite("mask/person_mask.png", mask)
    - i* \! x( {/ h; |* ]) A9 @$ j1  `* Y/ u& C' d
    22 y3 l6 b! g# Q+ R3 X# z# P5 t; z
    36 f3 f9 V% |' l( }6 s
    4
    * g) |6 n1 s8 A* o! H4 F' X! `5" o$ M* b5 r' {3 W
    61 Q5 W( f  L- d  ~2 n5 P5 v
    7
    # d; I  m" J0 F7 Y, [8  F% q3 \! C" z. h7 Y
    9
    & O" a. |/ n2 s# b  \* {. Y10& d5 V/ e5 g: P
    11
    7 |8 A+ p1 g4 e" v% y6 S127 S1 S. m/ N' v
    13
    : i& M+ H" T4 k" z* K# [- x( l14
    + Z! T- s4 |3 q) n/ G5 S15
    : e( _& q' ]" R* n1 n16
    0 s6 f  m( D& C# g" }; g3 h$ i17* \& [0 _9 T8 ^" Z1 p; j
    18
    6 e% Q. y5 i2 J. o& V$ h19/ ~9 T' F; U. W3 s2 l4 P1 D
    20
    , d& Q1 n: Z  P+ p- n21. X" q# f) v' f1 |, y& \
    22( W4 S5 T2 \- p
    233 {1 p. y# U1 @# o" v- ?( z3 v
    248 @, C4 E  [" ]+ w
    259 F$ E" [* K- h2 P9 u/ w0 l1 _
    26- q# f$ e, a- F- Y& q
    大概是这样:8 v& ~/ G3 x# U

    9 T: @( M/ i0 E2 _. L* u' [6 C; {$ w8 c& `
    然后利用这个mask生成图片4 F; G. I3 x  g0 p5 G0 c8 x/ F+ W! v

    $ s8 I) ?: _9 h) Q4 k) o; r" z# 参考自: https://www.jianshu.com/p/1961aa0c02ee- }/ {4 L/ O/ V
    import cv2
    / y' q9 v! A) j3 Vimport numpy as np
    % c0 v3 d; W, f7 w" Y! i5 k
    1 y. L  x0 W! G$ O5 V' V+ r* K! b, z; H# ]5 z1 W8 Q
    origin_png = 'origin_png/person.jpg'2 g$ D* M1 K: L2 }  ]) o
    # maskPath = 'mask/person_mask.png'
    5 T  Z: f* P; JmaskPath = 'mask/bmv2.png'
    " \9 f! z3 U- q6 Wresult_png = 'result_png/result_png.png'
    5 ~7 n! ]' T4 C' L! y7 W. T
    & p4 q& X$ t& u* w9 Q! D: d' U: W6 v
    maskImg = cv2.imread(maskPath)
    ) H  B% ^2 c. ^( Zimg = cv2.imread(origin_png)
    2 v% h. R/ u9 `6 G5 C$ X' yassert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'
    + m/ \4 d5 V5 e. E$ q: Y7 z5 e9 o. p: Y( @8 _7 R/ E4 f
    h, w = img.shape[0], img.shape[1]
    7 K& J& u# z5 R8 N  u( ~print('图片宽度: {}, 高度: {}'.format(h, w))2 D+ v! j. t% _* a+ Z

    6 a7 n2 N$ \  D+ Hrgb = (19,122,171)
    8 ?: {$ R  ?8 H, y1 y) r1 S+ i; K) wbgr = (rgb[2], rgb[1], rgb[0]): R7 z7 R  Z& M& z+ v- V
    # (B, G, R)
    # G9 I1 c- X% ^5 d8 b; M" ifor i in range(h):* x5 Q, S- R" F: _# i
        for j in range(w):
    3 [1 f% p; Y( m# _$ R        if (maskImg[i, j] == 0).all():% W- a! S, g+ J
                img[i, j] = bgr5 X- x# N  b( e- O: s, ?) E
    cv2.imwrite(result_png, img)) B& S, l; P/ X& j3 Q) U
    print('图片写入 {} 成功'.format(result_png))6 V2 B6 ~, [& @7 L" a1 ^
    1$ |5 X! F# Y" ?0 r: p
    22 `8 l1 ]& U# h9 P: T  |2 b
    3
    $ \( @' j: u7 \4 w3 R8 L# J$ Y! n48 P" Z- m; g1 t( r/ v
    5; Z; r7 i1 p& P& Q
    6; C6 ^6 O3 T% M. {$ ~
    7, Y1 k* z; ]  Z4 n3 K, O1 H
    88 Q; Q8 r) h, g( @2 e
    9
    $ w, z7 q! |; s5 z9 Y/ L% J! X10
    % g; a; b. ~* t% n0 Q! A7 j11
    . K. h4 C& G  l12
    8 k0 Y, V9 E- _; U7 V, o, B: Z13# O$ o$ k4 g3 f
    14
    # G/ H1 z0 Y5 _. q6 u15
    ( ^- y/ K1 B2 z; v16
    ) @( ^7 X! ^' Q! c/ g- n17& l( Y- S. Z* h  N: ?; |
    18, S% K4 S/ u# w3 M1 K! I# ?
    19
    + G( h) ~5 K( c/ T) i: [8 O' ~20$ M- R' W# f8 A! U) @
    21
    0 e! O$ r" x$ e& u. S$ z22
    - D5 `# l  |& Q- u230 m5 O- \; ~: t" r  w
    24
    ' l* t9 B* o! A/ R! k$ ]5 `25- _3 T3 @" p2 c8 e- M
    26
    / O4 D, p( j( Y# o6 {( Q, }274 Z8 T! j- w5 t/ h3 q" W) ~, a$ s
    由于人长得一般,就不放图了…
    # u, ]+ V  w: M+ m" |
    ! H! c$ w8 z8 q" y+ C1 P3 d缺点:
    / U* z3 ~! X0 }# \! U6 {lableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。& \* ~* r3 s- T. C* m" l
    + }6 y3 }6 m3 ?: q, O

    ( B5 G' A& z# s, [0 V7 \' {
    / Y; U# i6 S: l# k$ J  H3 |" P+ W) o5 `8 C: c( N  H* u
    ( k1 l& q" k) p
    方法二: 阈值1 N3 {# W* e6 b5 U% H
    该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。
    4 K7 S! V" L9 ?' A' E. Z+ {
    6 y  l4 x) j3 @' COpencv
    * X1 U; Z1 C, e0 _/ D" Mimport cv2# T% [  O, J# E* O' o' F
    import numpy as np$ B( z- v4 z- ?, A

    $ R) N' d0 A% E9 c0 E; Z# n7 A8 T  N5 E
    def mean_square_loss(a_np, b_np):
    ; i7 s, n$ G! H  h    sl = np.square(a_np - b_np)4 g# X1 I) B; N) I& l1 X2 J8 k
        return np.mean(sl)" S. k9 c- t! O  F
    ; A7 X; W1 N" n% w
    3 ?1 s3 g+ U' p8 R$ {. O
    def change_red2blue(origin_png, result_png):% {5 {9 C! U+ @- s
        img = cv2.imread(origin_png)
    + A! b; T$ j6 F5 ?- |% @  I
    6 I; z& p; W9 o8 [: e    h, w = img.shape[0], img.shape[1]; }7 }; d1 L. K4 d
        print('图片宽度: {}, 高度: {}'.format(h, w))9 p$ Q2 H  g. j
    7 O) y, Y+ B& a6 O( \+ c
        origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
    ! D: S& a/ o1 d    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    0 e! _& o) q3 k2 |0 `% c0 X4 J8 M    target_rgb = (19,122,171) # 蓝底RBG  F9 c6 K- }9 P+ y$ V: W* j
        target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])
    ; m2 r3 ~( M8 H7 Z
    2 g; }/ Z& w; h* {3 v    for i in range(h):5 \. A2 ^  O! C, {5 @
            for j in range(w):) t$ j7 e. B! q) B+ M; f; @
                # (B, G, R)
    0 b- _/ e9 _  o1 }" o8 V            if mean_square_loss(img[i, j], origin_bgr) < 50:9 p# V8 c, c, v5 ?% F# g
                    img[i, j] = target_bgr 8 V3 P& p. d1 t

    4 e! ~& }; D. |& X! s; ?3 e9 k    cv2.imwrite(result_png, img)
    1 ^% [2 ?% C$ y2 A7 L$ M! h- x    print('图片写入 {} 成功'.format(result_png))2 F9 a; X' ?  k. p5 l
    / K3 z5 @8 {- D4 Y7 [
    5 g% K) ^' @# y6 k6 e) ^7 Z
    if __name__ == '__main__':  t! I) P) r( l' S: f' l9 y4 V$ Y
        # origin_png = 'result_png/result_png.png'
    5 {1 R; E+ N; x5 j" i) D" X    origin_png = 'origin_png/person.jpg': Z/ h+ M4 y5 E6 V0 N) q# U3 v
        result_png = 'result_png/result_refine.png'/ U" q& `/ G2 S5 y  M1 P
        change_red2blue(origin_png, result_png)6 \' i+ N: A* a& O8 y
    1
    + }; W2 V0 S. C+ z, C' w2
    : k9 L  |' e3 E! T  K+ a3
      |) f5 C+ B7 A6 w; \42 I, o7 Y2 h/ u% n9 C
    58 K; F# S% ?& o: P0 p
    6( G+ U/ ]% ?% y/ n# @1 W5 c9 Z
    7
    4 ^3 w9 \2 P# Z& ?1 k8* u* }, h3 O3 l$ z! K
    9
    ; x+ X, x+ |+ U' B& E6 K  U10
    6 Q7 }# `# \3 S# j115 Z% Q& t1 C1 c" _
    12/ @, X  J) x1 c, ^/ @. N
    13
    ; D3 T7 T7 W  u5 E( i7 e+ P6 [" F' M14
    5 N/ x1 r; t) i2 S; L: i6 x( y0 q15" L- f3 p5 b4 L# R) l
    16$ ~4 _$ I& M9 ]7 k  U6 U, Q
    17
    2 D4 k4 e  G" Y/ Z8 J' M185 w  k1 s2 p1 h4 q$ c, s
    19
    + t  _1 h& N. h) a20
    4 B+ P( b- p2 [6 ]/ S. W. J21! O8 b3 u8 L4 M! Y) A6 o* S
    22
    " I6 s: v. d2 f( M% p" \! y" d23
    : k) S* }$ b6 u. T5 u1 l# J24; Z7 w, S" R1 `( j8 t: Q' C. O
    25/ ?4 J4 }/ M$ {0 i8 |
    26
    8 p! H. Q/ b) s3 S7 q" h. n27& {+ v# K4 N0 s0 U4 W. _
    289 S2 d! O/ |* l$ u
    29
    / r: g- W/ ~* a" f0 e. \9 d308 J0 c: h+ L" Z  }' t3 F- i
    31: g9 ]. W/ F% Y0 B% |0 `
    327 E! w4 Z: V) |) c
    33' N. M. t/ P/ I! ]/ T) ?
    344 E0 G' `% v- Y# ~
    35% T. K/ u" a3 m' i& J
    结果人与背景边缘仍会存在红色像素残留
    9 d# v+ E" d* ?  \& m6 u9 C& U; }3 b: ?; U3 M+ b$ j

    8 V( w' z! z; j& ~1 q- K& ]) p* Z% L

    9 d% V+ P' D$ _- p/ ~7 c- n% M
    5 f$ w& P' B/ l; W0 a* @, [PIL2 t. z3 ~) D  U/ ^& a- q& N' r# l: k7 a
    from torchvision.transforms.functional import to_tensor, to_pil_image* x6 q7 w  S/ G7 A2 Y; g
    from PIL import Image% |! P: n* Z$ ?, E& o, o9 @
    import torch# J: B5 |; ]; q6 q; C3 T
    import time" o* L# j, z6 p2 `

    / @: o0 @5 Y0 H+ T+ D. c# G2 V1 T5 o2 K: Z* |/ E3 V/ \' {' T
    def mean_square_loss(a_ts, b_ts):
    " e+ P& d0 v* L" v- Q    # print(a_ts.shape)9 r: X0 l7 c) O+ q
        # print(b_ts); e2 Q! ~- ?5 j  |6 I) h
        sl = (a_ts - b_ts) ** 2
    % F* ]+ T# \% \' `    return sl.sum()" I! t% e2 F" ^$ ?7 Z

    ) A# T3 E- w5 ]6 t+ @1 p, U1 X# B+ x4 J$ Y- x8 ^* O
    def change_red2blue(origin_png, result_png):
    6 v+ ?9 @# Z5 |    src = Image.open(origin_png)
    0 b/ W: H, d, G- Z- g, u    src = to_tensor(src); X# ?% }! K% K2 i: W; n
        # print(src.shape)  # torch.Size([3, 800, 600])
    ' C* ^- \- y; h+ p0 W) w+ u    # channel: (R, G, B) / 255. y( I) k, D! ~' J  D
        h, w = src.shape[1], src.shape[2]
    ) C/ j( i' l8 P+ K8 r% o" Y6 |+ C( f
        pha = torch.ones(h, w, 3)
    ! F0 e4 g6 j4 f  F7 X) P
    6 s% A  o* Q3 O    bg = torch.tensor([168,36,32]) / 2550 q8 ~' k/ x+ r
        target_bg = torch.tensor([19,122,171]) / 255
    ' p, y0 C  O$ S2 L' Y
    * c( V1 s% [$ l, H1 H    # C, H, W -> H, W, C) @3 z( F, b: [8 m6 d" [0 ]/ Q$ i
        src = src.permute(1, 2, 0)! E$ S8 [* ~6 A9 M8 `& Y
        for i in range(h):" t6 X! j  V2 ]  F/ W" W
            for j in range(w):7 C, ^$ ?7 y. _9 e% z" l% B. T
                if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数
    4 i1 D, v9 P2 M; D: `" z                pha[j] = torch.tensor([0.0, 0.0, 0.0])- i3 N; K( s! L  }( T2 h2 C
    . `6 I! j. n' H
        # H, W, C -> C, H, W
    3 p: J6 }8 r/ D! h! N) f    src = src.permute(2, 0, 1)# @& Y( C1 b1 ^# R  V" }
        pha = pha.permute(2, 0, 1)
    7 z. R/ T6 ]: T    com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)
    / K+ L" i. u, E# \1 E: _0 Z    to_pil_image(com).save(result_png)" Q$ R9 [2 S0 M9 Z  m

    8 |1 v2 Z, j4 a7 M5 ^; m0 z0 E+ x& I4 u- V
    if __name__ == '__main__':% X. ?: G+ p+ J8 G" v" o; f6 P
        origin_png = 'origin_png/person.jpg'7 {3 q+ m+ e) b7 |; F0 w
        result_png = 'result_png/com.png'- _  ~% m7 s5 P
        start_time = time.time()
    # C4 ]  \( z3 _6 v    change_red2blue(origin_png, result_png)  h$ w+ Y- N; H0 ]( ^' E! I
        spend_time = round(time.time() - start_time, 2)
    ! a7 O0 Y* I* f+ r4 n! |7 Q    print('生成成功,共花了 {} 秒'.format(spend_time))8 c; C( n9 |; O! s2 X8 i- o
    1
    9 x  h; o& I/ ]4 Q. P23 i) ~( M& P4 w" f: \
    3
    5 G) p; f- e. [* Q. ^4 S4
    2 Y# s* o( C: t. {5
    4 Z5 {7 U: d# R% o* h: L6
    9 u3 A1 h0 s2 I' J5 j  G8 E: T6 X7+ A9 o3 q7 d  j. `' P
    80 w# M4 M8 q6 d3 M
    9
    3 m; i! D( n5 c8 {10
    % ^3 c+ t3 }% z; Y* m  `11
    2 K9 S7 f4 i' G- S: u; q) Q1 E12
    & i0 I. h/ D. o1 D13
    8 O( f8 f) A6 V149 O9 F9 ~( {5 z( t" i
    15) h6 J9 |6 [9 J, u+ d1 f2 y
    161 ~1 D8 u" {0 U4 X# U; {6 Q
    17
    " a1 @4 p! l7 l7 v3 z; b5 M; J18+ k$ c1 D$ V- O4 O  b5 O# F( o
    19
    # G- d* ?) U) H7 S6 Q$ z2 b+ f201 [& x9 h( H( I3 D% M
    218 e0 g) M3 ^( e) u+ E4 L
    22
    # {! z8 Z' K7 P2 ^! c8 L% M( v23/ x6 l; T( n# i7 k: _1 m& n* x
    24$ k2 ]2 A$ O% Y: L, q
    25* I$ s) G- D' M4 y4 O8 \
    26
    * t  y+ o1 y3 E: ^: h) O* ~276 z8 i& u- H: r1 |: n
    28& p/ {7 l0 |* \' ^- H
    29  z3 g# Z& A9 n7 g& ^
    30
    ! R! t: I' |5 ~& o31
    , P! }7 w- G* @; D) @326 w! h  }; H2 [$ ^0 Y. E' D
    33
    3 K, X7 q/ b, o# D34* u$ g% P& E* i( ~0 U2 h
    35
    & T0 E0 \) N4 S6 H7 l1 Y1 t36+ n+ b+ `3 h7 \$ U- j4 f1 I
    37
    ! s% _5 b; Z! Q5 j7 u" D5 P38
    # |. k; r" p. M39
    : A1 W# q" Y( l( T406 m7 q) X/ l3 t0 b- v4 `
    41( g8 u) g% ]9 B! j+ C
    42
    + Y2 P: ~) f! H# B432 u9 l& O7 n& g* d  \
    44+ c0 V' t* R2 E9 A" s- K
    45
    ' M6 F. Q+ x, S4 a( v  B" _46# }$ `+ [3 a6 c0 Y
    该方法质量较好,但一张图片大概需要12秒。3 U0 K0 P1 M1 t" e2 r% q

    ; ^6 K( E# h1 P4 [7 O, s
    : _9 B1 t' d: c6 z$ b* C. s+ z6 a1 ]" k+ J) A, Y4 |) r, ~
    方法四: Background MattingV2( `4 T/ d. C) B' A' Q
    Real-Time High-Resolution Background Matting
    * L' v7 E1 V& g, F2 M, PCVPR 2021 oral
    8 M9 N! N: M& S, p' A; j7 r7 v& Y3 q# p( Q
    论文:https://arxiv.org/abs/2012.078108 }+ O/ |3 Z1 ?) d' t
    代码:https://github.com/PeterL1n/BackgroundMattingV21 ~5 o& }/ S  S* l+ |
    1 _# i1 e; x1 j9 ?0 a3 I5 X9 |
    github的readme.md有inference的colab链接,可以用那个跑2 n0 `2 H7 l, Q* g+ _7 s

    4 A$ Y) c6 S. U( @4 g0 C由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。- q0 }4 e0 @# K- U; q
    , ~. {7 V( u! `# ^
    于是这里我需要生成一个背景图片。
    & o6 g' x6 J2 [6 n5 l+ e' `! @首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。
    . w6 z6 g- p4 E
    $ V# m$ k4 o9 O. l然后生成一个背景图片。# ?1 M4 A# q, L( \6 J. @( w8 \$ f
    1 s& d3 M  o5 p4 ^" t% K
    import cv2
    , G, V" j8 M, L' Eimport numpy as np: e% Z4 B) \" h6 F. n- z! [( [4 ]
    / |. T4 U. m! l1 x0 R, ~: q! W) B

    . s5 J0 U9 R  o3 v* `" }image = cv2.imread("origin_png/person.jpg")8 _3 F! b5 s/ X% h
    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值* B8 Q# N9 Q# ]+ A
    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])# \7 ^  `) v8 s0 R0 N8 M4 U
    image[:, :] = origin_bgr
    & `2 f. k% z9 Q! `* c* u5 P0 }9 U' {
    cv2.imwrite("mask/bg.png", image)
    ( S: C9 e1 u* u9 A1
    4 b5 K8 ^2 K* U8 {2
    ' f9 s4 ]6 K6 p' h* [3 m3
    3 S/ w+ V' B4 w4
    + B) `4 [9 a" i5
    $ p8 L3 e5 H, I4 j4 z  Y6" g( ^1 b4 `) V* [) v4 S
    77 w! {/ {8 J5 B% X
    8, [' Q" A& G4 r. [3 e" O
    9- {) u* O+ y9 w/ t" O6 X7 _# X/ k% \
    10
    , v- Y, c% Y. y1 ~2 X1 e* w/ C2 u! r9 x& ]4 K
    需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码' a! B0 `9 h9 C- a: W) K4 W5 l- T
    + J6 ?/ d, x) g0 `! _2 s% D
    src = Image.open('src.png')' x% C" c+ J/ R! t
    bgr = Image.open('bgr.png')2 O- s. `$ R: E; {7 u* B- i+ h3 E
    12 @8 s) C0 d4 |7 c( w" ~
    2* X/ f4 D1 Y3 f
    另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)6 T) Y# R  c7 I0 x: R3 N; Z  A
    ) l; ~0 I4 P$ Y5 v& K9 x9 g6 O0 S- l1 `
    com = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)
    4 [4 U6 ~7 _4 h& f1- d3 x- i0 V! b/ [: n
    2 O/ m/ u; v8 x, ^& K0 c" c% N
    那么加入我要换白底(255, 255, 255),就是
    " V% d% ?5 h$ J3 f
    : e& m# r/ A  c" C9 D6 F. E5 ^com = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)- n6 p) N4 l6 j$ ~8 O8 l1 T0 C6 E9 ]
    1
    8 C% H( R. p% S( K# E
    ; W( I/ S" R% t( z' k; W" \8 b* }假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是
      t3 P/ ?1 D6 u" q# w4 z4 P; ?9 _! p8 B* J6 b. t
    com = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)
    1 N2 ]- u1 p0 s) }: D1
      `. P/ _+ H3 F5 w/ R总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.# B8 U7 _8 o" x9 Y9 m7 _

    5 L$ V% Z9 t( ^: y然后就输出图片了。可以看到效果相当好。不愧是oral。0 h& h- q; M# G

      `' r5 Q5 N: w. J
    / T6 A; Z: \5 N+ ?9 e; G2 ^原论文可以实现发丝级效果- I' D: X* {4 b" Q8 R' |; T6 Z' [
    / b5 j4 N1 ?" n) V
    ' n. Z" w+ V- \) H( t, T

    + T4 U, e+ \; h% p% W7 ]" j
    4 V% D; w% u4 J
    9 i# a+ m$ p6 |报错解决方案8 w$ }7 ^  i$ }! I9 m3 ~' t
    can’t divided by 4 / can’t divided by 16, R$ l. b& m; ?' ^7 \3 ?- h; d0 |
    由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。2 a& E' D  a! ^( p7 y
    这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize
    $ E9 @: \) v5 i1 X5 u9 [————————————————
    ! ?" b- k0 m  g4 V' T版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    & A8 \% R. ?$ f7 V原文链接:https://blog.csdn.net/weixin_43850253/article/details/126376767+ q: t7 ]0 H: c' ?
    % v& ~9 R+ K9 Q- G- L; Y+ `
    5 s8 b+ w( a5 V/ 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-4-12 09:31 , Processed in 0.333542 second(s), 51 queries .

    回顶部