数学建模社区-数学中国
标题:
python将红底证件照转成蓝底
[打印本页]
作者:
杨利霞
时间:
2022-9-7 11:41
标题:
python将红底证件照转成蓝底
python将红底证件照转成蓝底
: h S) W# [: I6 p1 k& E, Q
前言
5 v6 U* X4 `; r# s* R5 ^9 L% L
emmm…快开学了,手头只有红底证件照,但是学院要求要蓝底,这可咋办呢。懒得下ps了。自己撸起来吧。
" d3 T: O5 K/ ]7 W4 y1 F) j
/ a" | u& {) [# h. b+ v2 {2 l
9 N) l* J6 C) }) m# r
( O9 f0 n7 L$ Y5 ] B
! U( V9 {/ M7 V6 n; w8 {% J7 _ }3 t
方法一: lableme
; d9 B0 @" S ~3 W
lableme标注完后。得到一个json文件,然后将这种json文件转成掩码图.
1 l- i/ r: E% Z# [
0 Z' L. u# q( \7 {$ ?
# 代码来自 https://blog.csdn.net/hello_dear_you/article/details/120130155
9 w$ D; t; r2 T: b4 l
import json
. d- h+ Z2 s' ~" G+ y( l1 T F
import numpy as np
3 D2 f7 v" _1 ?/ @" l2 C
import cv2
6 e& a; S! `# h8 X# n- {
# read json file
3 D; J( B: z% K: G b9 i' a4 j
with open("origin_json/mypic.json", "r") as f:
' w+ p4 V+ t J4 p
data = f.read()
# Y: O+ z4 G7 H) d) R, b `
4 z5 T; A, V4 f/ M5 i
# convert str to json objs
# C0 w$ y. z: S' w6 U* h7 s
data = json.loads(data)
$ s& B( X- D1 F. n$ }0 Q" A
7 {4 q$ {5 k( `" ?* S& s" n
# get the points
9 g1 B( d3 K& T& P' ]
points = data["shapes"][0]["points"]
* h( A9 }% ^2 i# n7 O
points = np.array(points, dtype=np.int32) # tips: points location must be int32
( {! q1 D. ^( t- i H
5 p% y$ y5 Y* s( Z
# read image to get shape
* g7 }0 @9 }8 G: }! s$ `& x, o
image = cv2.imread("origin_png/person.jpg")
0 O; t( m2 ^- w x) I
1 x) Y" U8 p: O _6 s5 ~
# create a blank image
3 M( L, @1 d- I
mask = np.zeros_like(image, dtype=np.uint8)
) ?2 X# [+ m7 B- h
9 `7 x+ ]9 } x" N: h/ {
# fill the contour with 255
9 Y1 Y V' @, @. u; o
cv2.fillPoly(mask, [points], (255, 255, 255))
& |3 L5 L7 \: J1 l" i
1 S( F1 ~0 H) F2 \
# save the mask
: {, J+ b, D/ n, Y) q) t' Y1 m
cv2.imwrite("mask/person_mask.png", mask)
2 U) S5 U+ x- a4 L- A- p
1
( f' [5 \6 i, l- P# p& k7 h8 g
2
& w- w# i8 K* h& T$ c
3
* ?' o' f! Z. B6 D) q" e
4
7 z+ I: t) v" N' k8 x$ `& ?2 B$ H
5
- o% Y. F( e2 ?, E) i$ ]6 k0 d
6
r" o1 l) }. `0 i& K
7
8 q& Q: M* }* b: g, g. p; p& {1 h! i1 a
8
% _9 y# x) {' }" Q+ m
9
# G! n3 _+ a( `2 W4 J( z
10
8 a. W6 O" M7 [. A! V
11
) c6 ]$ y+ D0 W" I) {& P5 T1 A# C
12
6 N9 J# c5 X2 C
13
& Q! J0 P s# `7 [" E
14
$ @3 e0 Y! |% I, L0 t7 w2 H- v
15
6 A9 [' X5 z2 H4 |: U( t
16
8 ?: C' T$ Y' `4 t8 z1 k
17
& ^4 o/ }" }1 f/ |; e1 a4 E
18
$ q6 n; ?6 X. Z; w9 H# u5 G8 u) P+ q
19
! V G5 f% A3 g$ Y4 f
20
3 a; r5 K; ^, I* m5 i
21
0 g8 a- O, C, B: S: K$ }
22
6 u! c2 d6 d# l4 p
23
$ n5 p# O M2 F9 K( ]+ ~3 Q/ g2 s6 u
24
3 {- t+ J$ i$ H5 H; I. ]
25
# i* k% M' U8 @- M% T
26
/ Z, i7 E; x! [% v0 l
大概是这样:
6 g2 ]$ P8 p+ ]! }: s b
3 y) G2 K6 T5 X* Y: w* c
: k }2 H; f" r4 e6 l' K- T2 _. i% e
然后利用这个mask生成图片
) w0 ?! m2 o+ u+ l
: V A! E6 C3 }$ w+ ~, d) S" l
# 参考自: https://www.jianshu.com/p/1961aa0c02ee
5 N2 Q; U, x9 d: P2 j
import cv2
3 l3 c; h" m {7 |
import numpy as np
$ I# S3 `7 h8 S( R2 z1 O! U
) ]: [5 P) I- H& S* Q8 H# A
8 {( {' @5 ]- b9 k0 d: l+ y
origin_png = 'origin_png/person.jpg'
1 A% f) z3 r) w! s
# maskPath = 'mask/person_mask.png'
3 a t% _0 k. N
maskPath = 'mask/bmv2.png'
+ s) L. N' j4 L/ ^
result_png = 'result_png/result_png.png'
% s7 i- {5 ]* f# m$ {; {
/ o' Z( B9 {4 z
0 X- S) R$ C' I( y$ f a$ b% b
maskImg = cv2.imread(maskPath)
2 W1 b' l$ a i0 I& {- B
img = cv2.imread(origin_png)
" h! _$ I. n3 f( f; Z% i* s f3 \! Z
assert maskImg.shape == img.shape, 'maskImg.shape != origin_png.shape'
% Q3 t3 U0 ?" e" X# @3 Z& f
6 B; m) e2 G( B/ ^
h, w = img.shape[0], img.shape[1]
' Z* F6 d0 l& t
print('图片宽度: {}, 高度: {}'.format(h, w))
% U3 }3 l$ L8 n9 L, e
% R0 g; j* `, k6 X+ ]
rgb = (19,122,171)
7 L; l- L- L* f2 X# e0 J5 F$ R
bgr = (rgb[2], rgb[1], rgb[0])
0 h2 G0 c/ g$ n
# (B, G, R)
/ |: i; w! S/ R0 i7 S4 L$ @* j
for i in range(h):
: Y% s- g; [ D p# G
for j in range(w):
! m9 \7 k+ O5 Z
if (maskImg[i, j] == 0).all():
) P8 B& Z: s+ Q& T' `/ |" T
img[i, j] = bgr
3 V/ U) a1 [# m
cv2.imwrite(result_png, img)
w' h+ Z' k9 p- L# P, R
print('图片写入 {} 成功'.format(result_png))
' [% D; I# m! j4 t$ ^* |
1
" \- c) a# i) {: l3 g
2
6 i, L7 ?, [. [+ \/ r
3
! r: ?8 W3 p: C& A6 |
4
5 i# u. E! e5 j! c* M0 a" b
5
9 B; R; L" i2 e" O7 P
6
! y' U [: H* a: k; |
7
) b- X- }" S: F1 u0 W9 X' [! F5 ]
8
9 X2 c3 s$ p0 G
9
1 s+ ]" Y) w _+ ^
10
( j3 T. M0 Y- o0 s7 N6 [* K& X+ a
11
2 K K2 w/ ^2 r8 s i8 i
12
7 n" P2 F" A) W$ H. Z( O! J
13
f; \! W, r, d1 A1 G
14
3 v$ |( f! x/ ?7 i
15
0 f% R- R; i( P- B, ?4 ~" l
16
2 S( { u& b" I7 ~8 g2 ]
17
$ V K1 U5 Y. N( A) f
18
4 M: z+ L( A7 x* L* B
19
4 S$ l1 W, U( m# [1 k8 }# [
20
8 U5 L# q" r' v- l
21
, s0 {) I/ K1 U. ] x3 Y
22
8 g/ u# N7 g# E0 o r* N1 [
23
: |2 A0 ~- S5 s/ d3 B
24
2 w* o7 c1 K3 O. q6 Q1 Z# ? e
25
. q% G- l' S% m2 F/ O
26
" ~9 A2 V" K% A+ R: u J1 e
27
% \% J8 B2 W3 q# Y' p% @& x9 r
由于人长得一般,就不放图了…
+ Q5 X. C* I+ y% y% [6 F) X. A
4 g- Z J, A$ m$ Y! I$ [
缺点:
' z! C1 q7 O0 k4 Z4 |, I
lableme标注时挺费力,并且难以避免人与背景边缘会有残留红色像素的情况。
% f/ w* M) x O" t% X# ~5 g2 J( u* \
$ e1 K: e- }9 U- b3 ^. }* k
& e$ @% H' @6 {/ ?
/ b# B6 f* z% a/ H- m ~
& R1 W' @5 p1 ~% \$ P
+ x, W( q8 K1 e4 d w. S4 g& r5 |
方法二: 阈值
4 Y+ d/ W8 k' r$ f1 ~/ e" |7 w
该方法通过比较像素的RGB与背景的RGB来区分是否为图像背景。
p5 `) \& } C; M, X% }
8 X5 Q1 e! A8 E0 `* w2 J
Opencv
/ r/ n/ T# @2 ~ J5 S Z
import cv2
9 K9 f. c: g3 {8 v0 \7 ^- u- l7 U% k
import numpy as np
- }; x Q4 }% I% A4 m3 @
$ f3 F- A* g% R5 d5 r% X
- n. f% @/ H1 t: ^4 s: K( q
def mean_square_loss(a_np, b_np):
- y& a; y$ ?, w" f' T7 l2 S9 R
sl = np.square(a_np - b_np)
0 R0 \3 L4 \: l( { F' D
return np.mean(sl)
_. o- X. |( ?2 T: H/ v# X6 M
9 y6 V/ p/ u1 z) j
- ]; Z5 V9 a; b2 v2 ~& k5 h' ]7 x
def change_red2blue(origin_png, result_png):
+ g' M# D5 X# J" N3 W2 t
img = cv2.imread(origin_png)
; |2 U) O) B1 y ] J; r* w
6 L9 {; X \* N: }! G4 Q
h, w = img.shape[0], img.shape[1]
; H7 j7 m, Q/ c6 X' m& D9 h
print('图片宽度: {}, 高度: {}'.format(h, w))
6 F' ]& I+ V- ~% M+ z: _) V" E
9 P( e2 g; d- l( g- |
origin_rgb = (168,36,32) # 可以用浏览器啥的控制台工具提取出背景的rgb值
" @- c* W1 M- E0 }/ U+ q
origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
2 p9 I: b" C: ?# G* f" Q, A+ v+ `. r
target_rgb = (19,122,171) # 蓝底RBG
; }6 {& x' W [( k: i) _- C) |3 O- S
target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0])
) F* q. f1 h( v c
) ~% {, `9 R4 J( {8 m u$ r* N
for i in range(h):
. Q2 Y. ? A; L- q" Z7 b/ d
for j in range(w):
! _$ Y8 B. d7 |& v
# (B, G, R)
- J& w$ j+ I' a {
if mean_square_loss(img[i, j], origin_bgr) < 50:
9 Q0 w/ X* X6 I" ?' i6 Z
img[i, j] = target_bgr
" ~& P& d* r$ x" \
8 ]3 Z+ b6 k% }) G; n1 h0 Q
cv2.imwrite(result_png, img)
# E& _1 F" w- }7 p* @- s' m
print('图片写入 {} 成功'.format(result_png))
' l' I. B% F: x B1 N! K, T, T* ]
( {" |2 i; y- U* C
. d! E3 m! h$ y8 B6 q- q( Q
if __name__ == '__main__':
9 i+ o$ t* z0 ]8 M: p! n
# origin_png = 'result_png/result_png.png'
# m3 c8 k% y' ~: G' K
origin_png = 'origin_png/person.jpg'
, L- k3 Y9 B, F- b* F
result_png = 'result_png/result_refine.png'
! A _8 Z3 l- C
change_red2blue(origin_png, result_png)
' R+ S5 d! i7 o5 D$ p, s
1
* j: a2 v# ?; s- ]4 \/ |6 o
2
9 v: Q$ e8 S9 E5 o7 y4 C/ N. N
3
0 ~- y* v' b8 x" W) o$ P
4
% a( f( b |: g/ o& ]; L6 l! N
5
}1 N) q4 z% n7 j0 q7 N
6
4 ]4 S7 `0 C% l
7
( ~: S( c: t7 L o: l* q
8
; Z+ g: u4 Q6 C* P# _* |% x2 o7 b, _3 o
9
) f( w8 m( [& q: w7 S( L. S
10
- K( O& K' n( Q
11
1 f7 k( v3 E s
12
, Y% w' d8 w" J0 r* l {
13
/ I7 P' u) t) J+ r X1 B
14
/ s. }7 X, V `5 T
15
4 E- Y" g8 d7 {# ]% P q
16
$ m$ U+ Q: X/ [' i+ i$ ?2 r
17
) H. o! w! Z# A) x* v; L1 U
18
4 w2 ?2 C8 U: q9 u% R
19
- ^' J/ C4 T& H9 q+ J! j7 b
20
1 p- [, Q$ A. U& w$ E. u, Z
21
- o" y' z2 D8 Q. _7 J- X
22
) T* u% E- O( k4 \+ V
23
. f6 E- h! s2 `: N" K3 P
24
' K o {3 K( y1 n5 Z! {) ]
25
$ ^2 o% K' s! v( o. J
26
. ~7 `2 [! q1 u/ _
27
- N- A0 `% ^0 ^% }
28
; V# v. b( j; e9 ~! \* A, g
29
9 l6 X, s' E% S9 `, P0 a
30
7 N- f2 |9 I6 s2 p: M5 |
31
5 G U" e+ I, @$ H2 H: D) u
32
' x5 c( P) r# |' d' H) `5 E
33
6 P5 a ?: r7 `, r: Y
34
# _" f3 r! n7 j4 d$ K; |
35
" ~4 I) a: m6 R1 P4 X. L
结果人与背景边缘仍会存在红色像素残留
8 ~& K0 \' ]$ Y1 M* t: Z7 {$ }/ d
1 |* B+ p- \6 |, s! `& V1 ]
3 Y; e1 E- b8 n' u3 I3 x
* R9 ]' {6 A e! W1 z
# B2 t( W8 ^- s4 q2 t; j
5 j) a- x# ~' U& o) M
PIL
+ X6 H5 q. R% C. X# J! B8 g
from torchvision.transforms.functional import to_tensor, to_pil_image
- y% g# O: t5 l
from PIL import Image
& f" O8 V/ O( _: o7 Y. I9 u$ |
import torch
0 _- N4 I; X; M% Y! C0 ^ [
import time
# T- L$ l7 F3 R; s+ d6 J
( a3 {- m7 u1 s# |' _
2 ^1 i. u y1 ?7 t5 d3 x8 | H, I
def mean_square_loss(a_ts, b_ts):
6 U9 i8 u, N( G6 u$ L% K
# print(a_ts.shape)
- N% e& f* e6 z( r# [: f5 x
# print(b_ts)
: w) Z0 N0 H8 ]+ j& J
sl = (a_ts - b_ts) ** 2
# B4 v3 A/ X! o, V
return sl.sum()
: l* T. _( j3 W: q- i# V+ q
9 {( I/ q* J# y4 r! y
" H7 L: B4 Y3 d3 o7 g0 F" x1 A
def change_red2blue(origin_png, result_png):
" G. k. m7 ?' m
src = Image.open(origin_png)
: b6 c% ^$ U3 Z+ k
src = to_tensor(src)
( z9 |( H0 V) b: u) c' V$ G
# print(src.shape) # torch.Size([3, 800, 600])
3 P) z, C1 l" l; d: I& u3 k, \9 i
# channel: (R, G, B) / 255
: D6 }) b% E. E# e" E1 h: x
h, w = src.shape[1], src.shape[2]
' | ?/ P! }& R( ~
$ W, [/ u% r; G( n
pha = torch.ones(h, w, 3)
5 F$ |* G+ F& I/ |; F
* g+ i5 X! S7 B/ r+ _& ]0 K* J
bg = torch.tensor([168,36,32]) / 255
2 q4 ?1 a6 a$ Q
target_bg = torch.tensor([19,122,171]) / 255
. z' `, B) Y* q; _& f9 B' k' U. @
0 @+ a4 L6 G: @- O" G& H2 i' _+ M
# C, H, W -> H, W, C
( H, b* b1 q; I' S9 I+ Q& @
src = src.permute(1, 2, 0)
5 H% @5 A$ U3 k1 ?, n+ H
for i in range(h):
+ u g1 D# A1 v- I9 c
for j in range(w):
9 Q% h' t. t/ ~5 X: D4 i9 x4 L7 C
if mean_square_loss(src
[j], bg) < 0.025: # 0.025是阈值,超参数
0 r" O! i0 w% g# e/ ]* u/ z2 j
pha
[j] = torch.tensor([0.0, 0.0, 0.0])
0 l' h# {& b1 }+ I
2 |$ j1 f# B) l- b O9 g
# H, W, C -> C, H, W
1 `* T. h: u$ V# T6 w3 q
src = src.permute(2, 0, 1)
6 Z( T7 O5 o# ?. Z- R- o
pha = pha.permute(2, 0, 1)
1 X8 Q. _3 {- ?; B* K. p
com = pha * src + (1 - pha) * target_bg.view(3, 1, 1)
$ k2 R2 D) X( n6 t, b
to_pil_image(com).save(result_png)
4 n( l, D' n6 L+ v7 A9 l( e
/ h4 o2 U' X' { Z9 q
% q) f# j2 t0 D. ]) a. E( Z q
if __name__ == '__main__':
3 g! Z: C! q) y; t$ @
origin_png = 'origin_png/person.jpg'
$ @; ~9 e. o2 N' ?' J$ ~: L6 T
result_png = 'result_png/com.png'
& G, Q9 m" V6 i
start_time = time.time()
6 L% K) B. o, Y! Q
change_red2blue(origin_png, result_png)
& k a* y) w- B8 B
spend_time = round(time.time() - start_time, 2)
+ k; V7 a- j) \0 y- ^7 U
print('生成成功,共花了 {} 秒'.format(spend_time))
" v0 q- R, g E" h7 v2 r8 w7 V4 R
1
4 @$ E7 Y. U7 l5 T
2
% n5 A. i4 N S
3
5 Z+ |- i: K9 e
4
, |7 N# R4 H$ L. N( e) @! [
5
7 {' I4 k' n8 H# N" V/ L6 c
6
+ g+ N# P7 @& x0 e7 r
7
4 K9 r* @4 a" o+ g/ q
8
$ l8 _) e ~( o. Q! x
9
; e4 |( s, z* X9 ~# w
10
* d' P$ s/ M8 H/ b. l8 ~
11
. A; l* z2 e# D( a$ d
12
- k: E9 b1 Q/ z7 c/ b9 e
13
- }, {% m/ h3 Y, w6 y
14
6 Z/ q: |" w) y N/ x# s1 N6 ]9 Z1 `
15
: o5 r+ d! W0 g1 J1 Z1 [3 y
16
) F4 l2 f" m$ S2 ^# x3 O$ B! C
17
7 x# a8 C t9 }
18
& {8 i+ Z; N3 a0 [6 E2 k
19
- p4 T" u! n. u: T, L1 P
20
. D- W0 b6 c/ e7 x* m+ @) i0 Y
21
4 u1 R# j$ z4 u; t' |3 I
22
* g% r, c. D. z% g4 P2 B* Z/ B
23
" u! k2 o7 V8 }( X+ D
24
* W; {5 F7 ^5 x/ [! V. P( ]
25
" q5 x: F7 ]: ~+ A5 Q8 ?
26
. J. F" G$ g6 e4 S) G
27
4 t* g7 u% z. q1 ]( f# R
28
- M% X8 \, ~+ P
29
3 _! ]" Q: A( |( {% v8 S
30
5 o% C; f! K1 M8 H( \. ]7 G
31
- J+ q, I% f `
32
1 ^8 f ~. S0 D
33
L3 j; v1 ^' k
34
1 G+ ]& {( |$ B7 ]# I: s5 ?" d
35
( t' e0 ]) r( } G# v/ R
36
; F/ U( ~9 |/ |9 w: S8 b
37
% g- l: Y G9 }; @1 p2 z
38
# o& j. U; b# X' B. h3 b
39
- J# ]# K2 E+ p& |
40
( `4 k% B, u& x& X2 f" s
41
( v; E6 X& I" g, j0 C- T; J" p
42
1 |. r5 z' d( n9 y3 m, h
43
3 E9 c; v3 z2 d
44
& T, Z- ~* O9 q+ q" A
45
; D4 h$ e: n! T; t* a* m
46
0 \: {1 Z* t/ O* Y. y9 s: p {4 f
该方法质量较好,但一张图片大概需要12秒。
2 s! e+ }* S& ?1 J
0 |9 H- A3 l4 ^8 S
3 y' h' d6 s! z- i. ~$ o, O
4 I3 q/ [& H i |5 |& f9 ^
方法四: Background MattingV2
+ Z+ }* o+ \, C
Real-Time High-Resolution Background Matting
- p4 y# T7 J* D: F5 g7 Z4 u, |# F: M6 k4 `
CVPR 2021 oral
8 q$ b5 V, M* O9 z6 v
3 H) m" ?- \3 j9 R2 k
论文:https://arxiv.org/abs/2012.07810
6 z" h& {# W1 W1 e0 y
代码:https://github.com/PeterL1n/BackgroundMattingV2
7 [! @# o' _1 k1 w, b7 R
$ ? a' w; i- L( ?- G* t6 T( l
github的readme.md有inference的colab链接,可以用那个跑
" ^% |9 x# ~) O" v: B) K! p
3 ]9 J3 e) k3 F. |
由于这篇论文是需要输入一张图片(例如有人存在的草地上)和背景图片的(如果草地啥的), 然后模型会把人抠出来。
7 B1 D' E( i+ @! ~
5 M# Y$ Z& s& ?) E$ i, u
于是这里我需要生成一个背景图片。
K1 k1 T! U! i# @
首先我先借助firefox的颜色拾取器(或者微信截图,或者一些在线工具,例如菜鸟工具),得到十六进制,再用在线转换工具转成rgb。
3 {/ { ]9 M( Z
- d, _' {# c+ j- V l; y, x
然后生成一个背景图片。
4 W! P6 L- k, b( O7 M3 o
& |, X7 [7 G7 S! T7 T7 K- d0 A( d
import cv2
, F" j8 G8 V G9 ^
import numpy as np
) z% L1 [' N' X; }9 C
* Q% S" E, {* o% P, ~
2 t% C! B2 I2 K& w1 w' i
image = cv2.imread("origin_png/person.jpg")
4 w- n+ M r: K# i; m
origin_rgb = (168,36,32) # 可以用浏览器啥的控制台工具提取出背景的rgb值
# J6 h8 u% F9 q1 T `3 Q8 g; {+ n9 Z
origin_bgr = (origin_rgb[2], origin_rgb[1], origin_rgb[0])
9 i& T+ F% l9 n4 h( ?* I- m) I
image[:, :] = origin_bgr
% q" {! ^" X6 w) P& R; g9 ?7 @3 y
2 _' _, i4 h$ \$ m* z4 r
cv2.imwrite("mask/bg.png", image)
) C( A; ]* ~5 ]6 l3 U
1
* o: Z( w2 L9 E/ d. S0 N" u( e/ h
2
/ d5 v: @4 M( M5 X
3
/ a6 {# A, K9 b! k2 h% Q
4
0 V J: o% Z" @8 c
5
4 X$ I3 R8 Y0 d: D9 e: O
6
0 K3 H3 i' Q7 S0 @: E$ I [
7
8 s0 o/ h& J* R( p! t
8
" d, W# q: ~( G. S* E
9
+ J4 |' k/ `+ F: O" h3 |
10
: M5 F8 q6 E; S+ \( o- ]7 `0 I. _
/ b" v7 h6 h+ G$ |! ~. N% \- W
需要上传人的照片和背景照片, 如果名字和路径不一样则需要修改一下代码
/ y/ Q% L' y8 ^7 G. C) `( i; j! z
: N/ |0 K1 ?/ v
src = Image.open('src.png')
; g- }' c7 g9 F2 w1 ~/ ?
bgr = Image.open('bgr.png')
i( s ^2 x' c
1
- `4 O) w' l# Z, K9 ]+ P
2
3 l0 u7 z1 F; B+ i9 a* p
另外原论文是边绿底,要变蓝底,白底,红底则可以修改RGB值,举个例子,原来是这样的(绿底, RGB120, 255, 155)
) J) k. c) E5 ]5 E
0 @1 Z! f) k) ~; n1 D! Y* h
com = pha * fgr + (1 - pha) * torch.tensor([120/255, 255/255, 155/255], device='cuda').view(1, 3, 1, 1)
( Y n6 Y) K1 W' ]# J& n
1
* F) A) Z2 i" S2 u, ^
2 T. c5 _7 E: G2 b# S: _' c
那么加入我要换白底(255, 255, 255),就是
% U" }1 m' E4 A5 Z* J4 c
( W9 F5 T3 x' O& \% g3 \
com = pha * fgr + (1 - pha) * torch.tensor([255/255, 255/255, 255/255], device='cuda').view(1, 3, 1, 1)
- G; j p* @/ q, e
1
" |+ w2 z+ X; L$ A7 q1 x4 m% o. K
0 r' `1 @! ^) s) `, _. Z, Z: i
假如像我换蓝底(19,122,171)具体深浅可以调节一下RGB,就是
9 C' R( P1 a: ?) m3 ]" p
# F4 _7 k$ y0 ]) ~! w4 C5 u
com = pha * fgr + (1 - pha) * torch.tensor([19/255, 122/255, 171/255], device='cuda').view(1, 3, 1, 1)
2 [7 r! e) b+ @
1
6 R" @2 @5 h8 M* U( `; J
总结: 其实这种方法从 任何颜色的照片 都可以 换成任何颜色的底。只要换下RGB.
, w& j: Y! [+ j' c, R. M
P' r/ W: V4 W9 Q! g
然后就输出图片了。可以看到效果相当好。不愧是oral。
3 Y! d C$ J6 ]8 r. c
, y4 U& W" e1 W* h& Z8 W; |
5 d5 S5 D) D; M }
原论文可以实现发丝级效果
J. F. p; K9 h. Q' t1 y
+ P1 w$ _# `. n0 @& h3 Y5 e1 y% {5 U
0 m7 o* l- k0 t! L: j" F
: m( [7 D! B# a: X4 s* ^( v1 X
# v7 _$ {9 {. @
& y E; n/ i n
报错解决方案
1 H' h1 L3 f: m$ C
can’t divided by 4 / can’t divided by 16
, [2 {- ^" T! C; u1 j4 d2 \
由于该骨干模型可能进行4倍或16倍下采样,因此如果您的证件照不是该倍数的话,有两种选择方案。一种是padding, 填充后再送入模型,然后出结果后再用clip函数裁剪。另一种方式是resize, 给resize到规定倍数的宽和高。
" Z7 H0 B4 `" b( `8 m& ]) Y5 Z
这两种方案需要的代码都可以从这篇博文找到: python图像填充与裁剪/resize
- E7 f. h( c! ]4 k
————————————————
* R) U6 Z1 L" h, B8 u
版权声明:本文为CSDN博主「Andy Dennis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
2 v& E: G: y8 b& f% ~/ L; _! s: z K
原文链接:https://blog.csdn.net/weixin_43850253/article/details/126376767
. t, p I+ o7 Y8 v& U/ m8 c% b+ i
d' V9 Y. N6 S6 h! q! F" X
# [0 m* T+ z) T/ a+ |6 [4 e
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5