QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2094|回复: 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将红底证件照转成蓝底, W) D9 ^) v" O% U6 [0 V
    前言$ e2 j7 g' {/ O) j1 W
    emmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。7 l5 U' U( E8 L! b
    4 s5 w/ _3 p# o' ^; e  U
    4 o& j6 h: u: W- A8 z

    ! @- ]) E) P: T3 h" T5 [- L9 {. ~, e' O1 I! a3 R3 p" L. F
    方法一: lableme* R4 s( [' a" p; f
    lableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.3 q! x4 V3 J4 q* w  R& X5 I
    5 J  x/ h/ F! P8 M& J
    # 代码来自 https://blog.csdn.net/hello_dear_you/article/details/1201301552 R- I6 T: C: G
    import json
    & Z$ Z  a' w7 Z9 himport numpy as np  ~3 y' W+ l- f" p  m
    import cv2/ p7 r# i# z* _2 Y) x  T" r2 v
    # read json file
    ) s( c6 U. M* Nwith open("origin_json/mypic.json", "r") as f:
    6 ^$ N- K; h) L! E    data = f.read()( h! y4 ^' |+ \! S  q* b, w8 G

    + I" m9 H2 o) Z6 G6 q# convert str to json objs6 S  Z  D4 Z' p! N1 |
    data = json.loads(data)- d# v3 ?' e& p- X0 {, T7 q: T2 n6 E
    1 ?8 R- H) O' \- c! C; J
    # get the points ) }& Z# m0 ]0 t: `) Q/ M" C
    points = data["shapes"][0]["points"]2 t. o/ g) v" j
    points = np.array(points, dtype=np.int32)   # tips: points location must be int32( V) B6 O7 r/ S* Z& R& Q% o

    * y& ]8 G' n, K. R: N" J, J( {# read image to get shape& _8 e1 T; Y- P2 e$ X
    image = cv2.imread("origin_png/person.jpg")
    7 l) i. ]# D" R6 Q& u7 P
      Y5 O! l; S% d! T2 E9 j) H# create a blank image
    2 d* |5 E. B+ v; \. q( s- x/ ~% x; Y; zmask = np.zeros_like(image, dtype=np.uint8)- _5 c3 M5 @" B
    ; F0 y" R, C! k1 @9 [. W2 Z8 t+ C" r
    # fill the contour with 255, @8 z2 T' g9 I/ Y( o1 K  J6 P% }5 D
    cv2.fillPoly(mask, [points], (255, 255, 255)), ]0 {7 i+ {2 M+ ^( i

    , X* v2 s& i  g6 {# save the mask
    * c. E+ h  t4 F/ g: x% `* O5 xcv2.imwrite("mask/person_mask.png", mask): o' }5 ?+ ?- B# i( T
    1
      ^- C2 b; e! j* d2 r2
    / }* A$ q7 R$ ~: d, u3; U, M8 H  y, S" P' o7 \+ y- D" Y
    4
    , q' I. T3 }7 L+ b9 c  S1 ]52 w& Q4 J/ `. `: e: ~1 Y
    6
    1 j1 @/ d6 _; O( L1 I7
    4 r" b; G+ q$ @+ U8
    ( m+ c6 C, f* _! @; H( b7 I9. d: p% K( k! n, o4 H
    10& C" A( D* ]% A) A
    11
    / f5 w6 P( J- Y: u12
      k- `8 N  T, H, @% F3 h13
    ; R6 u9 ^+ g, i* c& U14
    " g! L; c4 C4 v# r( u15( n& S4 @, b3 l: R1 X
    168 F' `1 q- ?( e* P; p
    17
    4 H8 Y6 x8 _! I" w18/ d/ A; {- W' W2 Y  L1 @/ w
    19
    ' f: P, g# ]; ^$ C* M- p# p20% R8 x# ~! [. O" j+ E, \- V
    21
    8 S" x' U0 |7 w# V% D. L4 g22
    1 [& h) V. {5 D* G5 \& B  S& {. g23
    " \% o) [0 N$ g5 @24
      f* |: S1 u" P: A25
    / \! `) [, i+ g4 ~26
    + R# V4 D& P/ H) Y大概是这样:
    # S" Q+ k' `% ^4 N* }# W. l3 `1 a9 K9 V! {1 S& d

    % n# g) z, O) b- ?* r% ?+ R9 r然后利用这个mask生成图片
    ' G/ x8 q7 [5 `9 c  B2 E5 i; P; u6 {& ]
    # 参考自: https://www.jianshu.com/p/1961aa0c02ee
    " p/ e5 i0 L! w6 \: S. fimport cv22 m" q  h& b" D) k1 |4 @  ^: S) A
    import numpy as np9 K2 I/ ]  O) W* Q7 }* g: `7 K

    " _1 u1 s3 ?  m, y& I+ Y
    ; v+ {+ [9 m# w1 t, m7 horigin_png = 'origin_png/person.jpg'( y1 Y5 L% H+ @& g
    # maskPath = 'mask/person_mask.png'! t) b8 U+ |& ^  |. l. P( |
    maskPath = 'mask/bmv2.png'
    $ S/ y. N( ^/ V* m6 e8 t" e/ J6 x  gresult_png = 'result_png/result_png.png'
    + `1 q% X( E/ A1 g; }- d# G& `+ t1 e' L6 i/ G; n$ `" x- n
    0 |7 d6 _% }- l* N
    maskImg = cv2.imread(maskPath)) ~% a3 i4 r, f2 Q8 i" P9 u
    img = cv2.imread(origin_png)
    ) m, A& ?" f9 s3 Z; B3 p8 H$ iassert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'# H* P' k) d# {1 W
    6 a& ]8 k# K# W$ f+ S1 K& ~
    h, w = img.shape[0], img.shape[1]+ v& W% _  ~# [4 w5 ^4 H
    print('图片宽度: {}, 高度: {}'.format(h, w))* r& a, d  e( E  X% P# |' R
    8 i( O, \# d& ?
    rgb = (19,122,171)
    * L+ |7 {7 l0 b. H# y) @: G& \bgr = (rgb[2], rgb[1], rgb[0])9 M- Y2 R1 Y- m# b/ S: b9 Y
    # (B, G, R)
    - H9 `. Z( m! U: g5 Ifor i in range(h):( H, C- G! m8 d) Q: r5 ?/ _* _
        for j in range(w):4 p/ A3 n( O9 j- r. G& k( ], i6 i
            if (maskImg[i, j] == 0).all():' N# b( |; S) l; w
                img[i, j] = bgr
    1 V+ b. v& Z. Q5 Z4 c# u0 Ncv2.imwrite(result_png, img)# j! ?. b& W! Q
    print('图片写入 {} 成功'.format(result_png))* `1 m  k# {# t4 Q7 A( {
    1
    # r3 Y) v5 m7 B; Q+ q1 q21 y7 H( t& d# O/ O, z
    3
    $ C8 H& f1 r& W9 v5 ^4
    . A7 A# q$ a5 M8 t55 p) |; u  Q# _' ?* J
    61 R8 m( t1 J6 \' g. u2 B3 M) `' Y
    7
    ! c, J1 x# n, F; q# Y86 u- K& T, I. v, F" g0 T0 V' q; b
    9& E" I2 b& W# Z' T( O1 P1 T5 c$ @
    105 o( F. \$ Q) C( X2 P+ X% ?
    11
    ( S7 Y, C1 u: N" J% J& S  z) D12
    4 x- X8 Q2 Z! J* F13
    7 t, M& _5 y' \6 b; s& ^1 d14
    , o3 e4 M1 `9 q/ e- K! S) _15
    * \! S! H3 E! E% O1 }16
    + |& q/ `" ?" f2 W6 N' @- Q' ]1 x( J17
    ! b) h7 @" B; H3 y3 ^18
    - \$ d/ _' j9 C5 m19) g" s1 Z" F6 c) L+ O, O3 I
    20' X) r9 g7 k2 M1 @8 K
    21
    % W0 ?( ?# j" c/ D. A22
    $ M3 p# x# a2 C" X1 p" y  J234 _) W* p6 {+ u+ H0 L
    249 r& [# a4 G3 w* {- v( Q; n1 c
    25
    " g) c, H. K& [! u3 ]26- {0 ?7 [4 w7 U2 D. \
    27
    8 }6 ]8 ]! O  C. x( ^$ G/ M* S由于人长得一般,就不放图了…
    ; X! a7 t7 _* l; V( e2 y- W& _5 @4 i6 t+ A+ t+ f+ g
    缺点:
    : |6 }# @% ?* P" wlableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。# k) d7 w5 r$ ^, a; y

    0 z4 i/ T! j7 R  y
    9 P  `, m) ^1 }
    0 q" w* g- w6 N* e8 E6 [' {! f2 q' S! f0 q
    7 N' V6 n4 m  ^
    方法二: 阈值
    ' h( c, z' h7 G该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。; ]! b& }$ D: w% F

    " y6 |, `9 [+ y; `/ vOpencv
    1 f# c+ j5 k, J" b! M# _( fimport cv2
    7 s+ Y$ W' w6 O' Timport numpy as np
    - w. ^1 p* B9 l4 r- X9 @6 C
    $ L6 P: ~. G. n0 ^; S$ r$ H9 V! g. l; l) g. i# M
    def mean_square_loss(a_np, b_np):
    0 O. o4 n! o; E. f    sl = np.square(a_np - b_np)
      k7 \( z5 j; s    return np.mean(sl)
    * r3 o/ b  F# Y$ o7 T6 F- X, z9 X! F% A: {4 K
    " U' M. @! O6 ]7 ~, q6 p2 \
    def change_red2blue(origin_png, result_png):4 z$ Q6 e9 Q( b- L3 `7 r0 r5 h
        img = cv2.imread(origin_png)& W+ ?, D! q/ F% ?

    0 v- F& g! x' |! ~; r    h, w = img.shape[0], img.shape[1]3 ]& I& r8 k+ u6 |8 N# W
        print('图片宽度: {}, 高度: {}'.format(h, w)); M% G% l1 y8 |& F( O' [
    1 D: [4 _+ S3 D/ e/ v
        origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
      O( ]/ F9 i: B    origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
    7 i! s' D* Y+ ]* ~0 ~3 a1 W' s( U    target_rgb = (19,122,171) # 蓝底RBG
    : k2 h# \& U& v) C/ L    target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0]): E- |* U. ]% y* V8 ?! t. P8 t

    $ u4 M& q/ @/ f# U( {* Z* i    for i in range(h):
    % k: D- N5 W. Q2 @& v; a        for j in range(w):
    2 `3 r* h7 x" z            # (B, G, R)
    * l$ x" }% F. u  ?            if mean_square_loss(img[i, j], origin_bgr) < 50:! D) b. }9 ^0 _
                    img[i, j] = target_bgr
    4 k$ A( U' v  R7 j9 p; D6 o: H" x  m3 \. J1 F  q
        cv2.imwrite(result_png, img)4 e8 w) n+ k, K" |4 L* d% _
        print('图片写入 {} 成功'.format(result_png))' }# i+ ~: \" U! ]; X; y7 b
    : C1 D( y* l0 z( e% c9 T

    . [0 J" q( k  `! aif __name__ == '__main__':5 Q7 Y: E7 D$ Q3 y- V& |
        # origin_png = 'result_png/result_png.png'
    7 j: d8 J: I6 d8 h. c/ x& o    origin_png = 'origin_png/person.jpg'$ v2 b) Z8 n7 U% Z
        result_png = 'result_png/result_refine.png'
    % F5 S3 u9 w/ N- a, R    change_red2blue(origin_png, result_png)7 P- ^6 i* N7 X' A' c- r
    1& h1 ]; f  |  w$ _: a
    2! n  C9 s9 C& ?) n) w5 w* b; j
    3
    3 O; u& K/ p  ~/ }4) o& _' P1 c0 ]  q5 m2 h
    5
    : L: o" [4 q+ H) V. C3 E* a& ]6+ \0 h1 v; N2 ~: ?" j+ {7 r- C
    72 e' L3 V) i8 ~/ k
    87 W8 F" P6 ?9 d, d( @7 j
    9" e* p: o6 g  Y. K! K
    10$ l4 g# N) Q1 F
    11# a9 I; F# l" J/ {2 u2 F: J; z
    12
    " O  G4 J6 ], F13( S; V# z0 T6 r- E2 v4 M3 y
    146 i0 P7 w0 d2 X. N( Q5 e5 v7 _! ~
    15) N6 [# ~8 O( n5 L7 A* S( N
    167 t6 A/ y! ?. }
    17# i9 \: R) Z* ~6 |2 O  L) q/ X& Z
    18
    6 h; \$ ]" e4 i0 q% l191 [7 ^( P: x! ~/ w6 s
    20$ z5 H/ o2 Q6 S
    216 v# U0 m- m& ~. z
    224 E5 N4 e" c: O) A1 f/ F
    23
    - X5 F% g- E% J24
    6 d4 n9 F9 r2 H25
    ! G; A4 b3 O& A  i; Y  E& q/ Q26
    3 A$ r( \- O5 c$ }& _) p. o27
    + r& R3 W, Z. M28
    ! Z" [" {2 [3 Y& q/ t29- F; d$ D$ e1 W# i
    30$ f2 _  Y) x7 {. d/ T
    310 q8 r2 k4 A2 N# n+ X# l
    32
    . r0 z' X9 H4 r  i$ H& o33
    * b0 V! `& `  o2 @" x; p* t. V; l6 \348 s" }8 Y/ i4 o9 T4 R; C
    35
    6 P+ n! H+ P+ }* @% g结果人与背景边缘仍会存在红色像素残留  u" ?9 `) p! n8 A
    4 y: R3 ]- {7 [
    + I- p) k) o7 z4 N7 [7 Q4 Y9 ]& Z
    0 c: B# O. i. C; b

    # Y1 _% z$ U- W: d( y: G# Z* [9 P3 y: R, }, z7 \# w- D, Z. L0 l) @
    PIL
    , f! [( B* ]2 R! c! z1 Kfrom torchvision.transforms.functional import to_tensor, to_pil_image
    , U- W% i8 |) @) F3 h) ]from PIL import Image5 ]2 V3 V2 x9 Y3 n; Q5 Q
    import torch. M4 e* x* x! O. S& _% U
    import time7 B4 w5 `# E( [& l

    ; g, g/ {: `! a% f0 W( k4 c% o# v( s* M5 d* e9 p% `& |
    def mean_square_loss(a_ts, b_ts):* A1 U" F7 r  E/ v$ G- l. I' [0 i
        # print(a_ts.shape)
      j8 J  p) T  K, t" m% Q, s    # print(b_ts)
    4 d+ r; L5 K1 S6 y3 x+ J    sl = (a_ts - b_ts) ** 26 p. h4 f4 M: c% Y/ x! Q
        return sl.sum()+ d' S# i+ |" f# V, \$ f7 R

    ' O8 j5 B( D: y3 @( j$ ^4 x* |  |
    - q, V: g! P8 j8 P0 r3 ~def change_red2blue(origin_png, result_png):
    / v8 U7 u) k" {2 U. M* D, s    src = Image.open(origin_png)
    & x3 Q  M* B0 b    src = to_tensor(src)4 R# `  D. t% d0 l1 I3 i
        # print(src.shape)  # torch.Size([3, 800, 600])! p" }1 m. V9 _- V
        # channel: (R, G, B) / 255
    0 E/ {& \9 i4 A/ m& L    h, w = src.shape[1], src.shape[2]
    * n% r' G( G( {+ D( g3 T( Q5 S. L4 l' K2 d
        pha = torch.ones(h, w, 3)2 t" j  z4 V4 q
    - v( [" R9 a) Q  @' A
        bg = torch.tensor([168,36,32]) / 255( S2 S2 o% g" K7 c
        target_bg = torch.tensor([19,122,171]) / 255
    8 i& S  f+ v: ]3 N3 L) T4 W
    $ Y& B! q7 h+ Z$ v2 f6 h    # C, H, W -> H, W, C1 s/ f, Y: H* V8 D/ S
        src = src.permute(1, 2, 0)
    8 F: M% k3 g0 D* X' @6 k1 P2 m    for i in range(h):
    5 `+ w5 y! {+ U, |# {) h        for j in range(w):& x! t# t1 r( R1 U( `( }
                if mean_square_loss(src[j], bg) < 0.025: # 0.025是阈值,超参数
    & j9 P% X& O* }8 Q6 X                pha[j] = torch.tensor([0.0, 0.0, 0.0])
    ) y! @  ]& P& q; q7 B; P8 W* K2 o" F" @. F1 f
        # H, W, C -> C, H, W& Z: O& I, w3 v+ ~# v
        src = src.permute(2, 0, 1), X! {1 u4 U- H3 f% f
        pha = pha.permute(2, 0, 1)1 P/ X5 j' e5 L+ i7 ^4 F. m
        com = pha * src + (1 - pha) * target_bg.view(3, 1, 1); s1 Y. n. S- h7 P6 y3 L& ]
        to_pil_image(com).save(result_png)
    : U3 |2 D' H% T* f; x+ z* a' O2 m& h. e  H

    ; \  J3 x. |" W% {$ D! ~$ Jif __name__ == '__main__':4 z" G) A0 O! d- C  `4 J! t# ]
        origin_png = 'origin_png/person.jpg'% A8 A+ R( D0 q
        result_png = 'result_png/com.png'& `- u  @$ o5 `/ Z4 x! o
        start_time = time.time()
    7 @' a8 t* n- W. ?1 R+ j; k6 a    change_red2blue(origin_png, result_png)/ V0 ?8 d! [5 R: ^7 p& u, z
        spend_time = round(time.time() - start_time, 2)4 Z" C4 f, c9 }0 c. A, x+ |% C
        print('生成成功,共花了 {} 秒'.format(spend_time))
    $ g5 L$ y& M9 n5 x8 o1- j( y* J1 X  \
    2
    ; r- t8 [) a* R" Y- c, F5 }3
    ; w4 u5 z; X" G4
    ( s  w; L5 W# f) C1 t4 u* Z  l5
    $ P$ v/ U# @2 T+ b6: K2 e4 e: p1 S. r8 ]6 {
    7
    3 F" r. q7 m3 T: B8 u8" j; S7 u9 C$ e+ `7 v
    9! S/ C, E. E# O$ h" e
    10
    7 e. b' s6 }; |0 d3 M11
    & k: b+ [+ I/ _  f8 W7 X7 V12
    % l2 G5 U$ T2 r$ w7 k7 z2 v134 Q0 O9 j9 `: J2 T, f0 |' ?# c
    14
    ! _8 }  U! y/ H) ], R15
    ! H7 G0 _+ Y" h# F2 l3 M# g164 m: ^) H( i3 _4 N) T; S" D
    17
    & F2 N# J/ p( m" G9 V+ ]9 _% i# i18. F# ^6 Z  M4 [) ]6 v9 o
    19
    * ~% S4 ^- y7 m4 O2 I20
    ; h: @7 [+ p( P" h4 j% E/ j21: F) W. f  k! ^; |, U
    22" G0 ?. h- J( j. X
    23$ F  s' h, ?# L. k! c- b0 G$ C. f; ?
    24
    8 G/ N, T+ i6 A$ U+ Q& i" r25
    ) [% J$ S9 U9 A3 F, q26+ `+ F/ n, b# S1 L$ y0 [" ^8 }9 f2 r
    27
    2 y- A6 p+ d- ~2 n7 K8 [5 B- Z2 i289 s! c* E  R+ r# e
    297 H0 s" C4 V4 e( B) L( U
    30
    " P9 h: Q! O& d8 R3 X31
    " P- p& [" D4 V4 B32
    % W# D& R1 Z$ Q# X& [7 F7 K. i333 A: o2 F. d3 c9 ]! h1 W1 d
    34
    % X" P+ O, e+ a350 {! ~  \* N& G( ?$ r+ t
    36
      X" s$ J5 ~/ M4 u. V  \377 L4 x  U" ~; `# R
    38" j( o/ h$ l* l0 |  L: K
    39
    * H" L% |, i3 u# L8 c0 |40
    1 K8 e' d- u4 ]3 F- x) |41  j3 ~, O& Q0 s, F) i% P
    42
    9 w! z! U& U" `; J% a43) C6 T* p/ y' }9 g- K7 b3 j
    44) M- r# D. U. S) m7 \' n
    45" }$ d: R  R! o% }- V: c9 F
    46
    ; n, E" f1 a2 D  Y该方法质量较好,但一张图片大概需要12秒。- F6 E- ^  M8 v/ L& M, t4 h  J

    ) F9 D) Y( C: b# M( h7 [; x( e0 Y7 Z2 F: V
    . H% k2 o! O% G
    方法四: Background MattingV2
    , Q" G2 h: V: S- wReal-Time High-Resolution Background Matting
    & |" i; l' t& E3 ?0 _) VCVPR 2021 oral
    " o2 o7 l& |: {0 b, f/ g% j3 V- G3 E$ n2 z' h- g
    论文:https://arxiv.org/abs/2012.07810- o- N8 E  q% \7 f2 |7 n' z1 M2 w
    代码:https://github.com/PeterL1n/BackgroundMattingV20 o* X/ W/ }0 n7 [
    7 j0 c. e5 ^1 t/ f4 x+ n2 b! {
    github的readme.md有inference的colab链接,可以用那个跑
    / p9 |/ _8 H% Q7 ]: F
    / b1 x% {3 a9 j( r" u- P由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。" K. g$ L! s& d% B

    ! b/ P2 @+ A1 `" `( W  i于是这里我需要生成一个背景图片。
    , u$ F; ^$ M* ~3 |首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。
    - Z2 l2 z8 D' V0 F9 Q8 c2 I9 b
    2 j+ i' Q) Z3 W7 N' {然后生成一个背景图片。# }* E- r  S  i( e
    0 w3 c0 K0 Y6 O+ I
    import cv23 T9 B# b2 @4 R. h" {! j0 r) Q9 Y  T
    import numpy as np2 l5 o$ a6 ]- m2 C# i' t7 l% q8 o
    4 _7 m& e& m/ s) Y% y5 ?5 S

    2 h7 J9 E& k+ e8 pimage = cv2.imread("origin_png/person.jpg")
    , N; K8 i. i" ~! ^4 ~origin_rgb = (168,36,32)  # 可以用浏览器啥的控制台工具提取出背景的rgb值
    # p# P4 ^7 X" W& x5 N  \/ [origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])2 R/ j6 K+ Z: c( @, m
    image[:, :] = origin_bgr
    ! I. H$ o0 D* z* }+ ?, _
    0 s# Z4 @6 N& M4 S) V( e$ k; E/ z4 Hcv2.imwrite("mask/bg.png", image). T$ @" x6 Z4 D! B1 ~, m( D
    1: Y0 f+ Y* }- R* v& O
    2
    $ e" U* @* }$ c3 b- Y9 V3
    6 K) x1 ^2 ~2 v. m& D4
    : |4 }; H( x& b7 ]6 m: I5
    ; x0 X+ {2 n) D0 _& F/ Q" d( D6* ^: P: g' y2 a. Y( i' ^
    7
    " {" u) d3 c" B1 I0 e7 F1 J84 P$ A# Z5 F" X1 r% f
    9
    6 }, N4 u, q0 g7 n# K8 R# Y* d10( V6 o( h  l" J
    5 y4 `% \3 G! s8 G
    需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码
    3 {& i3 F% Z/ F; J8 r# q0 K
    3 M+ L! A% A# N% z8 t. j( asrc = Image.open('src.png')
    # p5 ?; M9 \3 ]8 p- R$ A' I, nbgr = Image.open('bgr.png')
    4 s& p9 n* l* W5 e9 ]  K2 V" ?8 X1; b& ^) \9 b  f3 w
    22 W2 X' n7 x) b# g# s+ I
    另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)0 I6 G' ?, E3 @; y$ T  E

    ! |) x* E" X" l3 b# T" \com = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)
    : M0 y- t: O* t& }0 U2 Y1
    * Z9 H% M4 i: _3 d3 U7 y0 |: e
    & g, }6 c# p+ ?! l0 X% K3 J( O那么加入我要换白底(255, 255, 255),就是
    & _4 d; P( H( e6 ~3 v6 i. E$ f4 }! s5 Y& e& O; H' t
    com = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)/ ~4 @$ l3 E& G& V) f* x
    17 c+ A' r: }* b& \- i
    2 R/ b2 @  Y3 V: w$ _
    假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是
    % x+ p- D9 I" D. S& C, I4 Q* o2 i% v! \& M& j4 ~* k
    com = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)
    " D( Q9 l" p1 A0 S0 E15 H) ?  }; s6 K1 M; t0 h( n
    总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.% x, n; U9 h9 ~/ `5 Z3 V
    : Q1 `! X1 v; m# B# D
    然后就输出图片了。可以看到效果相当好。不愧是oral。
    & o# N/ ^. ^' c% T0 C
    2 ]! M+ x  @9 V0 ~3 i' A& `  ~9 c# M( A5 a% \& I$ Q
    原论文可以实现发丝级效果
    7 W7 U$ v4 f' [  x/ s$ \1 w: |6 Q9 A* Z" N6 [  N
      q1 ^% b/ L1 B
    5 ]* \; L! s5 V7 N3 c. R: J- _! _# O
    - C  Z5 \9 q0 V
    9 V7 ~3 j# ?8 c' @
    报错解决方案% h9 |" k' k. R) j& n6 T
    can’t divided by 4 / can’t divided by 16
    * l6 Q) T. B7 F, D由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。
    " X& K% E7 W9 g3 N这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize
    ' T3 U* M6 N' N* C9 T+ y1 P3 M————————————————
    : x" W2 F/ s. U( f' D# A版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。7 ]: T, B0 x" m5 V$ N" T+ i" b
    原文链接:https://blog.csdn.net/weixin_43850253/article/details/126376767' |1 x& z! y5 a+ R2 R
    3 Q8 i3 {2 I. o1 u5 F! ^# A! k; [' J
    ( R9 c0 A+ N3 _
    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-16 14:31 , Processed in 0.529908 second(s), 51 queries .

    回顶部