QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2125|回复: 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将红底证件照转成蓝底5 a! c) G- B4 F. T1 n2 Y3 r$ K
    前言
    * _1 Q& P" J, G% ]0 T4 eemmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。
    " `) {" a. N2 j/ p" t, b& k7 M- ~2 W; ^- O" x6 n6 r  e

    ) Q9 v3 i+ D, H* A4 M0 J0 c" ?
    % R4 G7 ~$ u3 f. r/ h7 c$ f. x
    $ T& u7 [( W3 A, D, @方法一: lableme
    3 K) L- e  b+ G$ o2 @3 n" Olableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.  d4 g1 g1 [, X  N& [9 P$ \. w

    1 x2 \4 [; z" {" g; W# 代码来自 https://blog.csdn.net/hello_dear_you/article/details/1201301556 H8 p" C3 ?2 p, q
    import json
    9 I. E# U; R, P3 ], d- `import numpy as np0 @. N& F; _7 w6 g7 \# [5 e
    import cv22 ^- r: `% M" p& J0 Q4 g* _
    # read json file+ X5 S0 t. ~+ M. f9 J+ x, i2 K
    with open("origin_json/mypic.json", "r") as f:
    & C6 ?4 w9 R: o: n3 v% y# ~    data = f.read(): h' b6 q3 E' _
    5 E( j- S! }2 D- q. A& o& `
    # convert str to json objs9 k' z7 X5 h  `
    data = json.loads(data)1 a7 J8 U" L+ Q9 `) e
    . w( E3 c; _8 M# Q( {0 d
    # get the points
    / S) n7 P. m+ K8 wpoints = data["shapes"][0]["points"]6 g, m+ H+ n0 {
    points = np.array(points, dtype=np.int32)   # tips: points location must be int32
    9 V0 L, k- b0 M3 T( S* [& q
    6 U5 _+ q; {4 ^1 \# read image to get shape
    , b+ O4 P: ^3 Iimage = cv2.imread("origin_png/person.jpg")
    5 B6 x8 \- }# ^0 {; A% S4 q+ J7 T! [
    # create a blank image
    " v. E8 \4 Z" C2 p8 A6 g: `mask = np.zeros_like(image, dtype=np.uint8); f: S5 v% }9 }# l

    ( N% k% x" w- v( R# fill the contour with 255( d  Z+ z& S/ |; s  Z1 Q9 r
    cv2.fillPoly(mask, [points], (255, 255, 255))
    % h  n2 k: n/ g7 }# j7 _* M- L
    % w8 v" I# I# j% B  ]1 ]# save the mask " e) z# \! `3 a, Y* o
    cv2.imwrite("mask/person_mask.png", mask)
    % y2 i8 m3 T9 `3 q$ }# ]1
    : H9 s& J0 d$ M& r* D; J2
    * n) x+ W2 i- y, ?  L0 A5 y3
    2 R% D+ a. ~9 b1 w+ m4
    " V& z( K3 j, L) c  }* O/ L' \5, ~0 ?! M' i; h; i' ]0 u
    63 R. ~4 M0 V. [! ?
    77 G& o- j3 t- j8 ^
    8
    + t7 Q& R! D7 j( Z5 ~; v9( g3 X: n& ^) ^! T6 K) A
    10
    7 R) {. ]' O+ T8 j% W11
    ( A* V, H- v: ]7 ?! d8 K: c4 `12/ W+ ?) j, N+ v. E% q4 z2 D8 k) h
    13
    , O+ a9 x2 x4 u14
    $ @9 p% u: o; u; S15
    - k6 t/ Y2 {3 w8 P0 ^161 X+ K: _$ `( U( \+ _
    17
    ! z' G/ x  N2 r+ A6 U1 |& U' `18! ~3 K& B6 z0 G2 _3 L4 ]: ]
    19
    % Z: G8 L$ o% d20: O" w& v3 Z* j/ p+ }. d2 e
    21
    5 {. N: g* `8 p2 u- ]$ T7 e' S22
    $ y! h! E6 m" d: v& W0 Z1 W# ~23/ z# S4 V8 k+ k; d& Q: ~
    24
    4 F+ Z' ~) ]. w2 I; s3 i  [6 T25
    ) B" n, L3 y) G* _$ g26! X' G! n! W- o+ `
    大概是这样:
    / e& l( \+ Z+ k/ ~
    ( w0 R' I' r% q& x
    " T/ A: o8 v' g5 {( W+ i( g然后利用这个mask生成图片
    9 [8 s2 I( E8 N3 w
    ) \7 @% d5 x9 y# 参考自: https://www.jianshu.com/p/1961aa0c02ee, a9 c( V6 }: X" a( Y
    import cv2: K3 _0 D' R; b3 a7 Q+ Q! N
    import numpy as np
    . ^& f4 ^' N0 l$ D9 R
    - X! F- C, v* ]9 l. ?3 }
    & d* @; O9 C9 R% ~* S- Z4 s( ]9 yorigin_png = 'origin_png/person.jpg'2 J3 L% T, a6 P
    # maskPath = 'mask/person_mask.png'% m. o* M0 n( e
    maskPath = 'mask/bmv2.png'# b; y; d; y( E. {0 l( v
    result_png = 'result_png/result_png.png'
    , ]: [& W+ [# m+ ?$ U( ?9 ]
    # i6 l6 c% {7 L4 K) o7 Z& n# z
    3 T2 u: k7 U5 XmaskImg = cv2.imread(maskPath)) F' {2 L2 u" L" c/ ~! x& H* V
    img = cv2.imread(origin_png)  }" z' f' R2 v; D
    assert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'
    # s' z, K1 F1 s3 v# o- x% o- @9 N$ d7 M, H) l+ K  [% v1 p) o: J0 \
    h, w = img.shape[0], img.shape[1]
    # r/ I$ J  P, L# ^7 v2 Rprint('图片宽度: {}, 高度: {}'.format(h, w))/ t& {( B* ~0 P# Q
    , K7 M. ?& m1 b( b* F  O2 q
    rgb = (19,122,171)
    . ]+ W- m' \7 obgr = (rgb[2], rgb[1], rgb[0])9 {1 x3 O2 y* _
    # (B, G, R)7 P4 N3 ]. N( \3 M  u7 ^
    for i in range(h):" A. v; R4 U+ X3 u: I) i8 r8 z1 i; D
        for j in range(w):" I) t/ Z' L" X/ p
            if (maskImg[i, j] == 0).all():
    : r! U$ d8 M; E0 n            img[i, j] = bgr$ l* C3 d7 H/ \7 Y* `; J
    cv2.imwrite(result_png, img)
      T6 b6 O9 U7 b* A& U- f$ I, P& mprint('图片写入 {} 成功'.format(result_png))' x7 p. b# I. |4 C
    1
    ; C$ Y- x5 G4 q: h# h2" m1 u$ q8 I* [
    3
    # a. A+ W6 O& \6 R2 B* Q" I$ D4
    : t/ G; ?( ^$ j6 G+ B+ `0 a6 f" z5
    ( c; V5 I. [. o$ r% l6 Q: s6. z, N9 R' [/ Q8 s
    7
    9 ]6 n* I# C/ k8
    + t5 l1 M" d' [: P91 ]8 _$ l$ _- x5 L" K: a
    10
    ! r8 V$ \/ X+ f3 M  t# P11
    ' M$ p! y) h+ F9 }( w, `12
    1 T( q. P1 U" i# b1 D13
    ! W3 S* M2 q2 B6 `9 r# y- u148 Q% o) ^- f1 P
    15
    2 J. C7 s/ f3 u  O162 k2 U* x* V9 m, U, M! Q
    17
    + h" J, r0 D# @( y0 S/ U8 r18) o6 |" U/ K- b3 b
    19
    0 l* ]) w9 ?$ U$ X+ I) }4 {' N! h20
    / F% ~$ q- ?6 x# V21) W/ _6 X6 C$ B  y  w; V- ^
    22
    * z7 n, _+ l# b9 w23
    $ K" k5 [1 y# \( j% {24; _; s& w( }! N9 v/ c
    254 d2 Y9 j8 ]" x& f
    26. J+ Z2 I* ]2 X  I; o$ o
    279 q9 J) Y6 d! R; J1 F
    由于人长得一般,就不放图了…, Y/ r) S" y8 E6 y; }

    1 y8 w$ G+ T. o缺点:
    " |- f8 ^) P- ]lableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。
    ( H- Y3 B7 [, }. j/ L8 T+ k0 c
    1 \  M  H, y# j2 b9 J4 U+ [2 B% r. V
    7 a0 f0 R5 ?  x' p( @

    , l8 X. O9 H& p5 u1 `" F
    5 z6 g' r; t+ V' K方法二: 阈值+ Y, Q, r9 ?2 D7 I0 c4 D4 c
    该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。3 j$ @+ J" t- P. V/ j: a7 ]
    5 j/ J. m4 R  j* r! f8 n7 o& P
    Opencv9 J! c9 f) L6 m! `
    import cv2
    6 Z, J8 y0 ~4 g( Yimport numpy as np$ o3 V  }6 P, l* J7 N; l6 N
    9 s  c+ H6 P5 d- p- R
    ( ?- H4 E0 Y* r8 Z0 q/ e9 {& X
    def mean_square_loss(a_np, b_np):; ~0 @- r* S. {) e% y; G
        sl = np.square(a_np - b_np)* R/ ]2 `( P- Q& P& b: p! C: d: Z4 `
        return np.mean(sl)6 e, [6 C2 X' u4 X+ H+ H

    ( r& c2 @+ j4 z2 o7 D
    ' S% [# p* _( }6 i( hdef change_red2blue(origin_png, result_png):& F) e, H& l7 o
        img = cv2.imread(origin_png)
    * c: u% a* t9 s* O' V, \. P8 a5 W, V' }. h8 }) E
        h, w = img.shape[0], img.shape[1]. K0 v* ?8 p2 a2 Y- v
        print('图片宽度: {}, 高度: {}'.format(h, w))
    6 T9 b  z( u6 w" S' c
    5 }6 m' x. j, S, Q! d) p    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
    2 m$ n( o/ D9 @2 M0 R    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])2 U' r5 S0 Q7 t; k- q
        target_rgb = (19,122,171) # 蓝底RBG
    - [. v: V0 G4 f4 @% i    target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])
    / B& ~4 |8 D  E; ]* q& ?% g. _6 X, l/ _  P
        for i in range(h):
    % {( j( r2 u2 M# b' y        for j in range(w):; Y/ b& \  u% E. f6 o; h+ O/ D. f
                # (B, G, R)
    & Y/ E- t5 k3 h2 L- B0 k            if mean_square_loss(img[i, j], origin_bgr) < 50:; v* Z: ^: Q* f3 m
                    img[i, j] = target_bgr
    2 a; W& w+ j  [) }* Y8 w. A$ o4 _, D
        cv2.imwrite(result_png, img)9 M4 C8 T( {  \8 q$ i
        print('图片写入 {} 成功'.format(result_png))
    ' J7 U, W6 S' j7 e( ]2 \6 ]# d8 T, k
    ( y# ?3 `0 ^/ b* Z5 c8 a4 w
    if __name__ == '__main__':
    , R  i7 j$ O0 \8 j$ r    # origin_png = 'result_png/result_png.png'
    ; P. X6 y* \  P3 l; ^# U: o7 e8 q    origin_png = 'origin_png/person.jpg'
    7 v; [* {# E) U( ^: d    result_png = 'result_png/result_refine.png'
    / J  |% C8 `: d    change_red2blue(origin_png, result_png)
    - Y5 {; z5 I1 T% o' Y& k1
    & K8 F. `- e/ S+ v3 B6 ^  C5 e0 H2
    2 M1 o8 I" u0 p! R, h! z3( H+ l6 A. o! b4 M. _
    4% y0 A% e" A, ~5 n
    5
      D3 ~- Z. n. h, K6" R  f; N$ f/ p) L& x
    7
    ( a) f7 I8 A3 v83 \0 `6 X6 O; s, ]5 o' t) [
    9
    * N2 w- ~8 `+ G( L; m9 W, y% O5 j102 S1 U) A( ?! J5 o1 r% x: _. V: c
    11
    ! n4 ^3 f0 P, d12
    # W1 L" ~6 f* L/ {13
    0 |; a8 m8 E; V; F2 `& F# C14
    ' U+ {# O4 S0 \2 K* F  V15/ n) g( F% i" n
    16
    : Z' u: Z3 {; @8 G17
    0 a$ e$ |% i+ p18; ~9 a4 o8 Q) `8 s9 V1 A
    19( X0 L( q( E% l- s
    20+ l' ~6 |- u* A3 e
    21
    3 l, |# V: k3 Y& c& U: p' r227 a  u. N- s0 l3 G) B* ?0 m* V' m
    23
    . t( Z3 J3 O. I" ~24
    , a3 N* ]9 H# S/ I# `* N25
    ! u: o1 e' J3 B" C26  b' n* e) Z9 ]
    27( j' O2 i+ J. O! w" c
    28% Z. B- [3 c3 f1 q- q
    29: T, B( D# J2 y- h! X
    30
    " x) A2 V: ]+ ?6 u" q/ `+ B31
    - `  ^9 F4 t0 f7 A  f1 K32
    * x& j' w8 O( y" ^$ T( N( f* Z33/ ]. N( B% U2 x6 l: T* E: z
    34
    - C: {6 E& p1 D; X) v: Y35
    . Q: L9 h5 l! w8 J5 ]结果人与背景边缘仍会存在红色像素残留
    5 y. Y. c, O8 X! ?" l8 C  w
    + \: H4 p9 n, M& v  B) E
    0 u" u( S4 ?0 y7 Q* _# m  {
    * y" O$ I" ~% q: R8 n4 ]( o/ z( C3 ?5 R
    ' g6 M" T# v4 t7 U" l
    PIL! i! S1 V- {7 v4 [$ u& S  I% e
    from torchvision.transforms.functional import to_tensor, to_pil_image
    1 p' N$ p4 n  j: t, y9 h. bfrom PIL import Image# j+ S/ M) q4 @8 Q. T. r
    import torch( O1 s0 _# g! |4 o  Y
    import time0 u% C2 S5 Q6 d( i3 U; E  q/ b+ o0 i
    ; @4 n/ f  E* T% J, m( g) b

    3 w9 v* `* o9 e% H( edef mean_square_loss(a_ts, b_ts):5 ]' k$ r  c# ?1 I& @
        # print(a_ts.shape)% K, e% |3 E3 x. X3 e' c2 |) N& Q8 W' M
        # print(b_ts)
    - Q9 ]3 ^' ~" h/ `6 l3 O4 t; O+ E    sl = (a_ts - b_ts) ** 2
    / s; S8 o! {' j4 x" ~' Q    return sl.sum()$ {$ S; m9 C& [+ V0 S

    5 w1 J4 l: a5 H1 I. h; f& S8 c. x, k% K0 i" B" I) }) f% Y+ ^
    def change_red2blue(origin_png, result_png):& ?( a5 a# h* l
        src = Image.open(origin_png)
    ; M; I0 f4 X2 V4 j$ o+ A! ~  Z& b    src = to_tensor(src)/ _2 k) [4 @; t+ i  k
        # print(src.shape)  # torch.Size([3, 800, 600])+ O) n7 i8 Y2 ~# {
        # channel: (R, G, B) / 255: _9 e7 X7 k$ ?" I* n( E1 J
        h, w = src.shape[1], src.shape[2]- a, W8 \5 T. Y$ ?/ n

      }8 t. g0 O, P: g    pha = torch.ones(h, w, 3)
    * l: v/ E+ Z0 x
    - \% s0 o: S1 U* F; ]! G    bg = torch.tensor([168,36,32]) / 255
    2 Z9 t5 K$ U+ E5 J    target_bg = torch.tensor([19,122,171]) / 255% K* o( l4 J# b% |) r  h
    : [% _: l' M, I1 o
        # C, H, W -> H, W, C1 V+ o* X( s- f# h: Q3 x
        src = src.permute(1, 2, 0)
    2 ]& J4 h. v! y8 {% H4 {    for i in range(h):
    6 J1 J6 W7 G6 b! }% E        for j in range(w):
      s% A, S) H1 S. ^3 B# }- K            if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数
    ' `2 E2 ^8 k1 r/ A: J                pha[j] = torch.tensor([0.0, 0.0, 0.0])
    ( j0 L) c' n" V2 o  C
    3 _& e+ A$ M7 L, @$ {; E' w6 X! d    # H, W, C -> C, H, W
    % B! R- X  Z' o8 M0 W    src = src.permute(2, 0, 1)# f, ^0 p7 t/ [
        pha = pha.permute(2, 0, 1)' d$ r' y( L5 S. |3 `
        com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)
    9 [: x8 j( c" Q$ i9 w2 f% P    to_pil_image(com).save(result_png)
    " t; o# u. g. A8 L& M% x7 x: H! I; |& P6 G+ c

    ) [- J1 M# b' ^0 hif __name__ == '__main__':
    8 V" ~. q$ @0 t; g  L    origin_png = 'origin_png/person.jpg'! Z% K. Y7 _) S# |. {) {# Y- g
        result_png = 'result_png/com.png'
    + @. Q! c+ l% P6 ]6 R    start_time = time.time(). \4 ]# ?& ~; [& N7 j  X
        change_red2blue(origin_png, result_png)
    1 y; t8 P( c( A    spend_time = round(time.time() - start_time, 2)
    : F' g* t1 E+ _    print('生成成功,共花了 {} 秒'.format(spend_time))
    % d. x) L+ [/ v8 R; S" n1
    9 }# u4 O: t9 I  P2
    - o. o0 e, z, A7 E) c36 V! q0 f! H) @% P. q6 y
    4" Z3 Q% i& p" y+ O* W
    5) }* c5 u, Y7 B" f  T
    6( B1 O! Q7 Y2 C2 p7 z# v2 z  ]" e5 ^0 z
    7
    ; [3 C) q! y! j& l% Z8
    ! Y- @2 b2 \' |4 x( K. S96 }2 Z5 C6 P& W! m; a' _, V
    10
    $ I( t6 A3 t- J" ?- V117 t7 x0 B3 d; Z: R
    12
    ! [: N( L7 ^* |6 h& K2 c13
    1 {+ ]& ?# K4 t5 x, B: W5 F149 k* K6 y# t4 P* w
    15
    ; ]7 S8 h3 T- l. \8 ^! r16
    8 _1 C  B1 G: W1 G1 Y  U17; v+ {, _' y' E9 n" f+ ?) {; w1 Y
    183 f0 T3 d# O2 }
    191 N6 G, b' I9 l$ h6 R6 F
    20
    ! v7 n8 b' P/ E/ t( n/ d0 a- Z21
    % c. d" ]7 @* x2 [22. V4 ~) }4 x$ @, d4 o% ?
    23
    " s2 f1 I- Y" t' D/ G& u0 V24
    7 p: `$ m) H" S25
    $ q) h/ Y& x4 P. w$ O8 r$ b26
      f# F1 p3 n, k  B/ L; P' n/ W3 G27) T/ ^/ e7 O9 K5 K' J3 R
    28/ |# _( f9 i) E: \
    291 E, x' w9 E3 G- p( J7 X# v- \& L8 y; e
    30
    ; g2 x' l+ K) S; A4 M3 m310 c5 ^3 y9 e) k, G" L
    32
    . ~* i& B/ j" U7 d6 @33
    1 C; k* O( ?; H* e3 E* q8 Q34
    . R2 ?2 W  ?# U. I1 V4 a35
    ) o2 m6 R5 ?* j( z$ I$ S, @36! s0 C, p% {) }; n
    37" Q1 T  W8 B2 b& i$ Z; A- R( K7 z
    38
    6 p' n. ?  O7 }9 ?, u$ N* X399 ^- [% k' s& @* F- F7 ]
    40& X8 R9 ~) ?" A; h5 B% ]8 W+ ^
    41
    % E! D$ O- m  ]" Q+ b7 ^( s42" c* B# E# T4 s3 i6 i( Y0 s
    43
    ) [. W/ R6 Z2 G9 Z+ t1 b( j1 ^44
    - q  _+ D+ V! |% F- z) Q45
    $ F# @  ?7 y% H1 z  c# s46
    " ^' x4 a/ y+ f* C5 V5 {6 _* O2 D, x该方法质量较好,但一张图片大概需要12秒。$ N% L3 P% L/ k% N3 {/ \

    * \: |% x6 T; z6 U
    ! e/ Q/ i6 m' p& [* Q9 e) W  R0 u1 S" l' M  M. E8 V3 M  V
    方法四: Background MattingV2; L* s8 Y" a" P
    Real-Time High-Resolution Background Matting9 n" A$ c8 V1 G
    CVPR 2021 oral  f" y# v, i1 Y: Z7 w/ E# Y7 g
    + s: k) w6 \; N2 d0 k
    论文:https://arxiv.org/abs/2012.07810
    % i# ]" Q6 p! H& M. V) q% r+ x代码:https://github.com/PeterL1n/BackgroundMattingV27 r. U; R+ z! k4 k0 \
    # N; t# U; {- y7 Q. r; n' o- Q
    github的readme.md有inference的colab链接,可以用那个跑2 H; |$ H: Y% w- Q4 y

    6 W& E5 i* _% Q/ a  C$ S5 D6 \由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。
    ' ]8 ^! [1 s. S4 }  `0 ]' n6 e
    ' @- _& O8 u% t6 a( N于是这里我需要生成一个背景图片。% o! Z/ x+ |. }% D  @# \) I6 w
    首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。, |% J& y  J( v6 t

    8 c$ p9 M, x! b( y" L! V5 G4 d然后生成一个背景图片。, a9 M4 c% j* R0 d0 @

    7 B' N% O8 p+ k/ iimport cv2
    7 `& Q5 q$ l  i/ [3 Uimport numpy as np7 Q9 i/ o, J. J/ c8 p+ b7 d0 b' S7 Z
    7 j0 ?8 }  c0 r$ _; V  h
    - ]9 w4 ~5 v' ^  u$ {* P$ f
    image = cv2.imread("origin_png/person.jpg")8 n: h. T" j4 a) R
    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值$ Z) j9 W3 H5 I' i) S3 Q9 O6 F
    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])3 e8 f# F7 y. X' h3 B- V' C. k# Z
    image[:, :] = origin_bgr  K9 B/ S8 C$ l; ^2 T
      d4 \: p/ v; w0 |8 @$ U
    cv2.imwrite("mask/bg.png", image); q& q* o6 r* k  I2 P
    1% J/ o! F( ~' L6 r: B
    2) M6 j% S1 w1 s" M- L1 E
    3
    , \. i" J/ y& o% Q. i  o0 g4
    . e; S% R' Q$ b5 u+ ^8 ?* G5
    ) N7 M  y$ u2 V+ B6
    # J9 A- R* ^8 }2 F71 f  t/ m% V+ H- B0 T$ f' Q
    8
    2 H! \1 ?/ v# \  s! K  y  F9
      |% z* g% {0 o+ o' o5 K104 K# X; T+ \3 `9 U7 o

    9 ^* h- Y9 \3 h  j$ n+ O需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码
    + ?( m! p5 Y/ ^& U# ]% g8 \/ k# x! U3 C& }* w% ?* }1 W$ y
    src = Image.open('src.png')
    . D' f) V, I& g1 J8 c- p& ubgr = Image.open('bgr.png')4 s4 A* d3 E2 G. }5 |
    1
    ( J1 Q' i8 N" U" h, R& h2
    6 k7 g3 z9 ]! C. U另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)
    6 j- T% P1 R. V$ H9 t
    0 \0 K: X; T2 Vcom = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)
    ) l+ t' u; J3 a- N16 @+ |; F* t; t, s, v2 b
    6 s! q$ r- E4 W3 x. e
    那么加入我要换白底(255, 255, 255),就是
    : A8 u, Z7 q0 h0 u5 c1 {' G8 e
    . K1 Y% R8 X( {3 [( n9 [( Ccom = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)
    3 e- B6 [* }/ D& v+ G2 ?1
    ! a; P7 R) ]4 t- Y' {: ?' C% z
    假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是+ I  r* i& l# p% I+ l& ~
    / m+ X4 S! v) o: G# [  u
    com = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)
    0 ~1 {" D3 e% z6 T/ b$ Q0 U1
    * M1 @( F1 a* v9 k0 g- M2 g7 Q8 n1 \总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.
    ! D9 C& g9 V, _% c- L) K1 q; y4 f' O  `
    然后就输出图片了。可以看到效果相当好。不愧是oral。5 h1 D  G0 F, k+ B9 `: W. N+ z

    # y) ^  x1 j, G" a( ?4 P
    ) }  x& f) K2 u7 U# g+ w原论文可以实现发丝级效果' g) o% ?' l0 I

    : p8 t1 k  E# B6 i% i
    $ A7 E( B  W' u3 y, j+ E7 V! @6 F! {% u

    - M( x# ^: M" C# m6 m  U  F; A7 n# s2 F) x8 J5 L
    报错解决方案
    ! c7 R& _- e; [, b/ Fcan’t divided by 4 / can’t divided by 16
    * n$ U! D4 G6 Z* s! s: c+ ^由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。  c- U6 h4 [8 r7 c+ w
    这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize
    . K! ~, f* W& G! P" P1 b  M9 i————————————————
    : q+ a; W! @7 T, n版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    : r/ h5 K! P% T9 B" n原文链接:https://blog.csdn.net/weixin_43850253/article/details/1263767671 t- Q/ w9 v, _) e% ?5 z
    1 r5 U& u+ Y; K$ |  p* \

    : ?) b0 m' V2 j# i2 G' g
    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 17:04 , Processed in 0.436759 second(s), 50 queries .

    回顶部