QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2164|回复: 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将红底证件照转成蓝底
    ! o; x* B+ J$ i$ }! F前言
    8 I+ }: j  Z; c% `emmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。- I6 T& y# C, t

    ( T; R) T  j4 ?* S+ N
    ! c# ]9 v  F! ~
    1 l2 Q( I  X9 [' B8 D" I/ E+ Q2 K% O' A8 c: B" n* p
    方法一: lableme
    " {9 J6 W9 m9 r% o/ j9 {lableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.. H3 F/ g8 J5 T3 H- _4 X/ n7 m

    - U1 E9 q  ^- n# b' Z5 _  j# 代码来自 https://blog.csdn.net/hello_dear_you/article/details/120130155
    ' Y' L6 {8 P3 h" c1 |2 oimport json% E( W" I! V( ^9 E5 o) O' n3 Z( U
    import numpy as np
    5 H' V) w8 z1 ^9 G( v% r) T* yimport cv2
    % E' W7 {  V8 g9 R$ e# read json file; H: ~. l/ x4 k. C0 S: m( e+ Q1 u
    with open("origin_json/mypic.json", "r") as f:- q# q9 T, y1 x, v/ J& k* n
        data = f.read()" F% e1 B: W. Z0 W8 k1 H2 R8 w

    ) M: o( o2 @( Q) }; G$ S# convert str to json objs( C8 L& s6 i1 y. W; a% M
    data = json.loads(data), g0 g7 ]5 @- T3 y7 E2 `
    6 Z; m% T) _0 o8 {- `* c/ z
    # get the points
    0 Z/ Q, M4 \, E  y- \points = data["shapes"][0]["points"]
    - a$ `7 U5 N: Q! _points = np.array(points, dtype=np.int32)   # tips: points location must be int32
      ?# u2 M2 V: x; K- s+ s! ], _$ B- }4 ~8 |
    # read image to get shape& Q1 P7 n' k' ^: [0 x* n& T
    image = cv2.imread("origin_png/person.jpg")
    1 e4 k7 x  Z9 E% s9 y% Y% l7 o) U/ B" Q% Q
    # create a blank image
    - j. n! g' j4 c4 S" B3 K, W& gmask = np.zeros_like(image, dtype=np.uint8)8 t8 h6 g: w! D0 }. P

    & @8 n* L% |! }& u- c* a; H" H# I# fill the contour with 2550 x7 Z3 i" S- W$ ]5 t
    cv2.fillPoly(mask, [points], (255, 255, 255))7 k: v5 D- C4 J
    $ e1 {  Z5 S7 H  L7 f$ E. B
    # save the mask ! V9 Z1 g$ ^$ Y
    cv2.imwrite("mask/person_mask.png", mask)
    + R0 n9 M8 l$ j9 Z1
    4 b6 Y8 ^$ G- O% w0 t. l3 D2! c5 v) `* E, o7 {
    3
    , J; `7 H( d8 Z& v1 a9 x4/ ?4 ~  H% L' N- s1 \
    5
    % b. \; D8 q; y( O8 S* l& c64 [7 j7 `0 |! c5 m2 l. K
    7
    * V% ~+ S. K! \3 c" k: W: M" n80 N% A& d* b9 f. J) N* u
    9
    1 N* C& }4 z- F' @10
    % B; _6 D. q2 _1 P6 o+ H) t/ b  B11* e9 X( c! P3 A
    12
    5 q( N% z3 x' t$ q1 T( B13( j& K$ ?. }% K& ~, d  v7 p
    149 }% z- z/ g4 W/ v2 B8 E* Q
    15& j$ ^  V  B9 P9 d* ^# @
    167 b) X& v! C" z* T8 i
    17
    ! i0 c2 c. ]. F! d' W! [18
    6 T" w) e( z: n& S% E* U* x9 V2 X# ^9 s19  A0 Q( ]( c( T) a
    202 g' p) `$ \9 E9 r
    21; l* v3 z8 M7 o* L6 c
    22: ?' F  T) \3 b- u$ h, ^
    23
    , L( r+ v( o& _- m/ G9 w  r+ _3 o241 r' k0 t+ }( Q6 R$ w7 k
    25
    + H' P% R4 i/ \4 O& C26
    & m' X' ?5 j$ ?) d) O& a大概是这样:
    8 ]; T. s; }( k3 [" O
    3 l" P0 `% c  S5 k6 u
    9 G4 }( Q. ^/ Y然后利用这个mask生成图片; _0 b& ~: d1 j& y

    1 `$ k. C% n9 d: a( G; F; x# 参考自: https://www.jianshu.com/p/1961aa0c02ee; Y4 H1 S5 j; N- S% y
    import cv2
    9 S) D0 b6 @# zimport numpy as np* W8 u& h# t& J0 {! B) C- J9 Z8 S

    9 Z/ o" {6 o9 L2 f# d  }% D3 E; s% T7 H; Q& ^2 r
    origin_png = 'origin_png/person.jpg'$ {( t' |" o' G8 I" u2 p+ l. X# ~
    # maskPath = 'mask/person_mask.png'
    8 L5 E. m0 ?* s  T7 }' I- [" nmaskPath = 'mask/bmv2.png'
    8 m* p# e+ Y6 k: y, e" Fresult_png = 'result_png/result_png.png'+ e" H! w' O, R1 f% l0 L8 j

      x( s; {& o6 U, a4 B: Y
    1 B# F0 J6 z$ T: CmaskImg = cv2.imread(maskPath)1 O" o0 w- q% Q
    img = cv2.imread(origin_png)
    + o/ V9 X% S: F  y" ^assert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'" b# `; d% x, H* i( a7 h; o" O
    , ^* Q' }. I; c. @0 F/ d) X+ H" ?/ U
    h, w = img.shape[0], img.shape[1]9 s: y) e+ n, z7 Z: a
    print('图片宽度: {}, 高度: {}'.format(h, w))
    ) b& t5 R2 ^, n" |
    1 m( I. X2 z7 _+ \+ `# _* yrgb = (19,122,171)  Y8 l2 h3 S2 f0 j  E' n
    bgr = (rgb[2], rgb[1], rgb[0])9 U9 c/ [! h4 f% A
    # (B, G, R)
    . `8 l) _9 M- c8 }8 ]  [0 hfor i in range(h):, B/ ]! r$ p) y9 N; E! ~/ L
        for j in range(w):
    ; l  i  W! S3 L- T( f: j        if (maskImg[i, j] == 0).all():
    * T" {( U( c) X: a            img[i, j] = bgr
    ( X( I1 J: k4 L; Z! f: lcv2.imwrite(result_png, img), c9 z/ G# J% h1 w
    print('图片写入 {} 成功'.format(result_png))% W" ^# C( z7 p" Z2 q
    1
    ! {! r* }: G& d' ^2+ i" h7 c$ h$ W
    3
    - o: _% z2 j0 o  J0 U0 c4
    2 k/ Q, W: \0 _8 V8 l5
    ; @0 ~! H2 P; \* o2 P6
    , r1 {" K3 o  c9 d7( M3 r2 d$ Z0 d5 W) Z/ e
    84 x; }2 f$ H0 h- `
    98 C$ M. j$ f7 j7 Y
    108 u9 \& m8 Q1 D) p  _9 q
    11
    3 V) I2 [, L# Y" D7 R* m- _12
    6 I1 ~* ?) P4 J/ ~1 [7 Z139 v5 X6 t: C" G8 i- M6 n) d( o( P
    141 p1 |  U9 J5 Q  Q7 ^
    151 c' |& [1 v6 w! x
    16  _( u2 B) N5 |# _
    17
    ; ^+ J9 ~. U8 |4 o4 ?4 ^& L) }18. F/ ]0 C0 h" K, R7 ~  O# ?
    19
    , N. D& r6 I- H7 s6 C6 U/ M20
    3 l  A3 V1 P! d" U212 }7 P& j% [% m9 X
    22
    9 F8 S: f0 E7 D3 e: j23, E- L4 U3 l8 e4 n$ e/ O, r. b
    24
    5 M# I9 b: B7 i3 i$ {; y3 p25: b; |; x$ S1 f. F* V) x
    26
    : J- q2 r& x+ W6 h4 g4 f279 G: k1 S+ S0 P1 N4 y8 L$ F1 a
    由于人长得一般,就不放图了…
    9 P& r! k- G" L" ]* T7 x: D
    2 [( `7 Z+ E2 p- f+ h缺点:6 U6 W  {% x$ U& L# {4 i# h
    lableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。6 i5 O8 j! c8 `8 r: s. d' z) h1 `" N
    5 g8 h( e6 g& y( l
    . h. e. N! a' H# M$ f' t# m# A
    , I/ O# @' F' Z5 N6 ^) n6 E

    ( P( F8 }5 @. G0 ?( ~" W  p: v% P  v% u' q
    方法二: 阈值
    , [% e& I& H' ^3 d5 P该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。
    1 b' u7 q( x# z( z4 r' ?9 o8 s( V# C( r
    Opencv) ^0 Z( e8 A. Z5 E# |
    import cv2/ \% _+ R6 P5 ~& [' p
    import numpy as np
    ' V; @6 T* K1 `; N1 O; y, ?$ O7 Q0 S/ ?
    . W8 \* o4 B! Q9 {
    def mean_square_loss(a_np, b_np):
    * Q, W& v) {+ ~6 K    sl = np.square(a_np - b_np)
    ( i! _" w& x. d9 i    return np.mean(sl)
    ) M# a# a: t% A  C1 ]: Y6 U7 d+ |
    : R+ Y, C5 M7 }  I, r
    ) A2 k0 K+ ~; o8 v% ]1 gdef change_red2blue(origin_png, result_png):
    . ~) o) j! ^- c: f6 \4 P    img = cv2.imread(origin_png)
    . X1 ^" ?# l) r# |7 l, {  O% d' M5 t
      \2 {* r( l  h* [% H% K# }    h, w = img.shape[0], img.shape[1]2 s9 S3 Q% {. S" f; s
        print('图片宽度: {}, 高度: {}'.format(h, w))
    . X1 c4 \3 E* p$ U5 Q( E6 V8 x) m+ _4 _
        origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值1 b* @9 |. A' t/ g9 L
        origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    , y" k1 R" A, U+ A  R  L% |    target_rgb = (19,122,171) # 蓝底RBG9 Z0 A: M# u' {, h! V$ ~
        target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])
    ' G% ~+ j  A$ O5 t8 z4 F
    : r% _9 N6 ?, I    for i in range(h):
    7 I- B& i4 p. C$ E2 c+ L# }0 W1 q        for j in range(w):
    3 ]* Z, R) E4 x* Y" e! [& W6 Y            # (B, G, R)/ @# x' H7 T, [8 _
                if mean_square_loss(img[i, j], origin_bgr) < 50:+ b* i6 F) b! I6 [3 [
                    img[i, j] = target_bgr # k* t* t5 j0 O$ s5 d. H$ h2 Z
    . B; |- C7 Z4 z5 ~
        cv2.imwrite(result_png, img)0 p0 ]: h( \% @" S
        print('图片写入 {} 成功'.format(result_png))! X+ ]2 Y9 O4 q/ D

    " l- N7 l) R+ Z$ V: s' I
    1 s0 l% Z5 I- O/ S: Sif __name__ == '__main__':( _" `5 R- Z' ^- B' K% M" w
        # origin_png = 'result_png/result_png.png'2 O7 s# z: C4 `
        origin_png = 'origin_png/person.jpg'5 @1 @; X* |+ \" P, l) E: V6 V
        result_png = 'result_png/result_refine.png'
    ; M3 w! t% b- ]4 y2 }2 _1 x$ R( ?    change_red2blue(origin_png, result_png)& W$ U6 R0 {* ]
    1
    ( l5 U5 Z. Z4 j9 c& J! \) N2. o; J2 O: g2 W0 {4 Z
    35 W2 \1 n: D- i- ~- S9 v/ q. {
    46 i" d2 Z6 J: H
    5. }0 ~% g4 j; C" L
    6& {) B% ^4 E$ J# u
    7
    ! X" w' A5 D6 n7 z- m* U2 L5 e0 c8
    ; D7 I3 }1 t6 p, ?9
    * v# E5 U) M' l- ]5 [4 N2 ^& k, T- t10- k/ m. F* z; F8 q9 }
    11% z4 P# m! S* {6 [1 t$ E
    12
    3 `7 e$ ]: i5 c135 [4 W' N0 q( g7 m2 a4 Z
    14
    4 k/ `1 D8 r* a' X' X8 Q15
    - @! n0 z! e0 h, d) u. M3 N3 E16
    " K/ J% o+ F2 z17
    0 H1 \3 V7 Q  }9 f+ g18
      E2 k5 a: e5 |5 [! M! i19( w9 w, D- N, p3 t
    20; Y+ W- l* v( g2 s* a; k
    21
    2 @3 |2 l" J1 Z& y, `6 k22' [" R- z% e/ m; l* {
    232 j# o: j0 u$ Y+ \- \( D
    24
    2 N+ P3 S% E" t; ^25* P6 X8 H$ {9 x* U
    26
    8 T: S# c5 t; B, e27
    - W# L) y5 q, X: }280 s. M5 @( F3 H
    29: l7 p, h1 W. N( s7 u0 p' z. A- J* r
    30. u4 U6 k0 n( h3 s( x' J; T
    31
    2 d' M; F, P( }32
    5 L  j! Q6 O5 o( p0 M! V$ ]33
    8 x" I& C9 o4 m* O34
    6 o' b  A  N" ]6 ~35
    ! I# i  W$ ]) ~! j; F, I结果人与背景边缘仍会存在红色像素残留6 n! A" B; _- q5 M( U8 t

    6 x1 G9 X6 Q8 l, c  C8 D' R% A
      H2 e/ e$ w; s) t/ J( `
    + w/ k) F% S/ D$ ]) n8 |# {9 i2 l* |

    ) R0 m* x" h' a$ o4 M' P: ?PIL! @2 ]9 L) u" V5 b+ i: v0 e
    from torchvision.transforms.functional import to_tensor, to_pil_image
    ! R/ s$ ]5 w/ J; ^3 d. e: Xfrom PIL import Image3 O5 _! u4 x2 @
    import torch
    : {+ s9 \$ p7 j' U1 u  Qimport time/ p- G: j8 ~% W) B$ n6 `5 @, j

    * n- w9 n! b8 H4 D+ [3 F
    8 p$ f: U) v( z0 g2 o5 U+ Fdef mean_square_loss(a_ts, b_ts):- l3 M0 y$ d$ \) \4 u. b5 i
        # print(a_ts.shape)' |' ^+ l# Y+ Y* [: c  S2 V
        # print(b_ts)3 s( i$ F; ?* k; {* `8 ^: |
        sl = (a_ts - b_ts) ** 20 u( o4 X+ _+ u  R3 |8 p/ b8 S
        return sl.sum()# K( F% B+ g9 b! A3 [9 R0 l
    , |2 K3 t- S+ ^# g, R

    0 L. Y# n3 [4 Z! J6 k" ~def change_red2blue(origin_png, result_png):% V3 s( d) d0 J8 g
        src = Image.open(origin_png), s+ P. z( [7 C8 G0 K$ g2 H
        src = to_tensor(src)
    8 {) [, {/ g& g$ p    # print(src.shape)  # torch.Size([3, 800, 600])/ p6 W/ N4 q$ l5 G1 A
        # channel: (R, G, B) / 255
    ; i4 H! p) Y+ T% o, y    h, w = src.shape[1], src.shape[2]; s. r/ `$ ^7 n6 G0 C
    / E1 S8 I6 i+ U! I4 C3 B- J  x
        pha = torch.ones(h, w, 3)
    9 n4 u; O  y) K: C; M0 P3 I
    3 K/ a2 f! g  G  h% T    bg = torch.tensor([168,36,32]) / 2558 c- @1 a9 f8 D3 x; F; w
        target_bg = torch.tensor([19,122,171]) / 2554 V. m# c8 Z1 d( b, P( F/ a+ `! O

    ) e, w, Y: ~( z% p* z9 _, K    # C, H, W -> H, W, C0 M( i; E. w6 B$ s1 u
        src = src.permute(1, 2, 0)
    , x" j" J8 d4 j- j    for i in range(h):- l( C$ y0 e. ]7 d
            for j in range(w):; `, q5 t, H  Z; S5 C' F
                if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数
      U: D3 {1 ~: \                pha[j] = torch.tensor([0.0, 0.0, 0.0])
    4 V* V6 N4 {+ q. Z- R9 F
      d' o; `' }8 |1 j7 V    # H, W, C -> C, H, W
    % Y  b; i' e& F- C    src = src.permute(2, 0, 1)
    / i9 X8 b$ A. L1 [/ n! e; K    pha = pha.permute(2, 0, 1)* B% [7 d/ p4 Y2 h4 {8 s
        com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)3 \6 j/ Q5 _8 O* x5 ~# J) o
        to_pil_image(com).save(result_png)
    6 M& b6 o3 U2 ?- x) [: X5 b0 Y9 `! \- |
    1 {3 {9 a1 \3 @+ r2 m3 j6 q; F1 s/ J$ V
    if __name__ == '__main__':
    " p9 ?; D* Q* o( }2 B3 Z7 W    origin_png = 'origin_png/person.jpg'
    2 M2 f$ G- F# y; G! i$ U    result_png = 'result_png/com.png'
    & _' g& q: b  C& M9 ?    start_time = time.time()
    , M! E$ |& _  N1 A. b( q    change_red2blue(origin_png, result_png)8 i' v0 j& l9 u0 T% }; ]7 j
        spend_time = round(time.time() - start_time, 2)0 A, l" d* x1 Q
        print('生成成功,共花了 {} 秒'.format(spend_time))
    $ G4 f6 q1 Q. b2 c  R& ?0 g( p1
    + J  x- U+ X6 J5 a2 \% J2 V1 D2
    0 D# g, A' v! R) f. @& F3) h, ]) W3 ~( d  R. l, g
    4, f& W/ J1 D9 d4 f2 o7 _# o2 G
    5
    5 u+ s) f. w2 N4 c" j6 U8 k6
    - m+ M, b! r! R6 t0 N75 m  D) f7 {4 I* P
    89 k, ?& O. c, l
    9) r1 z" e: ?5 x4 ?
    108 U. s3 m2 [+ E, Z" t
    11" O; q; w+ p6 q9 y6 T; [2 X! q7 T
    12
    $ F* {  |* E) U1 @- o8 C6 j- V( L136 N+ M, f3 E) L+ h
    14$ K+ i# ~8 W5 Y/ L$ i0 S
    15" C2 |% P4 ^6 m9 a
    16$ ~$ `' @9 }8 N! l* e
    178 U5 {! k/ y' L* ?4 Y3 e! X' h4 M
    186 K3 d9 Q; j% ~  N0 z: u2 x( d
    19
    0 I9 A+ F; r5 O# y' s: n, r8 \20% Q! |+ `4 K" M! L2 e# ~' Y* p3 g
    210 Q+ I8 `5 @. W3 {% P# [
    22: {9 [. |$ b/ _" U2 b2 A
    23: P) L, U; e% M) w9 H
    24: w. v- T8 {3 |' L2 q% V$ m
    250 b2 z, d2 _$ H% s3 m
    26
    6 S2 J( y1 \+ H6 S27
    ( L. [2 Q0 P2 ?: b% M1 x28: m7 h$ Z+ N3 E& M5 E7 \( t
    295 a* f: h. Y. e! @1 g
    30
    " ]0 E% n) A" C31+ L: H& x* \5 ^/ G; y( F; m
    32
    8 t% x# \: o* \4 \# u33
    9 ?+ e# o* F0 o8 v  L, F34
    # S- R# ]/ ?, x, g* _# P8 f35
    # R  B& Z# B$ I+ L2 o$ Q360 g' V7 y& H! O; [1 s3 K, P) ]
    37
    ( }% f7 J( }9 ?4 Z38
    ; d8 {+ s' U  U6 X) F2 m$ Y, r5 W39
    7 e4 A- ^7 x/ o% n' H, W$ S* }40
    ; O! R5 X! @; `6 D: R9 ^41
    : k0 C3 m: ~; T42
    * b2 X( G. k# g# V3 g43
    & J# O/ i, G- F) z/ t* f7 ^, G44. d( ^! \  ?0 o6 X) j7 j/ K
    45
    / N1 E6 U) R' ~, E  \46
    . [, G# F0 b8 g该方法质量较好,但一张图片大概需要12秒。; A! C3 o- _8 l
    0 ~& p6 `/ x: J" Q3 v

    , d, n) ~% W/ R$ j! }6 A; s+ j: L8 R( u8 x% o) v
    方法四: Background MattingV2
    - a. c& M6 U& X0 L; h/ RReal-Time High-Resolution Background Matting+ a/ y4 I+ {6 s" z* Q( H
    CVPR 2021 oral# ]' `3 _! t5 e) U! P- Z
    ( `$ ?- Y! w) v3 T
    论文:https://arxiv.org/abs/2012.07810
    ! E) S* ~2 Q. F0 e" W3 B* P4 n9 }代码:https://github.com/PeterL1n/BackgroundMattingV2
    " U$ f' @+ x9 z6 G# B; C: Z0 u, i9 i5 ~
    github的readme.md有inference的colab链接,可以用那个跑$ c8 e0 F* I  Z3 R- n. Y# q  D- s
    $ n7 Z2 `2 W* [0 |& b. V% l' d; F- |
    由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。
    . ~- _1 ~0 j" v3 Y/ k+ Y7 z4 S' ?9 I( F8 o6 S
    于是这里我需要生成一个背景图片。
    ! y3 v' o) I/ S% u. W首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。. P# U4 d8 Q0 p, Y  p
    " N# K1 n$ L! ^$ A- `
    然后生成一个背景图片。) g# \2 M7 ?! l$ O5 _

    * b% }; g* h7 p. q8 {& m  Vimport cv2
    ( X5 A' e6 i/ k. Wimport numpy as np% H& ~) r+ a' _% K) v

    3 h8 K8 W# _8 M
    $ H6 c+ w  O% c7 pimage = cv2.imread("origin_png/person.jpg"); G: V& r, W" x/ F$ s% X8 p
    origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值& ?( ]( K8 P! P% o+ W$ I; Q
    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])- f: w- x8 q1 \5 [5 T0 n+ O4 J
    image[:, :] = origin_bgr
    ' U  t& a5 Y* ^
    4 S( D- J9 t; b. X2 y# G! ncv2.imwrite("mask/bg.png", image). Z# l0 [! o: P
    1- L) p- `1 K7 }
    2
      j5 g' @4 w! j) x$ o9 S3; c/ b8 M- N  w" w1 U
    4- T7 w% e* k0 J- x1 U  V
    5) T% @7 [) M( c1 T& A7 h
    6: X( M# M2 v6 x# g1 S& h* }
    7
    & @$ F6 ]) F* m86 D( J9 D3 u' Z) _+ Z
    9  q, r& L  m: ~/ B3 a
    10
    1 |  G1 l. ^: h/ {+ L% u1 ~
    - N1 Z* \' }3 h" l) @: D# r3 u' ?需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码; v7 @) g. C& ~' p; M4 W

    0 J9 n8 W# @9 v. f' Zsrc = Image.open('src.png')
      X+ _. o* _+ P! zbgr = Image.open('bgr.png')
    , |7 W5 g! ]  l$ k1
    & s/ R7 R/ d/ K( R2
    . i3 }$ f& {( A8 ?+ t  _7 b另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)  e1 q" k4 B% n3 I; X
    / A/ v/ i+ k/ o2 g1 m# h' B7 t% n) C
    com = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)
    + m/ n( D! ^: L% I' g% i: w1. {7 e" b* N1 K7 D3 K+ w% {
      r. R/ R, Z# D1 x
    那么加入我要换白底(255, 255, 255),就是
    ( p9 H; h8 |8 {6 f) V) x
    : F! Q; V( q3 y' O: Jcom = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1); }# ~, Q# o: s' T$ B
    1! a, [, u! A7 V

    0 i' O$ D5 }2 K' ]2 @假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是! ?4 d& \: ^6 F$ z

    6 U; G, x8 W- `4 i/ A0 Y% b, A" _com = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)
    5 D0 V+ q, |" \* O1- A9 h3 C8 Z* i% O( v1 _& z: W
    总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.
    & t# J; h9 Z/ t' [0 S
    : C+ b" k& `9 l. z" N% U5 k/ L然后就输出图片了。可以看到效果相当好。不愧是oral。
    5 Q& j# {! q" `' X* v
    6 m6 M+ F1 d3 b4 ^2 L4 ^
    : |! O6 U. a8 c! V原论文可以实现发丝级效果1 H5 p, J7 X7 ?9 Y# B# K; N

    2 j8 t9 F) C( l1 W5 H# u5 M
    3 u  ~4 y6 I& ^6 J; G8 e. b
    9 g0 Q% Q0 J' ~8 {: h7 W
    % F* ?/ i2 o2 U; a% \2 S; [- K
    . k0 r, S* k  u! Z1 X. N; w* e$ h报错解决方案' \+ I. x! T7 T5 I
    can’t divided by 4 / can’t divided by 16: H, v0 y% C0 r* n& H7 h# B, N' B
    由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。
    3 @/ T) B: [2 A这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize
      h' T$ d' W) e7 R5 _+ N' v6 G% I————————————————2 N$ \* S4 u  c2 P! e% _5 R
    版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    0 `) [. c! G# c' B  Q9 {1 h原文链接:https://blog.csdn.net/weixin_43850253/article/details/126376767% `3 R+ ]  h! P' Y3 o" k4 o
    ! a/ u8 x- Q$ O- ]# r" [
    ; k) ]# ~& T6 q/ L. t
    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-24 20:43 , Processed in 0.789936 second(s), 51 queries .

    回顶部