QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2091|回复: 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将红底证件照转成蓝底: v3 X' @5 r" r& H) @5 _
    前言+ ^1 R% T5 e& A1 I/ ]
    emmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。$ Z' b5 q9 K5 q8 w, P1 s

    ! {1 g- l0 g$ F- Q; L" }4 T3 S
    * R1 L2 a8 `! e* d/ E# e; T& i$ p4 h2 M% ~

    : j, |+ D7 f+ F& A/ {4 f方法一: lableme
    6 I' j. U. P6 F0 `! jlableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.# [1 I% K8 c4 y# R4 x) d6 V" a
    7 G: U& M' b1 e! z  l
    # 代码来自 https://blog.csdn.net/hello_dear_you/article/details/1201301557 n% k, V# f" m' Q) z, X
    import json
    9 q1 ~* x+ y' r1 Gimport numpy as np! x& H% o0 K+ ~1 b
    import cv2
      M3 `6 \1 g: i7 ]  B! t( P" a, P2 S& t# read json file, k! ~& V! U) l
    with open("origin_json/mypic.json", "r") as f:& g  X8 m: Y/ i8 h. k$ h
        data = f.read()/ w/ Y, K- D5 G$ I! B& k& u

    # D/ ^  a4 d* D0 l$ \; S6 T# convert str to json objs# j. ?) T8 P9 Z7 v
    data = json.loads(data)8 f* U9 u# J* m; S' Z' F3 d5 z
    0 C$ E% s. H# u6 `
    # get the points ' h) H- R, x3 k
    points = data["shapes"][0]["points"]4 S) @; \  T/ C! \- }# U7 c& z( m: [
    points = np.array(points, dtype=np.int32)   # tips: points location must be int32! Y  d) Y5 C/ H3 @2 d" {

    3 p" T; c+ w9 @6 D) B# read image to get shape
    + Y! i) n9 H; H( k: x; w2 [* M5 Qimage = cv2.imread("origin_png/person.jpg")
    $ u$ X) @1 K! F
    , t, }0 J6 g" G# create a blank image
    + p- n' C+ ^, ]/ L2 R, b1 y; l3 jmask = np.zeros_like(image, dtype=np.uint8)
    8 ^/ f3 _& M; V0 n- {$ B% G; k# v( s9 W$ s
    # fill the contour with 2557 K8 `* l  _. c9 {$ G
    cv2.fillPoly(mask, [points], (255, 255, 255))
    ; E1 v5 D2 u0 S( i: o; z' q' i' N( n+ i1 |% `6 ]# X6 w* Q$ x& V( M
    # save the mask : L" W4 z0 J! \, {7 z5 [2 w
    cv2.imwrite("mask/person_mask.png", mask)
    5 h* D$ t; C3 g$ @9 X8 |, m1/ U+ [, ?2 F: o6 I5 k( z8 a: d" |; j
    2: M; L# ?+ Y2 K& Q/ r* e
    3+ h) [% B& @3 Q/ g) k
    4! a" ]+ N9 ~& r! Q! W4 T9 S
    5  T& o* P! }$ s/ q4 r/ t* _1 P2 d
    6$ M; f0 e' O2 n8 L7 s2 H3 x, ]& Y
    7' w8 g9 p* T  W$ k
    8
    ( I2 ^# _4 K. J) P2 I* L: ]9
    & }2 u& d+ n8 E. F1 D9 M101 i8 P. i  v6 _* {& X: h+ t
    11+ C, L, {8 e( A1 u; t
    12
    / [$ L7 [8 J, t1 L9 X* z3 {' n13& h( L; ^/ ?2 [% M
    147 ?6 c% g  g8 X  Z7 g0 H3 _
    15& i$ T4 w6 ~. A" A. o
    16- R0 I' ]) T6 @$ Y1 @: ~
    17
    6 A6 G0 J" I, g8 t- n( ?& e. \18+ d2 @8 P% R: v- C2 W* K) S- M3 y
    195 @! I1 l8 k+ z' m
    208 r; r( p7 w1 @
    21! O/ q  m# {; U: X/ {4 K
    22* Q8 {6 }1 C" \
    23$ R- e7 ]- [8 z( }
    246 e6 p9 \! e7 G( O; `' D
    25
    # O% N# S$ u& C( q( J261 c8 @6 s9 j2 M5 h/ T* @8 j
    大概是这样:
    ; b$ p$ K2 q- J/ d' C
    ' X" _1 y4 l: m% U9 p5 H1 |, F/ D; \6 ?
    然后利用这个mask生成图片$ m+ c! d  C* D/ a& q4 Y6 {

    3 @7 P8 D* b/ y- O# 参考自: https://www.jianshu.com/p/1961aa0c02ee
    * I2 Q* K% _' ~+ @import cv20 X3 a+ u5 p- S" o4 t% W: D3 o6 j
    import numpy as np4 m8 t: k6 _6 v- g# ?

    & {: P" G+ f$ E5 d  K/ l$ Q, ?& U3 D8 l, ]) G" W' t
    origin_png = 'origin_png/person.jpg'2 m* A2 |" p7 O, V8 S! s% |' A8 ?
    # maskPath = 'mask/person_mask.png'
    2 M$ T+ s. D3 B* e1 r2 w9 f, {maskPath = 'mask/bmv2.png'7 |$ q. [# t; x$ Q
    result_png = 'result_png/result_png.png'
    - Z% M9 P1 g& @& n# a& F+ c5 X# _1 t2 K. k8 D* p

    ' F' ]5 }& q* D; h3 F0 H  R) z! [maskImg = cv2.imread(maskPath)# W* m. |0 m$ e* U" g
    img = cv2.imread(origin_png)" w9 ^1 c' E6 b0 p
    assert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'
    0 H' L2 p8 Y' D9 a. m) s4 N" T" w& v4 p" t5 ]; z
    h, w = img.shape[0], img.shape[1]
    6 y8 Z0 E3 m% p( Vprint('图片宽度: {}, 高度: {}'.format(h, w))% k8 P3 H2 S& b, N
    5 C# O8 Z7 M. b/ b1 Y
    rgb = (19,122,171)
    2 K6 v& E0 i' }& |& D( ^bgr = (rgb[2], rgb[1], rgb[0])
    1 a4 p/ L  k/ r) f- X# (B, G, R)
      m  D6 m# r7 h) w" L' P. y0 sfor i in range(h):: p$ f$ ?9 ]0 Q
        for j in range(w):6 C% p9 {8 M3 ^
            if (maskImg[i, j] == 0).all():
    , i! ?' a' j9 F8 x- |6 v* l            img[i, j] = bgr+ [; X1 r( e- u4 F/ N  [6 V
    cv2.imwrite(result_png, img)
    % ^' K6 |2 d- C7 Gprint('图片写入 {} 成功'.format(result_png))/ S5 T( f( m" d" C& c/ N6 x1 l
    16 i. A+ z7 n* w+ y' `4 o
    2
    3 s" h7 r) R- l. r37 T: o% G: \! b5 i! ?
    4+ R7 d* A# n+ o' R# ~
    5
    3 F5 F) y3 |  e9 D$ {. ~69 n5 u; @  i! v  F4 A+ e
    72 u* w: ]/ U; n% \; h
    8( Q5 y) X1 H# N  z1 U# ]2 `& p
    9
    9 @3 p7 u5 h0 N) x7 ~100 t4 P- B2 y; v0 \2 d
    11
    + _6 u% w/ n- e& V" T3 R8 s0 }& E9 g! P126 K$ c. v  @! l1 E) p5 W! y
    13
    & P. y; ]& }* F$ M7 P14: T. P8 A/ r. f
    15' v0 X. J! z' _# \
    16- \6 {0 Y0 J' j& z
    17* G7 f9 O& [9 l2 i9 V+ G; I
    186 W* I# W* R1 T( x
    19
    9 J# J4 f# {) m+ t- U4 F" R, ]20
    7 s; N/ h5 z! }* e' J21
    + ^$ H+ J! U; C; }( D" N/ E  a  ]22; i& D4 n" n8 N) ]! b# H+ n
    230 }+ A( S, P- D% Y  ?3 K9 V
    246 p4 g) \* u* B( u1 {
    25
    ! _3 R4 [8 |9 w( s% E0 g26) w, a4 U( A- T9 u9 C4 c
    27
    , I8 \8 G3 A3 c5 {7 O9 U3 i' w7 D! _由于人长得一般,就不放图了…2 \) p2 Z/ d2 ?2 }: `1 U% b. H6 h
    1 z! t3 z" D2 K" I
    缺点:
    - }- o& N: ?* ~4 x% llableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。9 [3 N% E+ Q* l- A

      v) v) M6 [0 f0 R, z+ H. x5 D9 F/ y8 t% l

    3 `- }! \- t! I! J2 Z, ~! n! r1 E3 d) q

    9 M& Z0 L# _+ l; S' `/ U" x( [7 A方法二: 阈值
    . T3 A0 t1 V  s. i* J该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。
    ! p/ O; ^5 l9 l5 {; x3 c/ K) [6 e) V. _9 Q& O$ {% {
    Opencv% i8 [1 I; w1 n0 J
    import cv23 \1 q5 k; t  ]
    import numpy as np
    9 N0 }: N) ]  D' ^! K2 T( ?, A
    ( K2 L0 t% e; z8 t/ [2 }. O% G
    1 K) D' Z. J4 E" m  B3 E* adef mean_square_loss(a_np, b_np):
    . e2 H! c( W! L) u+ g8 J' g5 @" W    sl = np.square(a_np - b_np)0 [$ ]2 i# y0 `/ W9 L6 q, k( r
        return np.mean(sl)
    ; _! m2 q7 v9 y/ q. ?; i; U/ S& M& O+ A) T) |! ]# Q
    1 h! _$ ?$ |# o& e2 s; Z
    def change_red2blue(origin_png, result_png):+ m3 V$ [0 @/ N# h" X, X
        img = cv2.imread(origin_png)
    ( Z2 A4 O' X9 X# t6 |' h3 G9 V
    ( e. |6 F( U& g' [4 S+ ?' ]    h, w = img.shape[0], img.shape[1]
    6 Q# v/ b" [' o  _" Y    print('图片宽度: {}, 高度: {}'.format(h, w))
    4 A# ^6 A* C- E3 M7 ~9 A  u
    : j  e% n+ _7 o; C! w5 x    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值( n/ i# }1 c1 m
        origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])9 G9 N3 r* {* o( c: {4 c
        target_rgb = (19,122,171) # 蓝底RBG
    7 J* ]" u7 |8 V% p% y    target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])1 H3 `* c* R" R0 \/ z: M8 b

    8 u+ u- T( i1 m3 v    for i in range(h):
    " {- B3 |- Q2 x5 w        for j in range(w):- A& }+ d( ~# f1 S! g' q
                # (B, G, R)
    - P1 B, D# P; z0 j! r& F6 b            if mean_square_loss(img[i, j], origin_bgr) < 50:
    5 z' o& d/ Z9 A# r                img[i, j] = target_bgr + R  h7 s! x) `. b6 p

    * I+ ?8 y. h2 E4 e2 }    cv2.imwrite(result_png, img); L' X+ l) e# t3 v# F& C
        print('图片写入 {} 成功'.format(result_png))
    # r" O% B) A8 O9 G" b* f# T" h4 p/ m1 j% v# y

    , p+ v2 I6 {. R  Jif __name__ == '__main__':
    ' t- W( A) L4 l' [  f: @    # origin_png = 'result_png/result_png.png'/ E" O( N. _) q% w$ A9 h% w  e
        origin_png = 'origin_png/person.jpg'5 [9 V5 \) a, h" l2 _$ e
        result_png = 'result_png/result_refine.png'
    - B) [% O2 d) O- D8 @    change_red2blue(origin_png, result_png)
    % ~3 N  o/ O' L3 \1
    & S7 W. ?8 M' U; o2
    3 `" T$ r$ D3 J0 Q3. X+ ~# m+ [) C. T" w
    4
    9 o8 z0 y" ~( ^" s5
    + j; K1 W7 ^  `6 Y6 b' Z3 v6
    ! U$ {, }, x8 f) v" U& K3 ]4 ~  Q7, T" _( ^! Z# E5 Y
    84 d" o/ L: N+ S* K9 m/ i/ o
    9
    4 l( |# U. G) Q8 T10) x  W& W) r6 |, m5 H% }
    11+ L) h. r7 d) P! U5 ~
    12
    6 P( @+ E8 H* P132 }; o0 p# b- j. _7 ^
    149 d9 ]1 ~; m) I9 V& h
    156 u1 g% o7 E: D# P- O
    16
    + Y7 G; L, ]$ k/ M- J9 ?17$ F) m2 C: E, b  G5 r
    18
    ( ]' V" g% p6 a1 J19
    5 j% `( J: r! H) ?20  i- F# A% o7 v" o) v" x
    21$ P, `6 j1 @# i$ z# E
    229 `. ^  k& d6 X! i! l7 X1 o
    23. h( U5 F) \! M
    24
    8 b% _. A2 {* u3 k25+ r3 J+ M5 x. x8 p1 ~8 a
    26( x0 D5 [% N; C: ^
    27: Q3 L! W  O$ N$ R, J
    28
    4 z' i8 E3 e9 ^3 Y! I5 g29' U" {( \0 k) c5 H" C+ |2 Q' \
    30* H' R8 k0 d6 r- u: r
    31
    5 }( H5 b4 u1 T/ u1 L7 y6 n320 k, v1 s6 G) _& ~' u, O3 |: E' ]
    33; S* ]2 v/ H% M
    34
    # ^0 G6 z8 x: I( l4 E35# s* d% ~6 P3 Q' t& n5 [
    结果人与背景边缘仍会存在红色像素残留' l" j' x# v' _; v* K" S( ]0 H
    ; i9 G; M3 Q5 g3 k2 D
    : [2 a- \7 b, `7 H5 y3 ~

    # r* q7 a, y0 j8 M9 x+ v$ h9 D* I+ [9 _

    $ Y3 ]: P4 V- e" z% OPIL
    * a* [1 E% o  L8 b  t$ d) F9 Q) mfrom torchvision.transforms.functional import to_tensor, to_pil_image
      u) k' d$ m2 n5 V5 n9 D2 I; yfrom PIL import Image
    5 I' @9 i7 p# \% `, p3 Z% V' `import torch; [% g, W' R' t6 d- R: M# s
    import time9 ?, w! t8 k1 W% \
    % D% B" t) E$ U% T& h
    - y# R) o4 T. N3 g8 B4 x
    def mean_square_loss(a_ts, b_ts):
    + Y0 B- Z, J% L, V7 Q7 l" @$ B    # print(a_ts.shape)# g, S9 ^( |; r9 Z0 e1 p) S
        # print(b_ts)
    4 p' S. s7 x! ?, N: ~8 {6 C    sl = (a_ts - b_ts) ** 2. Y* M8 F1 T6 R. G* D9 `, q6 Q
        return sl.sum()
    - \% m& l- N8 @# `9 _) }  v# H! N) W, s& v' J. D# j* z
    9 K* d' Z( N! G
    def change_red2blue(origin_png, result_png):
    9 i( r- L+ j: z+ j' \8 M; K    src = Image.open(origin_png)
      h# l6 V  T6 h4 H) y8 ~    src = to_tensor(src)
    * `* `' k* ~4 @. T7 C3 ]0 A    # print(src.shape)  # torch.Size([3, 800, 600])
    1 Y7 n2 ]! c4 D/ g. t    # channel: (R, G, B) / 2557 f$ t9 r1 _0 w+ Y; Y& j: `
        h, w = src.shape[1], src.shape[2]
    0 x" D3 e. P# t( L0 q0 [: J; Q2 F+ B- o( G8 @
        pha = torch.ones(h, w, 3); K- _; M" O4 X1 p

    3 W, `2 Y8 y& H8 Y    bg = torch.tensor([168,36,32]) / 2552 D- i. P: V) }1 C  L0 t
        target_bg = torch.tensor([19,122,171]) / 255
    / c* k1 q" Y$ M+ V; m! J+ {9 ~
    , K, @! m! V) ?8 {2 W    # C, H, W -> H, W, C. h  `' J5 \* J+ x* L1 Q6 c
        src = src.permute(1, 2, 0)# S. s& N% r+ r
        for i in range(h):
    4 n4 K6 A$ Y6 [1 D- H( q        for j in range(w):
    . G; Y% c! f  s8 I7 }            if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数8 J( A. s& |$ q
                    pha[j] = torch.tensor([0.0, 0.0, 0.0])' f# `0 j* d: C& C, x) r

    1 l( N; O* w! g( k& }) e: q  `0 d    # H, W, C -> C, H, W5 |9 Y  R. b0 i% e! ^, \+ E/ d
        src = src.permute(2, 0, 1)4 @- _3 u' T% T
        pha = pha.permute(2, 0, 1). Y! J/ g% }( l3 x. y/ e2 d
        com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)3 o; T& u8 s# x8 [, W
        to_pil_image(com).save(result_png)0 {, b4 f- y- u" ?

    ! M) a/ e8 l/ i; V& \4 q* e5 H
    ' j# F% b' p) d- fif __name__ == '__main__':
    - K8 b0 {9 K' ?    origin_png = 'origin_png/person.jpg'
    . P; T1 ^, r9 I7 X3 m# s! a7 o$ o    result_png = 'result_png/com.png'
    0 V2 R" i( O) C: _7 S& ]    start_time = time.time()
    % t5 O) \" f! A' q5 d    change_red2blue(origin_png, result_png)
    3 u# k: H" ]9 r9 n; ]# M% P    spend_time = round(time.time() - start_time, 2)
    2 ?3 M/ j3 x% U. g2 X# R' B3 K    print('生成成功,共花了 {} 秒'.format(spend_time))( p; a! p5 o# }0 }
    11 ]9 b2 l% }4 s4 u, m( o& L
    2
      j+ A4 F! F+ z  X7 w0 \5 f; y2 y3
    1 C6 \, \5 @( m0 a& V: ]' d) @: o47 N# r( C2 F/ v- t1 T5 u
    54 k5 P- F0 t* }) i) w, Y( k
    6# X! Q) {- O4 X
    77 X! L% F, V5 v9 W6 v6 _5 M
    8
    + i. t  e8 P, r4 b9% [) \6 U$ _! p: U1 F# v
    10
    6 B/ E8 y9 u, o1 e$ b11
    6 X3 Y: e( P9 U# M8 ]12
    % l) r8 C5 c: Z# E2 Y0 \. ]13* ^' l* d& `2 {, C% Y  X/ o0 E4 x  @" \
    14
    3 U) Q$ }" Q' G/ m15
    + I; R& I  k# I1 b8 o  B: E16
    3 Z* Q& v) T- d170 b6 k' _+ i7 k2 G9 z
    18
    , D/ r% S) k" v; D) S+ b) |8 H' _19! J7 O$ e- Z% ]+ m: S$ c1 [9 g
    205 l: v2 N) e/ {6 h
    21
    5 k. }# p& n1 i  q" A% P22
    + n" T9 t9 {" ]3 a: ^- N% x) f5 t237 F+ P' ~. k% K% V8 v7 ]8 e
    24, e+ N; c- ?1 B: j7 J  u* g, `$ P7 H
    25. a( A7 C# ?; U. n
    266 ~" Y; Z5 c4 m, d2 ~/ X$ [
    273 y) j# K( ]6 F+ b- W
    28
    8 @- T9 _8 I* Y! Z4 ]2 A$ I297 o9 x, e$ `" l6 ?& F0 S9 E
    30
    ) |& c5 h7 D' x$ F315 g' V! J! P9 o+ l( J
    32/ x' T( Y' A  |; m" I
    33
    . X5 `1 h3 o" j! G3 k0 [7 ^34; @  t5 C# \0 }. a- k( N/ _
    35
    9 ^3 Q0 L8 Y+ _369 u2 P* s  V! Z( A8 z3 x
    37+ `7 ~" Z, j) q" j  k: g
    38
    9 o, R+ f" ~) e& D39" V& k, V5 b7 p
    400 V1 G- t5 Y7 h1 f3 j
    41
    ; |/ t' y$ S" `$ i; P5 F' a! |42
    ! T5 P, h: A6 N, J" x+ `; W1 [' y43: D, `, }* g' p+ m4 z' V/ I9 h. R
    44
    : H, I! Y: D, U$ _! q45
    0 c$ r9 C/ R' T464 M* f( J7 D! w9 }# P$ A. ~
    该方法质量较好,但一张图片大概需要12秒。# h4 S1 {, L, \; I  P
    2 U$ K& ^* j/ Q+ Y1 u# X& q
    ; K; M9 H5 M+ [' S

    : n3 m  z! J& X  Q) g& ^1 m方法四: Background MattingV2
    ) B* }& ^, [. o4 m8 |. y5 _Real-Time High-Resolution Background Matting
    & ~0 @7 @0 [3 {0 ?CVPR 2021 oral1 H; K& \* G) [: w

    ! B+ M' F' T1 s论文:https://arxiv.org/abs/2012.07810& |4 R$ R; ~" z
    代码:https://github.com/PeterL1n/BackgroundMattingV2* p- c0 a, Q; m* ]: j1 g5 a2 B5 \
    $ W. O. b! [) d! O% ^# P
    github的readme.md有inference的colab链接,可以用那个跑/ d# L# P3 T- c( h' S+ H8 j
    7 T# ?- B6 W' a7 E2 c% R
    由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。
    $ E8 D+ e2 j  H* U6 f4 _4 i0 B# K  [0 q
    于是这里我需要生成一个背景图片。
    % |( ~7 y) j0 t- n! M' q  ]首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。
    ; B4 n2 L1 R2 p; b: R0 g+ d  P: p, L# u  T% U) G& k. x0 r$ H$ v
    然后生成一个背景图片。
    7 i3 X# Y5 {8 \% s+ S/ |5 M; R0 e- u$ L0 p2 G
    import cv2, x- q2 W+ m, T$ h; B! n
    import numpy as np
    ( ~+ T: i' t* V. }  p$ ^/ b; a- O  l% ^3 c9 O/ v: \

    - l) O; m  k0 d2 O/ m4 pimage = cv2.imread("origin_png/person.jpg")
    6 P9 f) v' l9 N& {  I* `: Rorigin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值1 |8 P5 [6 o6 G; {9 H4 @% }; M
    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    . p/ q6 `8 e& l- a! i3 i8 p3 p- u1 ]image[:, :] = origin_bgr
    0 i4 P; [# [% y4 `1 D) |+ q' @7 E, Q
    cv2.imwrite("mask/bg.png", image)
    8 a, d1 O- c+ g- z0 b$ W6 r1, ^& W8 Y) H5 Y( Z, I9 f: e
    2
    9 V: S9 _& A) z2 q9 p3  b6 K1 p% g3 B. X+ y' w* P% e
    4! y. h! {: i3 g
    5
    4 ~; l- `4 T0 ?2 P) M* k6' t+ b9 X) V1 P8 V; x( \# j! c1 E
    75 f5 b. ^6 c% ~7 I( D! S) `5 l
    8+ j1 w& T: d9 q# K! c
    9
    ) `+ k- c0 [! a% x8 Z4 j10; ~6 V/ W  t7 F' t, z9 H* F
    7 q; }% k% R+ ~3 f' {+ O
    需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码
    9 r6 m! g! Q' T: Z7 Y; W; ^$ T5 C4 T1 F: P
    src = Image.open('src.png')3 o5 M7 \/ H3 P9 N: i7 ], n; j$ P
    bgr = Image.open('bgr.png')
    / }& X: n' c+ j% |2 k% t" B1
    7 e+ R! k! Q3 m2
    . t/ W' H( `  t4 j8 b7 x另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)1 v" K- p/ _: T

    : C) h- E4 b: f( m* ^! _* Jcom = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)" p; `6 T/ w+ T. w* h
    1
    ) x* }. `$ C7 U' J2 C, u- G, D
    - F6 r& ~# H2 V, y' k; r$ l7 F那么加入我要换白底(255, 255, 255),就是3 M2 Y* \1 v0 o' w9 Q
    / b0 V% a3 l! q& v+ K8 r5 p: T
    com = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)
      [# C" o# Y+ z3 e2 h$ a- @1
    % T1 e. S/ ?; l) \+ L9 H6 f' k5 E- A" S
    假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是; P- H5 q- {2 ^! L

    4 e6 _: M! c, g2 ^, R' ]1 Hcom = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)8 Y5 G/ ]; ^: M+ g; B# e
    1
    " Z- I! _9 S/ }总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB., c9 V+ o# L" {) P1 ^! W

    & T3 I6 F2 A+ F, M1 j4 \8 \然后就输出图片了。可以看到效果相当好。不愧是oral。+ d% E6 M) P5 I- ~% m8 y& i

    ' _: b' d5 v8 y. K- V* ^4 t8 C- [( c5 a/ `
    原论文可以实现发丝级效果# r: e# J* ?4 ?. e; t$ g$ n8 [

    ; r7 B7 a3 \. b: y. s  x3 s/ i, C- ^& ]+ K% P, B- c0 y+ E
    * F9 T2 o" D7 q6 j/ h7 {3 n
    ( C( p0 o" i) o9 P( ^. W& J
    " h( H% |! c2 J+ C8 K
    报错解决方案
    7 U8 A( I5 o" J  b6 ?can’t divided by 4 / can’t divided by 16- ~. u0 `0 m0 t& L1 p, \
    由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。
    6 I& V7 Z  S% r! F3 l% j这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize/ z8 y% r3 G- i/ S& n
    ————————————————
    & ?- s+ Q$ U- V& `: M- c版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。9 C/ k( u+ m: E9 z  e- s2 w
    原文链接:https://blog.csdn.net/weixin_43850253/article/details/126376767
    / l- S: ]4 \6 z1 f) W* G7 [
    ; Y0 [- q& G# K! e* R5 [, _
    ; s/ d  d  Z0 u+ P. n& _
    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 21:38 , Processed in 0.563621 second(s), 51 queries .

    回顶部