QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2113|回复: 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将红底证件照转成蓝底
    0 B, \! R, E$ `) z) @9 C前言$ W  j: i: f: N  T% O
    emmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。
    : b! x9 L. c9 {" J- X
    . P5 n+ p% |* m% T' ?4 ~7 ?
    , k2 W6 K1 L% d  n9 F; F0 u
    " O+ T( D7 q7 @
    / i; r' r0 `9 a9 ^2 @+ Z( l方法一: lableme' e' u. v) A6 z3 M2 s) E' b
    lableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.+ `% @2 ^$ d, W( S

    ) i+ N: D  R5 |0 M  ]7 ~6 J. j# 代码来自 https://blog.csdn.net/hello_dear_you/article/details/120130155! e- O4 U3 d" D4 C% l
    import json  Q: Q7 g3 G/ f8 Y* h$ b9 j1 j2 U/ y1 {
    import numpy as np
    % C' G# W' B8 t" dimport cv2
    9 g! I* }6 N( F) @' s# read json file
    ; E+ v2 Z7 |" e- |' i$ _with open("origin_json/mypic.json", "r") as f:$ X4 v7 W" m0 F, W% N4 _
        data = f.read()
    6 P1 L5 z- l& G; P0 v  f
    0 n6 d- N* F2 T# convert str to json objs
    . @/ U3 V6 ?9 y1 ^! \3 odata = json.loads(data)
    6 |; [8 Q+ L$ T4 Y" ^+ q' ^! W. `1 c  {% t/ q8 \
    # get the points
    : L, [5 a/ E4 [points = data["shapes"][0]["points"]
    ! a$ S; @6 n  S) Vpoints = np.array(points, dtype=np.int32)   # tips: points location must be int328 X) ~1 Y+ ]3 `+ T" G

    0 ]$ w' \& F* F- V! b* E# read image to get shape3 F9 j1 M( K; H
    image = cv2.imread("origin_png/person.jpg")( g0 g4 N5 ], `/ B9 z1 O6 u5 [

    $ q# V4 I, K; _; }" Y# create a blank image
    1 V$ d9 n( J5 Smask = np.zeros_like(image, dtype=np.uint8)
    " `9 @. }" a7 r4 b& G* c+ `4 p0 k3 `) y0 u
    # fill the contour with 2550 r" s+ F, |! q# ?) h( K
    cv2.fillPoly(mask, [points], (255, 255, 255))
    & w# F5 M8 q5 k* s5 @7 W% M) V+ ~" L* r" w7 @5 q* E  ^9 o
    # save the mask ) v5 H4 o8 N9 }
    cv2.imwrite("mask/person_mask.png", mask)9 h( H. d  T" Q8 L7 Z
    1
    8 [/ D& Z3 g& J# p" K2* c) P5 ^: b3 N6 L. p
    3
      h6 D# b. X# L2 ?4
    * [- |- r5 u, r  I" N7 w5" f9 z% [, ^5 V5 C
    63 j3 g" ^5 l* B" M
    7
    ) k0 K2 s' y" K: `3 c, M0 I8& I+ K! }1 Q9 U" r* Z
    9
    7 M+ U* ~; n- h0 o10
    1 ~5 J+ h% g4 t11
    9 Z; L0 {/ W/ s, Z. a+ j12- k. |  J' w7 ?: K5 f% \1 ^
    13- M9 c: j8 N, T! C8 I0 Y, J7 D
    14- b, }: x5 N+ q+ F" ?/ y0 U
    15
    2 W; l4 z4 R% [; e1 d) T7 L16' M  f6 M- b) K  d: V# a
    177 ^# x3 O$ [5 k/ N* b  S* Z& W$ t
    181 t! a) L4 L/ B' R5 F* {6 a' q
    197 D/ n3 Y: b! o' d
    20. s- ^- }8 Y7 ]' e4 C
    21
    + r7 U$ t6 p6 t4 P  e! b6 u22
    : Z* I. Y) @% d. o, f- M234 U" e- `% V- n  K0 Y3 X
    24
    9 I; I3 F: Z7 l% n, T! U( `25
    $ Q. Y3 t' G* r+ G& u" L* B. ?, x3 v26
    $ K" o3 [9 J' ~4 T大概是这样:
    6 D4 ^( [5 M7 U% N1 |  v! v$ q+ Q0 [" u  ^% ]7 I; d8 u* r
    / T/ C$ |' x8 E
    然后利用这个mask生成图片$ P& J' ?8 s# e# ?/ h8 `" w
    ) y% M: u; t" t% B$ F7 e
    # 参考自: https://www.jianshu.com/p/1961aa0c02ee
    + R2 `$ W& i$ x. E  @0 Nimport cv2" P- f8 P2 j$ ?! c: E9 Q6 j4 m
    import numpy as np. ]0 W: V" W( I3 ~" n5 O( n3 b# b

    " N; o& H' F& s/ @: M/ H7 Y3 i: e0 {) p1 C
    origin_png = 'origin_png/person.jpg'( e7 y2 t5 }! f
    # maskPath = 'mask/person_mask.png'
    / A2 L0 c2 Z, G3 X  q8 e! VmaskPath = 'mask/bmv2.png'4 H$ q, @+ Y7 q; A2 x# j4 n+ k
    result_png = 'result_png/result_png.png'
    6 B; o# P/ Q: X/ {  I
    % ~) r& \$ ~8 D5 L& G- O% k* u9 H% A& h( T' ^* Y
    maskImg = cv2.imread(maskPath)  e9 d$ i( J$ G
    img = cv2.imread(origin_png): U. \+ L$ e$ p3 `) N
    assert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape', b5 d7 I! p8 P  c3 D5 [
    / g' ?+ g5 N  J
    h, w = img.shape[0], img.shape[1]
    2 Z! I( }( x8 o+ Zprint('图片宽度: {}, 高度: {}'.format(h, w))
    ( H  q0 ?- ~0 j1 Z9 p# j1 l5 M- z6 a# Z. Y) u% c3 F2 U! S. ?  O) g# T
    rgb = (19,122,171)0 a' y& ~- p( N1 x$ }' V
    bgr = (rgb[2], rgb[1], rgb[0])! L9 e2 U. F1 L( d* }3 [1 e- c
    # (B, G, R)
    , i4 a9 a) i0 u2 V0 H  Ifor i in range(h):* [* P8 J/ ]3 i+ k) Y
        for j in range(w):
    # T  e3 _, x* }! n        if (maskImg[i, j] == 0).all():
    + e5 U  G- t3 X9 Y$ ?            img[i, j] = bgr6 p3 U9 F7 f4 C  }3 n
    cv2.imwrite(result_png, img)
    ; n- O, b/ c8 {print('图片写入 {} 成功'.format(result_png))/ e0 y& M  S* E7 E0 l8 \( T2 I
    10 F$ D+ d' e% ^. Z, ^" ^
    27 u+ }5 @8 ^% E; G$ Q& ^) A
    3: t6 B* q3 L7 p1 J
    45 S# P# r3 D, H/ x8 z! t
    5
      \4 _- j4 q- ]3 b- R3 K; X6
    : [: s6 k3 c! o# w0 g# k7- }$ `' u! Z& S) s. T
    8
    & ?' S1 c. ?+ b; Y9
    6 M2 x1 U, F$ X# s: F8 I- B108 N. G% [3 Y- ]1 Z! u5 G
    11
    8 L. d: N  g+ F! R9 A# r12; E2 P( @9 G7 E9 w" X
    13
    - b+ T2 o  x' c; t+ {+ U14  h0 f0 V% E1 n9 Y9 x9 V  h
    15. ^$ ^4 y4 {2 c* g. n
    16
    0 H) w# }1 P% }9 p- Z* E17
    2 A5 H9 @3 o  X8 x4 _18, K* J1 ?2 _) M" [$ a# V, s: Y
    19
    % P* E8 f4 c% C' l' S20
    ' }5 j, B6 [; W/ r+ x9 e, A21
    + Z+ `& G0 |: n* A! S: K22/ m' e: p' H# G
    237 R4 T9 Q1 G$ g! u
    24
    & V# D2 }0 r/ }4 a. c, _25
    ! @; ]: l" Z! T0 x26
    ' B3 v% w  u3 |* d6 S( b) Z27
    2 x/ W0 `/ h- Q, n由于人长得一般,就不放图了…- S2 o5 s( A( `+ R* K2 l
    ! e. A, W$ u7 i
    缺点:
      j/ Q6 k; n) |  M0 I( A3 t+ I# |lableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。
    5 O+ F  ?0 D& J$ Y
    3 b. T7 a8 `6 d8 ]0 x' B7 J. b! W9 U" d

    9 I. H- q2 o7 n) b5 ~# Y4 P# L5 S9 h$ e- ~% o
    2 ^" E3 ~+ h0 e- f' g  ^0 o0 @# {
    方法二: 阈值4 G. A* m: T/ W3 l% [, j& a5 ^
    该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。7 l- L0 x8 z, D

    " q. F  L% L5 w: k) ?" k+ z' yOpencv: t6 U+ ?! |0 l
    import cv28 L) i4 B: M7 ~; e4 H
    import numpy as np4 ^* O, f; U! E  r1 L

    : a; G4 u  Y( A( C: a: k" v* |8 Q+ \6 I+ [
    def mean_square_loss(a_np, b_np):* ^, D9 |3 X+ A- m3 g) {
        sl = np.square(a_np - b_np)
    1 X6 t' L) [* S; N2 e4 Q. q! b. X    return np.mean(sl)# s1 n8 F/ L. J0 M
    . d& [2 g% u  Q% W9 p9 m& z3 N
    5 `: y+ }1 D. _( ?( @( a
    def change_red2blue(origin_png, result_png):2 A$ R* A2 v- j1 `/ g& k
        img = cv2.imread(origin_png)6 O+ x7 D# d+ n* \) N9 U
    3 ]9 B9 o0 R: R/ Z# Y8 ~
        h, w = img.shape[0], img.shape[1]
    " o$ g$ x0 {' j0 q' `' u0 q  d    print('图片宽度: {}, 高度: {}'.format(h, w))0 X1 L, {. s- E; j2 R5 T" F
    , x: q1 d! X5 b  ^8 f
        origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值5 C8 Q. ~& k- L/ Q: y3 y
        origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])& D- A  b. _& n3 K- k8 I5 e9 v/ O; |
        target_rgb = (19,122,171) # 蓝底RBG
    # c7 J9 ~+ ^4 a; Z    target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])
    2 A" z. \& y/ I& r7 _; y/ ]7 d& ~/ Z3 }* Q1 w
        for i in range(h):1 A$ A9 i3 L, g* I& [( g
            for j in range(w):! ?2 u/ Z. f$ ?: {1 R' `* A7 }# l
                # (B, G, R)
    / m- c$ R( a, Z' E. ]$ b0 N) M% \            if mean_square_loss(img[i, j], origin_bgr) < 50:
    8 m1 d# b( M8 o/ |# B0 V4 E                img[i, j] = target_bgr % L1 h) g( F( `* N: _

    & Y+ y& h8 ?  H' x' m, ~$ j% H) c    cv2.imwrite(result_png, img)8 Y1 K4 j+ v0 ~& e
        print('图片写入 {} 成功'.format(result_png))
    3 \2 f) G! R# U3 U+ v( e: @  i6 K
    & J- u2 e6 Z4 C* O$ a2 m! Q
    : T7 T+ S* [( M4 X- }* r8 U" l' aif __name__ == '__main__':* T, K% K, ], [7 [7 ~$ B+ K( `+ G7 G
        # origin_png = 'result_png/result_png.png'
    - e9 E1 H* ?7 |/ ]/ h- C: b2 y    origin_png = 'origin_png/person.jpg'
    7 N2 @$ p1 l$ x8 g) V; F    result_png = 'result_png/result_refine.png'3 K) ~& e9 I! a7 @1 R& d
        change_red2blue(origin_png, result_png)
    4 Z* A+ t8 l) f- z15 C9 L  M, d# g6 u
    2
    0 q7 r6 o% @0 a5 U3: L% U2 [7 n9 R! ?2 X: `
    4
    ! Z( E: U1 s6 h2 A2 i: _" q2 f# u2 u51 J+ h% ]2 [7 s
    6
    3 K+ z, \; q: r) h7
    $ `  L$ X% s" |! H, w, N8
    7 H6 C9 O. L0 C/ `0 @  {9
    5 E9 S* V9 l% J# k2 u) M10+ {% d3 |8 \0 q( U6 Q9 k2 G
    11
    7 g2 J2 Z$ X2 y0 {* q; m8 I12
    7 [+ q! W7 e9 C132 o! I( I/ n6 y3 G2 J' v" s
    149 L& @( w$ S6 E, ~
    15% U8 I  `. R# T3 o1 U, N$ g
    16
    . T% f: |' w& a6 R: l& |17! c) k( p3 b# C; z( k
    181 D! v7 @$ G& N4 e, v! p2 `
    194 H; v+ {- X5 K
    20( F' x4 P2 W! a% h
    21
    : x+ ~5 K7 e* U9 \6 C22& z% ^6 C' }4 ]! }  O1 u* S
    23
    6 `! b, i6 o+ G7 c0 y8 c24
    : F8 k( X2 y1 f2 C' M, X! @/ z5 z! n/ k25* r9 W8 B6 \5 G5 z5 t
    269 U! B& U2 S) L7 V7 E8 v3 d
    27
    ! @8 R: A, z$ U. k$ N9 c28
    ' y3 z; N& |2 j1 @6 W6 q" b  T298 O) \+ c% w( e' q4 W5 W
    30
    ' J& W; w8 x* B1 |* O: a31# J/ p( D( U; `5 N' w$ z$ Z% @' s
    32
    ' a$ [1 c7 }/ P# {, o1 o/ S33* `! g3 D; O, ?; i
    34" a0 O) O# S$ a& Y5 F. C$ w
    35! W) ]% T* R" x% D4 q
    结果人与背景边缘仍会存在红色像素残留
    8 q5 ~! H7 G: Y9 u3 H4 \9 Q3 _
    / J1 C- V" X% i. n- ]$ }' J3 N1 _0 ^% X$ p+ h3 B0 [

    , y& C7 G& h+ E- ~
    8 N$ Z4 i9 H! r( [- {
    + A& a5 {6 o2 R) nPIL9 e; z4 s" i6 ^$ O0 T8 ?" t; X0 i
    from torchvision.transforms.functional import to_tensor, to_pil_image* L5 ?- J6 W5 k/ z# x1 R# F! O
    from PIL import Image& U( B! y4 D% N' Q& P1 _. l1 c
    import torch
    3 w; {9 d6 k- m% S- rimport time) L; B6 }7 {$ r1 [
    3 H5 n2 i5 n. e# w

    % @6 f  h. ]3 M0 z. i2 X, S0 Adef mean_square_loss(a_ts, b_ts):) K( R" G9 e: W* g
        # print(a_ts.shape)
    + p; J! N$ @: @) u3 W    # print(b_ts)
    2 }; C# J7 h9 R  D    sl = (a_ts - b_ts) ** 26 H' A: D% d8 Z! `# O, H) t
        return sl.sum(), E5 d# `$ L( l. n2 H* y/ s
    7 j7 Z4 E  I2 l* ?

    / e2 r( W* F* }+ X( c9 `def change_red2blue(origin_png, result_png):& F* A" x+ c8 c/ y- ~1 i; a
        src = Image.open(origin_png)
    0 ~7 F. W/ P6 ^/ d0 ]# ]' a    src = to_tensor(src)1 g- z6 m7 T/ |
        # print(src.shape)  # torch.Size([3, 800, 600])5 C( ]3 x2 w6 y
        # channel: (R, G, B) / 255
    : F, q6 [4 Z3 H  Y0 X    h, w = src.shape[1], src.shape[2]
    . ]2 R* ]' N7 H8 Z3 n1 u
    1 W" U, p4 I0 b! m9 L    pha = torch.ones(h, w, 3)9 _0 R( I! ]# ?- b9 W4 n
    - B# ^3 X8 Q) f3 |, Y; }
        bg = torch.tensor([168,36,32]) / 255
    - Q+ R- I, y% _0 F6 b) u    target_bg = torch.tensor([19,122,171]) / 255
    , i- U4 R% G6 @+ K$ p5 U; x. r& u5 W* t! J% j
        # C, H, W -> H, W, C, e! t! _- a5 r4 c2 P0 c1 o5 R
        src = src.permute(1, 2, 0)( t; O* A7 o4 t6 C8 c$ v& i7 |+ S
        for i in range(h):* x$ t% F4 ?( w1 @
            for j in range(w):: a% H9 M% r& h# Y
                if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数' h  A9 E0 ?' R  l
                    pha[j] = torch.tensor([0.0, 0.0, 0.0])+ j3 J& c9 Q$ Q
    , H1 H. H$ o0 `
        # H, W, C -> C, H, W
    # C5 A! u$ Z+ E) o6 u' b  R    src = src.permute(2, 0, 1)0 E/ ~. r+ h; ~2 O# |
        pha = pha.permute(2, 0, 1)6 U/ X) d+ Z. D5 w
        com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)
    4 P: M9 i" V2 p4 _: u' [    to_pil_image(com).save(result_png)4 u' y$ V* a% I% H4 r
    4 }# {0 p& u  z% D: e5 P" d
    * E' l! z( P+ ]6 \6 [0 K* f
    if __name__ == '__main__':- H7 o# F4 M; K0 A. q" Y% n
        origin_png = 'origin_png/person.jpg'
    1 i, j/ R8 ?$ w0 d! e  {7 k5 N    result_png = 'result_png/com.png'
    % O9 X7 l" f) o. b' z0 y    start_time = time.time()) b: X1 G( r$ Z* s2 a+ v5 y
        change_red2blue(origin_png, result_png)$ t. L& f" _8 t. h$ i
        spend_time = round(time.time() - start_time, 2)
    " E% {# C: H7 [2 v2 ~    print('生成成功,共花了 {} 秒'.format(spend_time))" U+ |4 k3 x* |2 x$ W
    1
    & K1 y6 n1 ^/ Z+ U5 f8 e2
    / z1 a4 Z9 d- Q" w1 V8 r* Z3$ L) {6 r5 x% I) F  K
    4
    ; e1 {. K" x% w. Q! z/ C, J5
    0 V" R0 u! W' I8 f6
    " u$ z& K7 `; b' ~* F7& @) }! f' `8 o6 N6 G
    89 O- p9 e8 [' E: p: |% I
    9
    ! B, }! B2 e  r  V$ g$ Z8 X10
    1 z* K3 e+ K1 r1 ]  m5 @( `' a2 Q11" p, X/ b" c' c
    12
    ( m/ Y# z) a/ M8 o# p- z133 Q% g+ n  g* E% G  P4 \( f
    144 |+ ?: f( K- M8 Z. W% @+ l# c3 Q$ Q
    15
    * ?4 C- A" d- a8 ]+ j' w+ U, C7 k) ^16
    7 G+ c9 ^6 O) l& \8 I, k( d17
    : J6 ?# I. g4 c0 y# n- J18( m) y, s/ Z' F
    191 j& o2 D. ^2 ]/ o* A
    20
    5 t( F0 r! \. f0 Y21
    % D) {. x# p/ ^8 b9 |6 e22
    ; e' U3 O+ X. [$ `! v* e- j6 {23
    " V7 j5 @1 F& ]5 C24
    ) [( W; H9 `, y2 b257 _+ p+ I. U' A! y) k1 ~8 Z) ]
    26
    3 P& B7 O* _, d  S$ n3 g# m- [276 c/ j4 S% p  A9 g, y8 N7 L
    28
    ; L4 a; v# f7 B" b297 O, B  N0 {( ]# g7 {
    30
    $ Z7 X9 [' c$ _  p% j6 E31
    1 w5 [) ?, E  ]4 l7 s32
    8 }' C0 y+ L' F* ]% O. U! \337 o5 ~  S) l& h6 |
    34( _" x% Y9 ^. i! N9 f5 I  `) h
    35
    2 [" K0 y3 r6 n' ~* @# y& y36
    : D5 D. L5 R9 d9 [371 L' l7 ?- C( |" M
    385 t. a% W) ?- s3 H% g
    39
    : J! [. F' o- d" N4 L409 A! D9 S( R! |. q: L9 Z/ J
    41
    6 d3 w' b  K+ v1 K# O/ ]42( Y/ l/ m. x% e7 G9 G4 g/ ]# |
    43! N/ ?( }& L, S+ W, }/ m# p- v4 p
    44
      j* m& [5 E' E% T9 X$ X45) t( F* {9 R6 n6 K* d
    469 @; ]5 h9 _4 y0 ~7 z: B. d2 I
    该方法质量较好,但一张图片大概需要12秒。
    . K: w* X! o) |6 z, R( I: O
    ; E+ n- W7 }2 s, C- f8 E7 Z( V- B+ g4 l# O5 V

    ) ]) q0 [2 X9 ?# V  C3 m方法四: Background MattingV2
    9 n' f* @0 N6 w! I9 i( M5 S( jReal-Time High-Resolution Background Matting- p, `# @  S) Q2 X# p  J/ |
    CVPR 2021 oral
    $ E/ p& T4 l# ^9 b2 s! {
    6 }  x8 v5 O9 @: p论文:https://arxiv.org/abs/2012.07810
    7 e) s' H4 o; m6 |0 k代码:https://github.com/PeterL1n/BackgroundMattingV2& H4 n. \% `' H" F1 G, L% r- F
    " x4 n$ Q* X+ Z5 P" U
    github的readme.md有inference的colab链接,可以用那个跑& R/ t% r9 h! q4 Y5 q. I  g& _! K
    # z2 n3 F: ]5 i  W
    由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。
    / _: U0 ~9 D' v$ A' H; u# s
    % r# n) p  e' d. M& S( Y于是这里我需要生成一个背景图片。! Q2 y2 v# Q6 c/ \
    首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。% J+ E) g( x# x
    6 B1 z! b4 ?  s+ T- U. e
    然后生成一个背景图片。
    " x3 b7 ^: n8 x1 E% ]8 j% W9 T. M
    import cv2/ I+ b# Q* }. w7 w9 o
    import numpy as np% a) `6 `% V0 U8 a

    0 g8 B1 i0 j# Z) [3 L' g& ?0 K
    ! E& c5 T& b% @0 S8 k- b5 Yimage = cv2.imread("origin_png/person.jpg")
    2 ~* p8 F+ G1 I0 H: borigin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
    " J7 r: n- \$ F5 \" _origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    ' _' B; k6 t, a$ ?# Y& P$ gimage[:, :] = origin_bgr
    9 k2 V+ B  R" }& S1 D4 X6 H
    8 |! [* e! i  W& K8 T7 Ncv2.imwrite("mask/bg.png", image)9 w% m8 U- c3 Q9 a. O/ E9 u
    12 O  f/ m" @# ^5 q& j$ k
    2' x/ E- s- A1 h* L. c6 o; D
    31 p$ s* l- a% i8 h& S! J) i
    4# ]% g- K$ l8 Q- z
    5
    7 ]' K& x: L* k8 k' }! D6$ t7 |  I2 `- V3 R* v  U6 Y9 ]
    7
    , J  X: n& g% }! _! q/ n8
    % w6 N6 u: P- O) }8 W9
    ) l" |6 [: Y5 l  V' ]101 r5 [. r5 b% R4 Z" O* X3 D; |6 O
    ! f) Q' t: z1 Q1 p+ U6 l; F
    需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码
    - m8 f- I6 R& E6 C; g+ o6 w/ @- B! G$ ]$ q5 Y
    src = Image.open('src.png')) b$ [+ i( B, G0 ~. s
    bgr = Image.open('bgr.png')
    ! t5 L# x% T2 b+ \* G7 o+ r3 ?8 d, C1( V) ~' O& }$ e, U/ e) p
    2( @4 B1 Q% s. L) S, x* ?9 X4 T
    另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)+ h0 F' u; V6 Y7 j7 d4 C* X

    . `! h& U  b7 B; t  v/ B1 scom = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)+ d5 h% ]( v: j5 L1 @
    1
    ) ^+ Y/ G; n3 J6 t2 d, H3 E5 o
    - `; ?; F6 B- h) d: g那么加入我要换白底(255, 255, 255),就是
    & j% P7 U# m( V* L( k0 m1 X' D& P( U$ I6 [
    com = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)# ?. k' P" ~! b+ x0 G: B% @
    1+ U+ l: ?9 Y3 W1 L
    " Q" [; q! s0 @. X5 o" J4 Y
    假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是! V* x: s- |, w! H8 n, }
    ' l# C$ Z# s! D5 P0 p) A* B
    com = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)
    4 @9 E& p% \) r$ ^1 `. r  e3 |1
    8 I$ `+ T& i$ m总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.
    2 k/ j% c5 J& F9 E. C1 y  Z1 M9 Y; u0 H6 x5 Y5 l
    然后就输出图片了。可以看到效果相当好。不愧是oral。
    5 W3 P. `" q. z$ G# v2 g7 P3 F$ w& [5 H- H+ P
    . K5 p5 z/ W4 G: {: {
    原论文可以实现发丝级效果1 _! O. U9 r: [6 h& G, R+ g2 F
    ! a5 k9 @1 D3 o: J/ b5 g. W

    + E  J, c& c2 V! u& N) {
    + F( b/ B. @; n( q2 @8 C# T- p3 T+ t; k
    9 |/ o9 z/ Y6 Z+ _( m  n
    报错解决方案2 j. Q" T2 A, H% U8 _
    can’t divided by 4 / can’t divided by 16$ B4 O$ }9 U, O! @
    由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。
    3 e" k/ V. p1 S. m  L/ K$ t这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize/ U" s. A3 J. B- I
    ————————————————+ v9 F+ T  n% J( x5 g, Z1 i8 `
    版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    $ C4 y( a* n+ b: i8 Q7 J6 D& D; G+ x3 h原文链接:https://blog.csdn.net/weixin_43850253/article/details/126376767* F# `; M/ N3 D0 V4 M+ x6 \
    7 {- g1 }( |" W, M) f
    1 b; D1 K/ \5 b. F* J$ 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-6-16 18:03 , Processed in 0.507710 second(s), 51 queries .

    回顶部