QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2144|回复: 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将红底证件照转成蓝底
    ! J' D. f7 T8 {8 `- F. @, Q# v: u前言1 p( r/ o  \* R
    emmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。) I0 O& _* d" e8 `0 J* H6 U/ M# N

    , o! d2 r. p) D, q) ~9 u/ c, s5 J/ V& b' {/ V8 C

    ' z6 Y( [+ \" I/ B" M9 Q# u9 z0 p; c% Q" [. l4 f( {! x% v
    方法一: lableme
    4 h, W: j5 {& @7 U3 U7 ^6 hlableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.
    8 ~  u# W7 t* `
    ; _+ k+ X3 R. d+ A# 代码来自 https://blog.csdn.net/hello_dear_you/article/details/120130155
    4 r% \1 S5 j- {* E; A# }! P, yimport json
    & n7 d( V0 U* n/ a0 q6 G  H) b+ Himport numpy as np
    * L# Q$ M" j( c( j' `( |import cv2
    7 b( n& Y+ W+ U  o2 h7 ~: g" a+ b# read json file
    * D1 {: R4 F# p# G/ t2 {/ Y; |: C" Ywith open("origin_json/mypic.json", "r") as f:3 g* c: B- C7 z0 z6 Y# c5 k
        data = f.read()) {+ E& R3 h5 {& b+ b
    + H# n  z8 d" ~/ z( ]) d" S
    # convert str to json objs* O, z4 C5 @3 z
    data = json.loads(data), @0 X; t) D7 I* N& ~& K

    $ n( |0 {" R" V# w3 G# get the points # p  |/ \, E5 O3 b) Q4 _$ v
    points = data["shapes"][0]["points"]
    * `, m6 \' J( j5 F! E$ O  wpoints = np.array(points, dtype=np.int32)   # tips: points location must be int328 i6 f( T6 K' b; {& s- ?; N
    ' f8 H! N) r$ N4 o4 Z
    # read image to get shape
    5 z# O* \$ f. w# c6 Z' X) H9 zimage = cv2.imread("origin_png/person.jpg")" ]% T- _% G) N) y* h0 \! N7 e
    % u. K) P; z( \) {% Q4 n0 }$ T
    # create a blank image. ^1 ?  I4 i" I) d7 F; b
    mask = np.zeros_like(image, dtype=np.uint8)
    , {$ u4 V% v$ E" Y7 Z  c- f+ X1 t2 A+ }1 x: e3 H
    # fill the contour with 255
    ( g* _1 q$ e* g" b# G/ f' Y5 W( Tcv2.fillPoly(mask, [points], (255, 255, 255))
    + _, b1 s0 ?# t. U! H7 R- I
    ' z3 q1 L% ?: g/ L0 G# save the mask
    ) p5 s; \! C* L- Z( Fcv2.imwrite("mask/person_mask.png", mask)* v" b% [: [: ]! W  g
    1
    0 P) N* |8 f9 w' b0 z2
    4 T, k/ W* ^! i- Y/ L$ I3
    - H" f' I& J/ ^4
    ; G9 d" q: f1 t, g, }; I  \1 G: h5* E: e& Q- H0 V+ I
    6
    ) z  l5 [* X" O4 q7
    + ]: b" {/ E% B. I; _8 A" K2 R8
    + ^) _$ y/ s" L3 ^: _9
    & |+ n$ G/ ^4 P- D& H10
    # d( D; R$ X. X1 S11$ J5 ^  s; X0 ?* t, B6 S, u
    12
    " ~% ]/ E- F7 O* e13
    5 L) z7 Z8 \' O- ~+ K8 u. i% a) n14; J  h, N9 I+ S( G! N3 E$ A9 w
    15
    3 G$ \1 O$ v( Z- n16
    6 U% o4 n" u3 |# \7 S17) }1 |+ ]) u4 w, A
    18
    ; ~0 \9 ~$ f" U/ Q) X9 \  ^195 a& ~: h+ _: p- X- Y
    20
    + e/ P  y9 Q) y21
    ) O& Q8 s  [" {22+ |; L4 [4 s. [) u! Z. B0 V: I
    231 y- ^3 b7 n' r8 Y
    24
    + C/ r$ U& J. I9 Q25
    + n( E+ \; A/ s+ V6 Q26! q$ ^% R0 E! i& F( s: {
    大概是这样:3 i) p7 `) |3 m! I, J
    ( X! h. q  D) b! V9 m
    7 u$ P0 O* _% B* t! s
    然后利用这个mask生成图片1 u" e2 u' P# V
    5 O% F6 T1 d% G* s
    # 参考自: https://www.jianshu.com/p/1961aa0c02ee, `1 `3 C5 J" ^0 n$ l
    import cv2! K$ H: G* |) x& P' m. X( T9 i
    import numpy as np) m% I3 \: o  s' S
    6 G* |9 s! }/ K3 e( Y1 x7 D2 W

    ( U& L; C6 A- a  b( w6 `2 |( x! [origin_png = 'origin_png/person.jpg'
    4 x4 T- {* K; n& ]  ?3 A# maskPath = 'mask/person_mask.png'3 N6 d/ Q2 b4 n
    maskPath = 'mask/bmv2.png'
    5 f' T* E% \0 p+ i9 hresult_png = 'result_png/result_png.png'
    8 X' G- z! U8 N" U% }) w! x3 T* g, i  m: V# \+ m8 z
    0 z7 u, ?, [9 D% ?7 q
    maskImg = cv2.imread(maskPath). e( P5 N; ~4 ^
    img = cv2.imread(origin_png)
    % a: u& I6 S1 d4 Nassert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'
    $ P3 S6 n9 j3 p- ?# ^# C& j0 s8 v7 F$ B
    h, w = img.shape[0], img.shape[1]
    $ X7 ?( v0 x5 U1 }print('图片宽度: {}, 高度: {}'.format(h, w))' s' Q' H- r  g3 q) L$ U, b! U
    2 E1 n' B. n4 h
    rgb = (19,122,171)5 E* t( c. K7 g
    bgr = (rgb[2], rgb[1], rgb[0])( a% P) p/ w( P# a) f
    # (B, G, R)1 Z8 C. o3 v9 g0 B( d
    for i in range(h):
    , q, N  l4 p' ?1 ?8 T    for j in range(w):8 N: Z# e5 w( J& [3 x4 T
            if (maskImg[i, j] == 0).all():' h5 D8 z( k& |1 d& [
                img[i, j] = bgr
      B6 P. p' y, x2 K# E! Q6 h- T" wcv2.imwrite(result_png, img)
    * D& d8 {) g; Sprint('图片写入 {} 成功'.format(result_png))
    % K8 S. H# l2 c9 @1( o( e, Q2 h. Q( O: z
    2
    , w+ E/ h3 E/ p  J6 {. F3
    ! r: }/ n. m9 y2 k' J" j1 A4
    ' Q3 w/ F$ s: C9 L! R5
    ; n2 [9 q$ i. Y; v6
    - m, K% N5 I0 V- x% F! c- h7$ s$ |& J: E9 i  T; q
    84 r0 R/ t! B) K0 ~; ~
    9
    7 s2 I' P1 H* ?3 b1 R103 O0 S! W. @3 c  n! H+ ^* w4 L
    11+ K$ @" [9 V8 C; N) T
    12
    # y' j4 o* w! [* H1 q7 e; d13' w8 \5 @& X2 l9 W3 p' ^# R- X" z7 [
    14
    # O/ j* D0 I) }) t# Q1 b150 ], p8 V& t# [/ U
    164 j/ U. K( s$ }# q+ W/ s
    17
    % V& ^4 s9 q* e( J& `$ Q18, B; v2 E9 n3 i0 z6 [4 \/ F) d
    19
    7 r% G7 F7 b) T* N) ^3 ^5 V20
    ! j2 z8 t8 X- S3 ]: ~( ^21; H9 K. b: D- s) L4 ~
    227 o* {- F0 E4 a* y- N& ~
    23# @( C+ i* b6 b4 @9 g, [
    24& u  x. F$ Y, k3 S
    25
    5 K( V" o* R' a/ F4 `9 I2 Y26
    7 S! k! \  s- E/ m27
    6 J# Z$ O, G2 ^2 F' {由于人长得一般,就不放图了…# e6 @; f; X0 y: I$ t, a6 r1 m5 h
    : x2 G& B2 _: x0 l( p) }1 x3 Z
    缺点:1 m8 k( a9 H+ k) m. Z
    lableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。
    ( a9 U. v: m/ O7 d: C8 ]! {) }: B% U: x$ `8 ?/ W
    4 ~' l/ o. n: B" E4 d" q5 s

    & q9 a$ A" _0 D4 K3 N  E8 E1 W; c
    # k+ e* Q) h, {0 z- |4 j$ e" ?1 p
    方法二: 阈值
    - `4 H- Z7 x( O& x! B) V该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。. J4 c5 ?8 |6 m4 V& F' K

    % h) K7 I) J% m  I2 lOpencv
    ' N3 x. ]+ O3 f; aimport cv2
    : b7 v4 q0 f4 k2 Q3 gimport numpy as np5 d- a( g* {- I

    / b+ E/ R$ X. R4 Q' g- ~9 H" r$ |
    ' e. J9 Q; f7 G  q7 |* L% H7 G& udef mean_square_loss(a_np, b_np):8 E" _. _7 X3 M
        sl = np.square(a_np - b_np)& v! R6 u! \. S4 u1 X2 E+ B% v; e
        return np.mean(sl)
    - a7 {8 o, B( o& ^! v. R; C4 p# @' R
    . X2 u, b, I$ a4 d
    + W6 R8 R* p' W& \def change_red2blue(origin_png, result_png):6 {2 `7 c/ m' {+ A  [  ?" C
        img = cv2.imread(origin_png)# ~6 M) m3 C% h  }$ J! \

    ( Q/ o" n" s  ~  T' r# f    h, w = img.shape[0], img.shape[1]1 G$ z8 }6 E/ T' M' j; L
        print('图片宽度: {}, 高度: {}'.format(h, w))
    5 V- D% o. f# `) W1 ?2 A) W5 y8 d( K. P. R! g
        origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值7 F" O/ m. I# Y# y& V& ^
        origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])+ T3 B' n" w- ^
        target_rgb = (19,122,171) # 蓝底RBG
    & e" T9 r% p- S. f0 R    target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])' W3 h: c- T7 d% v2 T* u

      Y. |* V* `( }* U- u    for i in range(h):8 N/ c& R+ N/ K3 t6 D3 d& z. z
            for j in range(w):: U- s' z% u# I( j, ^, m
                # (B, G, R)" P, s1 b  p- m1 ?
                if mean_square_loss(img[i, j], origin_bgr) < 50:# s% s/ R. L4 t
                    img[i, j] = target_bgr
    7 Y) A3 @: Y0 W- u* N6 q# \
    $ f8 s& F5 H& z* x: X! \    cv2.imwrite(result_png, img)
    1 w; @; f" S8 }8 T4 w    print('图片写入 {} 成功'.format(result_png))
    & P+ l* r" d2 ]: `8 D; H/ ^1 a  F" \6 p9 A- u

    2 j, }' v5 ?6 \  C' oif __name__ == '__main__':
    " O+ m8 K$ k; B: i$ x    # origin_png = 'result_png/result_png.png'
    " T( e" K* f* e- A    origin_png = 'origin_png/person.jpg'
    ! {) A* G* X2 t    result_png = 'result_png/result_refine.png'
    ; M: S( @3 e' V2 F    change_red2blue(origin_png, result_png)
    9 B( H9 B9 J3 g* S2 k10 F- t" U: k0 z% M- g6 F
    2
    0 G' _9 ^! s- a; z; Y% d' B3
    # g2 l' ^1 m; i9 T4
    8 z! `1 H. N9 s* ?) h. L5
    " }/ K7 j" L* \' I1 e$ G6
    ) i; h, h5 V% C+ V& ]( H+ T7" C: i4 [5 w3 X
    8- D1 i/ K4 s) w3 y) R
    9- r2 r6 O/ ]# H9 \* n& U
    10
    & I$ c1 v4 X0 L! k  ]' v6 C' Y; p$ J115 T$ j+ |6 ~+ ~6 A0 A# ?1 \
    12
    * [1 m% R. p" y- I/ ]3 C132 M  \$ L9 e% V' G7 Z9 |
    14, A2 `# S+ g% B. p: s
    15! L( P4 k1 Q" Y4 l2 B  v
    16+ }7 H7 c0 R; H
    17
    9 [; G. r) V% d/ e' h* e18! U+ k" k; P9 T* R
    19
    ; Y/ R0 p8 v; E20
    5 B7 ~- v) i4 W21
    / X8 n  R9 P  j" K9 W! |223 e9 y8 |2 o" ?6 x7 t/ Z9 B$ N
    23
    ! `  D3 C% r- z$ Y* g24
    * N7 ]3 v4 w  a* B( T257 a( u2 A6 f/ P% G' Q
    26
    4 w8 G! {' \4 j5 Y* m27
    $ {4 x# ^7 w& v: T7 }, @286 c8 y) V+ A9 U/ i! Q0 v
    29
    & ]- N1 h4 O' m5 F  @7 p6 m304 U1 ~9 w& w3 \+ D* F
    31; v1 Z$ ?: @. |: q* m" m
    32' O' ~( z; _1 E$ }. z: P
    33
    % a/ K, A2 i5 J! U( x34
    ' N% z& u4 h" u8 x$ L# N35+ j; v$ W! K9 j& Y
    结果人与背景边缘仍会存在红色像素残留
    , T5 ^# T5 ^6 h. H1 c: S2 c; x# w6 m+ J  D5 a0 A

    4 A# {% X; j' m' d4 u. X( e2 V
    , ]% ?$ _1 i& z7 B: ?' X3 p" P# A0 \0 Q  {

    2 {$ n5 q1 V" R8 ]! O: aPIL4 ?7 ]3 k5 e" R
    from torchvision.transforms.functional import to_tensor, to_pil_image) C- k0 u7 ?7 V+ I" r
    from PIL import Image: x# z6 W. Q% g1 T% c
    import torch$ R9 W" }. O) L* e
    import time
    " i" C% ?. S% G: S+ u
    + q) f. y6 I/ v4 C/ n) g. d! R- Z0 K& j
    def mean_square_loss(a_ts, b_ts):: w: {/ }  ]) M$ t# a7 N
        # print(a_ts.shape)
    3 W- t; a- I" u* N+ C9 ~( `& G    # print(b_ts)
    - w: ?2 g- G- p* f% C+ G    sl = (a_ts - b_ts) ** 2
    0 _  X: ~) Q- ]6 Z4 X, v: d    return sl.sum()/ c' y. `; ]6 H
    7 g# y, k% d( H. [: F* x+ ?
    ! q8 f1 S/ K# y! {9 ~$ B! J9 N8 b
    def change_red2blue(origin_png, result_png):* a6 X9 Z5 P5 A6 d2 T
        src = Image.open(origin_png)( j$ G  S+ u/ w1 K" @' |3 f. q2 D
        src = to_tensor(src)+ e4 [3 O0 X/ q; }' l/ A
        # print(src.shape)  # torch.Size([3, 800, 600])
    ) T; T7 ^( U" j8 S# }    # channel: (R, G, B) / 255
    . S/ g8 T3 C1 k: m. z; q# E    h, w = src.shape[1], src.shape[2]5 }7 g% p* H# ^8 L* ]4 d
    ) M# Y$ T+ d8 ?# F& t' W
        pha = torch.ones(h, w, 3)1 K: s, N# M. S

    $ ^1 A; z( ~$ y$ I  \    bg = torch.tensor([168,36,32]) / 255
    2 r6 m6 g' y7 ~5 r, B* p    target_bg = torch.tensor([19,122,171]) / 2550 r8 ~# I2 s; f. h; F  p

    & I7 o8 l+ u( R; H6 D    # C, H, W -> H, W, C
    ) {2 `, E) `; J- F    src = src.permute(1, 2, 0); {# a8 I" q( x" C& n$ c
        for i in range(h):+ s0 _& e$ j9 v2 J# @2 w1 z/ I, S
            for j in range(w):
    ( E! A, [; N/ r5 c            if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数
    - [$ D# D- A9 u. j; H9 K                pha[j] = torch.tensor([0.0, 0.0, 0.0])2 c  i! `7 N' d2 Q' L" q

    $ R: D/ T* f" A    # H, W, C -> C, H, W# t; m/ I1 t% E
        src = src.permute(2, 0, 1)9 J1 \# P9 q& z# o4 z, w& D9 e, `
        pha = pha.permute(2, 0, 1)# J: U* ]9 i4 M  U! a/ X
        com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)
    5 L! c# E3 A6 ~- ]* p( ^0 `    to_pil_image(com).save(result_png)
    ( b+ `6 n6 o/ d. B5 R  Y; P* o  U' X2 I+ x8 r6 V

    : y0 _- F* u7 \0 l" Eif __name__ == '__main__':
    & q1 U! X) Q2 j. |5 ]1 _* M    origin_png = 'origin_png/person.jpg'. `( O# l# V' s. \3 U0 g- E( z
        result_png = 'result_png/com.png': Z1 G7 F" r8 b0 ?. y9 C
        start_time = time.time()
    - C$ n' l7 q2 f! a$ ]: B) R" _; h% [9 H    change_red2blue(origin_png, result_png)
    7 `2 b. ^; q/ p    spend_time = round(time.time() - start_time, 2)
    ; f8 ]3 S& o# s  s( L2 S- s    print('生成成功,共花了 {} 秒'.format(spend_time))
    . _7 F2 N, L6 g  d! Q1
    : E0 d/ V: c0 @# ~2+ \! m; I" y7 F& X' d
    3; a/ y5 a+ v" ^- M: p) N+ C
    4( F5 H! w& I  O( c8 R  X( {  f
    5
    & u$ ?6 x2 [7 }" X6# Z; d/ C9 x$ K. K) A4 `% x' K
    7. L$ T  w: R1 Q6 y3 E5 p2 j( |
    82 S& v9 [: M* q
    9
    9 d6 I& ~4 W1 ?) t% Q, h10
    ' D; p2 ]2 y+ G: X$ s0 T6 `118 {: @5 f: Y2 I/ R; ~# R7 ~0 A3 I2 l
    12
    % Y# W8 y4 G6 `) D133 u. n. t! b5 S' g$ D! r
    14
    2 ]$ t7 m0 B0 }3 k& ^15: H! ?6 d9 F" s
    167 j! [8 l" B9 d7 c
    17
    $ y, c' x4 ?, O. N5 r18  H& l2 ^1 @0 H" ~6 h/ e
    19
    ( L$ m9 X5 q1 c8 l, I4 p7 B! m20% p6 k+ o1 z. m' i# ^% d
    21
      D* U5 n0 x. h/ g. n1 L220 x! H4 o; W' p8 `7 V0 Q( Z
    23
    5 ^& X* s* W, I4 u* L/ j  Z  E. y24, c& @/ S+ R& q( c/ n8 N' N1 P' p1 x
    25$ Y0 U: w, f* X( p9 q; \
    268 B/ ~/ W4 a& a: f4 J8 o' S; o
    272 ^0 q- p" D5 }. q
    28$ K0 Y5 v& H% O. u- l
    29
    2 h, |& p  V! R. K6 `7 e) X) c30* M* u1 M; J# ^1 p2 n  N# E7 n8 F
    31
    & {6 D4 p# S: ]; k32/ q# `7 a( j& F2 U7 c5 @8 y4 ]
    33
    , r' M* q* y2 v* y8 O. ~+ @, w4 ]34
    " b5 n0 `2 B8 D8 V+ ?; \35
    ; V+ q  d' u# T2 z  Y2 _360 q4 c! c1 X/ O0 s
    37
    , X' W& K4 D  g: i38: T: n7 y% {1 L$ H1 ?* H8 O" f
    39$ S6 x. z* ^) u! q7 F5 Y/ a6 J
    401 q- v0 c5 w. k1 ^
    41
      X9 }8 b. e# M4 p9 Z42
    ) S2 `( W' m6 K0 Z) p43
    1 j3 G# E# f. E6 `0 u44- b" W# z$ z8 G9 S* r# U! Z4 D
    45
    * S5 ~. C3 Y; `% S+ \% P46
    5 t5 `# n  i6 m# y& h# j! P( N该方法质量较好,但一张图片大概需要12秒。2 I  D* W- ]7 |

    6 j0 r/ B& G- B
    8 C' ?' f) K# |# E6 P* `  n# K
    % f; }; u% X# Y; c; Y5 }4 F方法四: Background MattingV2
    4 ]6 i) c1 w* y) u( K% Q2 p  [Real-Time High-Resolution Background Matting
    ' r  a$ u$ A3 {$ E% @0 XCVPR 2021 oral
    * Y5 F3 K- o9 v6 f( k0 I+ P3 e* A& x0 K+ P
    论文:https://arxiv.org/abs/2012.07810
    5 ~; |0 R: V1 p' d4 [代码:https://github.com/PeterL1n/BackgroundMattingV2
    ' s) M( O* K0 y7 U4 T% l* @: P/ D
    3 V( p8 M3 h8 s) dgithub的readme.md有inference的colab链接,可以用那个跑
    ( R9 v3 o9 y  U+ r. `6 K3 l
    ' h$ w7 z. |# E/ ~由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。$ R/ I2 d  d# [5 J6 K) ^

    5 Z' q& d; F9 \& ^% T于是这里我需要生成一个背景图片。
    $ Q* b" a1 P7 a首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。5 {4 w$ ?9 Q7 h4 c' Q: K; @( {
    8 L9 B8 W! ^. W  f
    然后生成一个背景图片。. G) U+ v: u6 L0 B8 t) f! ?  F0 B8 k
    & y9 T. G$ u, t- d) ~# S$ V, v
    import cv2# W/ ?  n# ^8 ?) _
    import numpy as np0 N' n$ O' z, @; J5 s
    , ~: G, q# d; ?1 o5 |% B
    # T  K0 |5 s/ X4 f2 M- G4 f0 Z9 C
    image = cv2.imread("origin_png/person.jpg")1 E6 S( ~9 v1 F6 N1 Q* a" G
    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
    0 Q9 a, R* i/ e, V1 T$ S+ uorigin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    2 r4 r4 Z* r# k9 }; gimage[:, :] = origin_bgr
    % ^; J% z9 f) M8 l: Z- Z6 }( l( r5 Q/ L* R4 D5 u0 i
    cv2.imwrite("mask/bg.png", image)6 E# Z0 J9 R" w) I7 ]
    1! B% I7 v- n7 e! {& C4 _' D8 a
    2
    7 a: Z0 c9 O  X9 z' F* D% V3; a7 V& z8 U% O( B/ S2 }8 }
    4
    ' L0 o% d# C: Z' Z5
    # f2 T$ h9 S/ E6 M" d  }6" I' k8 T0 N  W
    7
    / o) f9 ?+ {6 _0 ~6 [0 J8- e7 W8 E6 E% g( R3 G6 j( |
    99 h3 S2 C7 N3 G2 M( Y) E
    10
    8 d6 k* Y3 Q0 J' x9 f+ B" ~3 v$ M9 X( F1 F, u% U
    需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码& y* f( p0 _+ c2 q
      e% i# Q3 E8 O" G
    src = Image.open('src.png')8 c/ {* W! ]& D& s5 @( ~4 k
    bgr = Image.open('bgr.png')
    - @. T/ P% J1 {: S1" l) x7 K7 g/ |, y2 }7 C
    21 v9 J6 J, r& G
    另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)
    : C" l, h& V1 d) _( u- g2 i) e7 y' Z2 v7 }- g$ s2 J* l
    com = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)
    3 G9 z/ N! B* A  Q8 Q9 B9 U1; I; Q; A+ x8 [, i8 I5 v" H7 C- b

    1 z: G, n; e6 h& \$ k5 ~- P那么加入我要换白底(255, 255, 255),就是
    3 R: U/ f9 k& {/ [. N- f5 g- z# N' s- A$ X
    com = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)
    : j- a5 w% j. V1 i! R. U9 t1
    3 j( m# |" |" n" X* X/ B+ D/ E/ G; B/ m, k& u
    假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是2 }( G( c. O8 ]/ L

    * Z4 s( E! }& T: ^com = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)
    # p( \* d6 A$ v$ _: e1
    3 j) J8 g8 J# P总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.
    5 Z& R* E$ D1 c$ l2 i$ }/ [  ?1 I" i/ u4 j5 R  Q$ n/ _
    然后就输出图片了。可以看到效果相当好。不愧是oral。. a8 S. ?0 N6 }; `0 R: _
    9 [3 ~" R: M; r" a) ]6 ?
      m' q- K8 S' k* B2 E7 [
    原论文可以实现发丝级效果" R8 j, o% t4 z/ V
    * k2 o! C; x2 A" Z* _

    : P& i# Y* Y$ \- H3 ?+ Q$ O, s# A5 S* _

    6 I$ J6 M: Q( g0 x8 R' N, \
    3 `7 l$ s) \: g报错解决方案
    % X5 s3 x* b- @( x4 c9 vcan’t divided by 4 / can’t divided by 16" B8 A' C" n, {9 C
    由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。
    # G  a, Y! r% ^9 _这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize" r% f+ c' ^8 W: v# {1 h9 q
    ————————————————7 ~: v/ H$ ~3 J; H: a- E! J
    版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    $ J. Y. P! g% U8 S原文链接:https://blog.csdn.net/weixin_43850253/article/details/126376767
    / G6 F# q4 d! L* ^
    0 B! K) c# Q# P. ?
    1 H/ S0 D- x% _, _3 L
    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-9-13 16:30 , Processed in 0.412883 second(s), 51 queries .

    回顶部