QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2108|回复: 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将红底证件照转成蓝底4 p# d5 O- x! H8 W& p
    前言
    ( L& ]* M/ A9 ]& l, i3 x. `- `emmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。
    . D( s- h6 H( t# c
      L2 y# \+ f; T9 @
    ) X- S- }9 H/ E2 x# D; N% }- t
    6 ^( Q+ J" y/ ]9 R+ T
    , P' r2 M+ x/ ~# \# K方法一: lableme
    * @* ?. M& R6 `& }0 C5 _  ]lableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.. }! B! F4 u2 |7 C3 p. K$ W. V7 i7 H

    8 g1 e/ d: T$ F/ q# 代码来自 https://blog.csdn.net/hello_dear_you/article/details/1201301555 L, h  @1 O* J7 q
    import json- L; X  |/ q/ X% h
    import numpy as np1 ?. Z4 o, |" c- N) f
    import cv2: t# z7 c) U8 A, d6 Y' a  y( q- b5 k
    # read json file  U0 o& x: i' W( x& N, z/ ^
    with open("origin_json/mypic.json", "r") as f:- ?2 v5 j+ E* X/ I1 H
        data = f.read()
    & o1 N5 j* c: I: T$ n1 l' X( ~- u4 f8 z
    # convert str to json objs- b8 ?; s/ I  ~
    data = json.loads(data)) x" o' q$ ~* o: l  D

    ) |2 n, l' i7 P) r" G/ T& q# get the points , m& U) m1 b9 t3 Q, ^" Y
    points = data["shapes"][0]["points"]
    0 X7 L% z* ?% s# n  e% x# v- h$ F  apoints = np.array(points, dtype=np.int32)   # tips: points location must be int32* p# J( Z5 A* q2 {- K# m
    , H$ f/ E2 `7 s
    # read image to get shape# ]) `8 d. z" _
    image = cv2.imread("origin_png/person.jpg")9 `8 |6 Z- @- d: _" \) L, V

    % O' |7 o2 M, j& ?$ d# create a blank image
    & R+ G7 n* z. H) _mask = np.zeros_like(image, dtype=np.uint8)
    - Q  [; J+ Z; p* F1 J9 _
    # \5 I& ?  B; u# fill the contour with 2556 E8 e+ L; i" g! t5 c$ y4 {: v
    cv2.fillPoly(mask, [points], (255, 255, 255))6 M- J1 T' [, ?

    & f% i$ L& b$ ~5 r5 B5 @# save the mask - z4 g  X/ h  M/ p4 C/ Y
    cv2.imwrite("mask/person_mask.png", mask)
    ; k5 K% `' F* H3 W) I6 p1
    ( ]) a6 y& S6 ^) h2
    1 g0 q2 ^; p; k3 o( Y3
    + T% R% k! I6 q' H4
    9 _. Z* k* w* z( {4 A8 B5- _' `% h$ u  r1 [; i
    6! ?3 J+ ?2 x, o
    7
    ( G* R  ?& y6 [7 U1 s6 U8
    # E/ ?3 h! O& I0 D9
    ' s1 U3 e1 E( o) y/ h; F10) S* r- R# x4 `( ~: m9 k7 N6 G
    11
    1 p, `  {# Z. h+ r- [" u" j12$ v. W; k( L9 e! l, D7 M1 I
    13
    ! H" O8 C, B3 j" S/ f2 W14
    # _* t+ l# L( p) |! _* g( F15
    ! B$ q) H, \9 `! i6 r16% T4 C! A+ p5 S6 l" C; G; x4 Z7 N
    17
    + g% f& R6 z9 R! J6 S18! g  m( l! Y* N& E' W
    19
    8 {$ `& B+ ]% C8 k5 W3 e20
    + g5 l' x9 P/ N; E216 H7 J+ E5 h4 m
    22
    : w  s2 ~5 r! V" a! K8 k8 W23
    ; G  S  o4 ]" P1 L  j249 q* a7 O9 ~+ c4 v- N% V
    25
    1 K9 `5 i1 ]0 C26
    $ ^  ?) x/ V: M大概是这样:! f  z9 ~1 }2 a6 s& ~

    8 I* I2 J7 A* g2 L2 o' Q' u, u7 e8 ~6 f
    然后利用这个mask生成图片3 k0 }* F+ J3 N# k! P
    . }0 K) t/ @. H8 f" d3 ?
    # 参考自: https://www.jianshu.com/p/1961aa0c02ee4 D: L% B$ R3 C9 f* r0 f! @9 ?; b
    import cv2
    # e. e* q* k! q$ t8 r3 W, A' eimport numpy as np4 K0 {: {* q4 m8 e2 s- V+ B2 F! }
    . p; ?; @! U- o7 |- {+ D( W
    : h% C9 K: V. @5 T) M  V7 s
    origin_png = 'origin_png/person.jpg'
    ( H( E$ S7 ~% ~% {" t# maskPath = 'mask/person_mask.png'+ t  D- }8 w1 v  H& y
    maskPath = 'mask/bmv2.png': I; j* y0 b7 \# n; J" h0 a8 s
    result_png = 'result_png/result_png.png'
    . Y; s5 A0 ]7 t  ^% n! Z# S  t/ m

    * ]4 s/ p  M2 F7 H% ~6 nmaskImg = cv2.imread(maskPath)
    * {# `  X% D, aimg = cv2.imread(origin_png)
    ) N5 w+ J0 f4 g7 h1 Lassert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'
    - H8 o7 f) j& d; ]1 m6 ~; X; F1 O% l6 j6 E1 l$ S9 n
    h, w = img.shape[0], img.shape[1]# G8 O: @. J7 @. E- j6 G
    print('图片宽度: {}, 高度: {}'.format(h, w))
    4 g3 q3 b% \! R$ ?) I6 F/ u1 N7 c  p& F. y( o3 d' T- J
    rgb = (19,122,171)6 \2 L6 n7 x" B) ^1 j
    bgr = (rgb[2], rgb[1], rgb[0]): m' w2 |4 N- h; _
    # (B, G, R)
    3 l" Z( `9 q1 G1 f6 K9 ^for i in range(h):) i% u3 a1 Y; I' F
        for j in range(w):
    & i. ]8 l5 q) D2 ?- C5 X; @        if (maskImg[i, j] == 0).all():. ~- L7 F* Y* N/ w
                img[i, j] = bgr: Q+ t) \) @9 b3 c
    cv2.imwrite(result_png, img)
    & Q7 J( F+ Y. M8 c! `* Fprint('图片写入 {} 成功'.format(result_png))
    ' _& J# H( o& K) O9 E. z1
    8 L4 A7 t/ {( \) Q2
    4 b& y) I% X. c2 G4 L7 Q3' a) b" Y  G5 \" j
    4# x- }" O4 {" f$ {5 m+ Q3 F4 m5 u
    5& q, {- U% z" I* q9 Q
    6: j! s# d1 N7 E1 [  W1 L9 Z8 G1 m
    7' d" ^. ~* J9 e4 ]1 x0 `9 F
    8
    / u' x1 b9 d  U, r( }5 d9, b7 M# Q  k# F: r" ]& r# `
    10/ Y1 r* o% n2 Z  I2 m
    11
    $ ?5 {% W; {' C' J124 u0 E  d$ e3 u5 a! W. m% e
    137 a, G/ I  Q" z2 f4 H8 l$ e  G+ d. G
    14
    . G0 f2 P" v3 K0 Z6 O" c15
    , g& P% T* r3 G# i: B/ W169 g  p* C8 ^5 V+ `; w
    17$ z) u4 @* F& R& H( Y6 ^0 f. H6 r2 Z5 ~
    189 y! F5 @5 N7 L9 q$ V( N
    19
    # b& {- b! ^0 m$ [  f6 `" [20* q  b* ]! I: {, w' a5 q9 e: t
    21
    2 ~* A1 q& Y/ g. c220 h/ o/ [4 m2 x4 g3 H! b
    23
    ' p: m3 ?# O: L% d: }; \% \24
    / _7 \+ K; M5 j& ?0 j25
    : i# @: h7 `/ b& b' K26! \- @1 J: A  l3 ~2 F
    27
    : q; ]9 g4 I; n2 l; {由于人长得一般,就不放图了…
    ; @( E4 h1 p6 a+ P% _# y+ S& _* U
    ) N. K/ a4 y; e# j缺点:
    , H; Y, ^  f3 x- @lableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。2 _( S" n0 u; F0 J

    + l& P2 t! f" G% ^! s/ b  z; I
    . [  B9 W3 U* d$ b, o9 [& B
    $ d( ^  e; I( |" Y2 H/ r4 m/ X
    ) T$ W7 H; d% T7 @# R, T# U& z
    1 @/ ^, Z9 W& y7 h7 k% u, z# A方法二: 阈值5 L9 X  X" D1 d; l* I3 f5 p1 n* Y
    该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。
    9 V+ j9 W" p5 n; w# s1 P: z, {7 V- e6 u* a, b* ^5 y6 @2 q
    Opencv
    5 u. n- `- w  t) U4 {import cv2
    % ?$ ~* D/ M4 l0 Bimport numpy as np
    9 E3 w6 C$ L2 b. K# B
    5 ^; S8 Z9 h5 Z* ~. L
    & f5 @5 F4 h( x; k% pdef mean_square_loss(a_np, b_np):4 h  G! x4 P5 r9 F3 O
        sl = np.square(a_np - b_np)8 H1 ~" J% C. M6 k% A) z; ?
        return np.mean(sl)  @, X) B( M+ j- I: J
    . o. D8 U: ^( z% k- t. j" E( i

    * N) }5 U- ^) C/ f3 _def change_red2blue(origin_png, result_png):
    0 {: H2 O- T) f7 y+ X2 l* w3 w' m, T    img = cv2.imread(origin_png)3 R# h! K" s4 d: N9 r6 q
    6 j3 N7 B7 A( t" e# H1 E& Q8 o
        h, w = img.shape[0], img.shape[1]
    ( }5 d% _0 z, l    print('图片宽度: {}, 高度: {}'.format(h, w))
    9 e; c/ ?) y  E
    4 v7 h1 D; c# j+ }# Q; w    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值/ T+ ?  v& G% ?! R( g
        origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    / H7 {( t1 ]+ T9 M' u$ D/ R# X    target_rgb = (19,122,171) # 蓝底RBG+ P' U% J$ z$ Q1 e: O
        target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])& ^- m* o( @+ I* a3 G9 J

    2 }$ X8 x; B! `  S- K    for i in range(h):
    # H' Q( v' p+ e* X        for j in range(w):9 F2 I7 O- e0 F: g( u8 J
                # (B, G, R)
    + l! W; v' ~+ W3 y" l            if mean_square_loss(img[i, j], origin_bgr) < 50:
    $ @  O6 x4 ^& o7 g8 d                img[i, j] = target_bgr
    - s1 k" @# @4 g, P
    ) V1 t" n; Y# z$ Q: E    cv2.imwrite(result_png, img)
    . i+ d& e% u/ `    print('图片写入 {} 成功'.format(result_png))
    ! e; u7 c# P! k# N
    - N4 o2 D& u* M' N* J3 M: I: N! T* p; z$ h
    if __name__ == '__main__':
    * Q. ]: [5 B+ F8 j  k# D4 _    # origin_png = 'result_png/result_png.png'
    9 `' N) S1 B: z  G    origin_png = 'origin_png/person.jpg'% S/ I" K6 V4 Q" g
        result_png = 'result_png/result_refine.png'2 m: J7 r1 H# \; @! W5 ~2 U
        change_red2blue(origin_png, result_png)! Y$ l; q2 ~5 [) r9 z1 u
    1( E4 f$ P4 e( G. Z+ q
    2% w% t  U6 U* A* R: l% r. I
    36 `/ j+ X+ }7 E7 z: y& B2 Q* ?
    45 |' k  i- A1 d: z5 @8 z# `  T
    5' e7 R* g% C5 _! m6 d4 {
    6
    6 V, @1 ~4 I6 b4 `7" H1 y, A6 y8 a' q. o& {: R3 d
    8) a; g# f" }5 e
    9
    & H+ a1 m* G' j( g* w. x  k10
    , |9 ~6 n+ m$ s0 z11
    2 T$ a: D$ f3 M: B12
    . Z6 D  `* I, F( P0 O6 L+ ~+ c13: _; ?4 D% c0 o3 L( X- z3 w, l, M0 {
    14: }8 K) z5 @- L) U/ P: v
    15" A9 U) @+ ?* _: j% `  B
    16/ h9 u) l+ n5 \1 ^0 H
    17. ]4 l5 w; A) }' A
    18
    , v7 [" D$ n9 R# \: b19
    + b0 g# p! @8 P20
    + Z: w- u3 I* ^21
    ! _8 y; ~/ ^+ S22
    + J5 B# o1 E) s: ~( f7 `23$ }  K4 u' h! ]3 P; ^7 I
    24/ F( H, R0 K% r/ G3 ]5 ?+ v
    25
    1 V, k/ \$ o$ I0 Y) y$ O+ m26
    2 |7 `* c& G/ X6 m0 L0 F6 E277 G, a( U- i. O. U/ t
    28* `& ~. P. Z  U
    29+ @  T' {  R3 n) f+ ~
    30
    1 v3 O- _$ I/ ?' Y% d: f4 S31
    1 T1 B; Y" i; Z$ z3 }% p& v: N9 V32
    ( v1 U% u& i' Z% M! e+ v331 \1 w; _( _0 F+ j; w3 x
    349 G% W) L' K, V/ o6 D, t
    35
    8 i% l0 [' y  Q- o* H' L结果人与背景边缘仍会存在红色像素残留
    7 \7 e" \8 t7 o+ l' G# d/ U$ J" }) W( c7 p2 y3 n2 d# b
    / @* d1 g0 V- ^4 a" S: h

    8 z5 c. u0 I8 l/ N3 D4 q2 a" a, C. i8 U2 C  A7 x

    , ]3 y( r. f7 N! [1 N3 v& KPIL$ K" e( T$ k6 `& @9 u$ t0 D  L, G' }
    from torchvision.transforms.functional import to_tensor, to_pil_image
    7 \% f( |4 e; z$ [' B/ Ufrom PIL import Image
    ' N, }" Q5 @3 T- r; s0 Aimport torch3 K1 }# |* g* r! T
    import time
    ) r0 ~5 M& N$ R! Y: ]( M0 N9 u- a/ l; W2 `
    3 [0 }& i; m5 E+ X
    def mean_square_loss(a_ts, b_ts):
    8 c" j) `8 M9 ^' Z* m* h    # print(a_ts.shape)
    , s7 {* G. E4 T; [9 v- l: x    # print(b_ts)
    & |7 [0 {. G0 y; a7 N    sl = (a_ts - b_ts) ** 2
    , j' w, s; ]: e* j+ t. j& A: d. a    return sl.sum()
    # K! d8 y3 C+ K$ B9 a' w4 `# _+ ~+ @5 F# X' K
    # {, \: }* n. [2 a( S" N
    def change_red2blue(origin_png, result_png):
    0 Q  h$ S0 @& d% C    src = Image.open(origin_png)( h( ^, u$ M0 t5 ^
        src = to_tensor(src)
    0 Y* N; v+ ]) C    # print(src.shape)  # torch.Size([3, 800, 600])
    7 m" ^1 f9 y" ]% Z  c4 d    # channel: (R, G, B) / 255, a5 y7 S2 a3 z1 N7 X: I
        h, w = src.shape[1], src.shape[2]1 x7 c5 \. Y! }9 o2 v+ n
    3 C* p0 [) h$ L1 ]" j5 \! w+ M
        pha = torch.ones(h, w, 3)
    8 k6 A  W1 f: I0 O2 }  Z( `  ~6 k" H4 J1 H1 g
        bg = torch.tensor([168,36,32]) / 255' T5 y, t1 V& g
        target_bg = torch.tensor([19,122,171]) / 2559 H; t! @; S1 {5 a

    ; _4 V) R' v0 X! k# N    # C, H, W -> H, W, C
    & y/ s4 k% \0 ]+ M+ B! l7 J    src = src.permute(1, 2, 0)
    9 S( h9 E* O2 Z( ?2 {    for i in range(h):. ?0 O$ j8 j3 f6 E
            for j in range(w):7 B6 s; ?" m! N9 T0 C9 I
                if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数
    $ v8 T$ S8 C$ J' D                pha[j] = torch.tensor([0.0, 0.0, 0.0])
    : v0 [9 t" q/ n  X: V+ b/ l4 _, x: X% X3 v& g
        # H, W, C -> C, H, W6 M6 n# W( G. P5 u3 ?
        src = src.permute(2, 0, 1)- N3 j, i7 X. d* f% ]! L
        pha = pha.permute(2, 0, 1)
    8 ~& g$ U/ [9 o, z% B8 N    com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)3 z3 R0 N/ q/ P
        to_pil_image(com).save(result_png)$ p: p$ ~5 V( O( [% o  b& a

    0 e% c  J: {1 p$ t# h: q3 T' c  J0 m6 x$ Z& \" r
    if __name__ == '__main__':) v2 P; s8 T5 Q  N
        origin_png = 'origin_png/person.jpg'' X$ _. c+ ?  c" L: a; N
        result_png = 'result_png/com.png'1 M' v: k. x% F1 _
        start_time = time.time()
    & r, I# f5 H, t  X' Q5 ]6 ?/ p% n    change_red2blue(origin_png, result_png)
    * j, h6 p9 L. v6 K& E    spend_time = round(time.time() - start_time, 2)
    & s2 V5 c# [  @0 v8 u$ N/ C    print('生成成功,共花了 {} 秒'.format(spend_time))3 w" s! O2 i4 v: }( V. y  ^
    1
    ( L( i& J; u2 y" \9 i. H, N2  q( X% u1 p  h9 Z4 n1 |% a, v
    34 z. m% P& R8 |& L
    44 a  Q2 M6 B3 H
    5
    # }* g' |: v' D: v4 n4 ]) v6
    ) |# ?$ @' E5 y. c7
    " |/ j9 z3 b  Y8 A; U2 J0 ^. C8
    6 d; `6 L$ \: u0 b1 o( |5 w& p9# j9 W; G" x) ~: u# A% X# A+ K
    10
    $ n6 C  Q% B( D! l7 s! V8 K11
    9 O* b1 [0 [; c: W12( f2 [9 d, I" F  ^
    13
    * p0 Q+ [, ?4 w: _* h140 {1 {! z5 T& K
    15
    3 ]  ^; \, m# S4 N# {161 ?  Q, ~; d5 X% E4 V
    17
    : @$ J& I0 k1 J/ y5 }9 }18. x( U( `+ @6 Z% F/ d4 d
    19: d/ y0 G  n$ M$ M2 T  C% i4 X8 t
    20/ X! p  t$ J) u$ ]1 X6 }
    21- K% e& _( j! u; D' r
    22' S3 }  y( V5 t" E
    23
    0 g) O- L6 `. ^# u9 Y24
    ! G3 J5 t4 C& f( r/ d25
    & d& Y  c; e1 u3 z7 _/ g* Q% _266 S2 Y' N0 `, M1 ?- m) c
    27. z" {) K+ o3 e7 x0 h7 U2 X& f
    28$ Q4 H7 R% A$ q' L4 U  v
    29
    ' ]3 Y9 P  O8 E4 x" ^- c5 L1 L30
    9 k6 r% k' A! K' W& E" J! K319 R! e7 Y$ c: ~' S. u. I
    32- e) T1 z2 k/ Z/ Q# U6 e- Q
    33* n. N# @; `6 f! w% s: o
    34/ D0 a2 `7 H9 K1 k5 ^
    35/ |! T1 S! ^9 U
    36, W. u+ y, ^/ u: O
    376 ~1 k$ Q' f) u
    38
    5 ]! A' C2 O! u; e. _39
    7 b2 h& s3 ?" ?# Y$ v* d$ f40
    1 \* `, m! R+ ?& f7 O5 l+ L41) w. h/ o1 K* N. p' S
    429 ~3 |: y3 G6 e3 s; G# k1 x) W0 V
    43) X. N1 D, }: w9 n2 E! ~( z  S
    44
    4 g7 m1 L: y5 j# a7 T; i453 T% H. \  e( s1 {
    46
    # J" V, B6 T' @该方法质量较好,但一张图片大概需要12秒。
    ! }4 E6 b" e, Z7 }1 q3 L# m: c+ g" k$ ~  y6 J' E# T! Y! _, [
    % F; L. w* x4 n( ?
    0 ~4 w. s2 f% Q* |$ j* O
    方法四: Background MattingV2
    9 I3 V% J7 f- `' `& I& M  n# |" R( TReal-Time High-Resolution Background Matting3 k- v& G& z' D$ v$ N0 W. ~% S
    CVPR 2021 oral4 N* b9 S: p- {9 R
    5 c* A2 Z/ w) a
    论文:https://arxiv.org/abs/2012.07810
    + i1 [9 P' f4 ~. g; k- H7 o代码:https://github.com/PeterL1n/BackgroundMattingV2" z( G* i3 z) d, ?: p3 Z( g
    5 f' N9 O+ f: Y6 a/ g. l/ h
    github的readme.md有inference的colab链接,可以用那个跑
    . L4 G8 P9 h- x- K# a1 D0 B
    , i0 u  h) O+ Z0 ?/ T& J7 q由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。
    + p; x9 v  A' C" f
    : @: }4 B) y9 Q" P; U于是这里我需要生成一个背景图片。
    . J* G" F( i1 ?# |% f首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。: b7 e4 e  C  d" k: Z" [
    " P  {2 v- R* }$ s; M
    然后生成一个背景图片。- D/ _% @, y2 w( p/ l2 ~
    - N7 C/ N* P# B  ^; r0 N. _9 x
    import cv2
    0 ^% t5 v/ h2 i! }import numpy as np0 n$ @9 y! Y+ U4 r- `+ N! y
    / g8 J- v% ^4 I# D- V

    + U5 y! h; V" j, s2 gimage = cv2.imread("origin_png/person.jpg")# o. c2 f5 a  E: p( j
    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
    1 o2 k! Q$ J1 o0 n) }1 Y/ G% |; Gorigin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0]), E/ ?, q, S7 [6 d$ e5 W
    image[:, :] = origin_bgr
      W9 ]% H' Z# W9 N1 R6 S, ^+ r+ y$ P# s# L. X
    cv2.imwrite("mask/bg.png", image)
    : Z! |- }7 H7 I$ [1
    , e  s! Y8 \+ L3 q) k  o9 z: c2$ W4 e) t' ?5 U4 k2 k8 a, F
    3
    & r- G, E' H% G4 o8 h4
    6 t8 ^* t- Z- }4 c! ^5
    ) L! P; L! K& y( H6 c! X$ t% p: G6( A. Q5 Y! [# ]( r: _* q( P6 t- o
    7& u1 _& j2 Y: ]7 b- Y( ?  ~
    8
    6 D& L) Z4 M2 M! j" }2 y* Z9
    $ L$ W% T; s7 ~, `8 }0 K% m10- P: ~8 J* R8 d5 L! a) e2 |' q
    ; p' T9 S! A! E9 C; N% O. a
    需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码$ C3 u/ W) v' S/ \5 k2 H2 s& L

      P, R# J- m  b. _9 x1 e  m5 g: Nsrc = Image.open('src.png')) t/ M9 O( |) M$ Q: y! S
    bgr = Image.open('bgr.png'), Y# L5 H" |3 S
    1
    - ?7 T: {# a& @! q  E2& t% T6 S! A' s# s$ h/ z* J
    另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)
    0 n- A, L, a; k5 c2 H0 L+ K# h* K2 q7 f
    com = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)8 ?1 a3 }- K6 `+ c5 ~) I
    1$ Y3 P0 R+ [, W; ~. j: ~
    8 ~+ V: W4 V; X' z$ U
    那么加入我要换白底(255, 255, 255),就是5 a$ ]" Q1 Y& T& K7 {
    ; R2 X0 G* e6 v1 ?% E+ ^- }4 q
    com = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)
    % I5 f, n* s$ F" k# D( g' W1
    / }& k2 ~  A/ D' g; `
      ^1 k5 {- R4 h; N* F: @假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是% j' p, W0 ?7 U- l7 [' E
    0 ?/ O: p& h4 K! l$ X  ?
    com = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)$ @3 q" W+ J1 i% q% q
    14 T! d" U& l2 k" X+ [* L- \! Y
    总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.; a0 z, r8 J/ |5 k! w0 q
    + v) k: _8 b: F1 L4 e0 C+ S( J1 G
    然后就输出图片了。可以看到效果相当好。不愧是oral。
    3 x/ ?! Q' N7 G- P" k4 R
    6 I7 o* ?+ q# H, p  m! c) C6 U) c
    原论文可以实现发丝级效果, g! ?& L$ \! x3 q

    ; M+ f- @3 [1 Z  W5 a3 w
      N6 H/ G4 q  f. [. t  Y" i
    $ J* W- e4 W1 m% P0 n3 ]; a5 n5 ~, @' q! b
    - f! |4 D8 o( z% _0 [. U5 s& j5 E) g; R
    报错解决方案
    3 S1 M, Y+ W0 Acan’t divided by 4 / can’t divided by 16' b, ]9 Q4 D+ q
    由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。3 z0 v- h8 _4 \( F
    这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize! M! D/ x) R1 X
    ————————————————
    ; U. i& k  W& U, O# T6 L7 }4 N# R版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    7 }, Y8 |  I; H  S原文链接:https://blog.csdn.net/weixin_43850253/article/details/1263767676 L5 }% |# I  ^1 R; [% B- C
    * A, C" Z2 j2 [( }) a( x0 i5 N
      |0 _# I/ B" h  w+ b
    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-30 18:05 , Processed in 0.402775 second(s), 51 queries .

    回顶部