上半部分方程為:
f
(
x
)
=
2
?
x
2
?
x
2
f(x)=\sqrt{2 \cdot \sqrt{x^{2}}-x^{2}}
f(x)=2?x2??x2?
下半部分方程為:
g
(
x
)
=
?
2.14
?
2
?
∣
x
∣
g(x)=-2.14 \cdot \sqrt{\sqrt{2}-\sqrt{|x|}}
g(x)=?2.14?2??∣x∣??
import math
from matplotlib import pyplot as plt
import numpy as np
x = np.linspace(-2,2,1000)
fx = np.sqrt(2*np.abs(x)-x**2)
gx =-2.14*np.sqrt(np.sqrt(2)-np.sqrt(np.abs(x)))
plt.plot(x, fx, color="r", label="upper")
plt.plot(x, gx, color="b", label="down")
plt.legend();
如何將其偏移到正數(shù)范圍呢?我采用下面的方式:
import math
from matplotlib import pyplot as plt
import numpy as np
x = np.linspace(-2,2,2000)
fx = np.sqrt(2*np.abs(x)-x**2)
gx =-2.14*np.sqrt(np.sqrt(2)-np.sqrt(np.abs(x)))
x =(x+2)*7.5
fx =(fx+2.5)*7.5
gx =(gx+2.5)*7.5
plt.plot(x, fx, color="r", label="upper")
plt.plot(x, gx, color="b", label="down")
plt.legend();
同時有上下兩個函數(shù)方程時,畫實心愛心也很簡單:
plt.fill_between(x, gx, fx, color="r");
接下來我們?nèi)サ糨S,并保存圖片,就可以直接用PIL讀取了。
產(chǎn)生愛心圖像并保存到文件中:
import math
from PIL import Image
from matplotlib import pyplot as plt
import numpy as np
x = np.linspace(-2,2,100)
fx = np.sqrt(2*np.abs(x)-x**2)
gx =-2.14*np.sqrt(np.sqrt(2)-np.sqrt(np.abs(x)))
fx =(fx+2.5)*7
gx =(gx+2.5)*7
fig = plt.figure()
plt.axis("off")
plt.fill_between(x, gx, fx, color="black")
fig.savefig("t.jpg");
讀取圖片并轉(zhuǎn)換為黑白圖像:
im = Image.open("t.jpg").convert("1")
im
現(xiàn)在需要去除多余的空白,對于這種黑白圖像,我直接使用numpy去除邊界上的空白,。
首先轉(zhuǎn)換為numpy數(shù)組:
data = ~np.array(im)
print("去除前:")
display(Image.fromarray(data))
ys, xs = np.where(data)
data = data[min(ys):max(ys)+1, min(xs):max(xs)+1]
print("去除后:")
display(Image.fromarray(data))
💕繪制愛心照片墻💘
有了上的愛心蒙版就可以很簡單的繪制出照片墻了,。
為了減少最后的渲染量,將愛心圖片縮放一下:
im = Image.fromarray(data).resize((60,40), Image.ANTIALIAS)
data = np.array(im)
h, w = data.shape
print(f"共需{data.sum()}張圖片,寬{w}張,高{h}張")
共需1504張圖片,寬60張,高40張
然后開始繪制:
import os
defcreate_picture_wall(data, imgs, size=50):
h, w = data.shape
random_imgs =iter(np.random.choice(imgs, size=data.sum()))
new_img = Image.new('RGB',(size * w, size * h),"white")for y, x inzip(*np.where(data)):
img_name =next(random_imgs)
src_img = Image.open(f'{img_path}/{img_name}')
src_img = src_img.resize((size, size), Image.ANTIALIAS)# 將圖片復(fù)制到 new_image
new_img.paste(src_img,(x * size, y * size))return new_img
img_path =r"C:\Users\ASUS\Nox_share\ImageShare\avatar"
create_picture_wall(data, os.listdir(img_path))
import requests
from io import BytesIO
url ="https://staticc./static/2020-11-01/6d2e4f9d31d1b7201e23198869de2f9a_preview.png"
r = requests.get(url)
im = Image.open(BytesIO(r.content))
im.size
(190, 200)
圖片過大,轉(zhuǎn)換為bool數(shù)組,并縮放一下:
data = np.array(im)>0
data = np.array(Image.fromarray(data).resize((48,50), Image.ANTIALIAS))
display(Image.fromarray(data))
然后就可以生成大拇指的照片墻了:
將以上代碼封裝一下:
from PIL import Image
import requests
from io import BytesIO
import os
defget_mask_data(im, size=50):
width, height = im.size
if width > height:
height = height*size//width
width = size
else:
width = width*size//height
height = size
im = im.resize((width, height), Image.ANTIALIAS)return np.array(im)>0defcreate_picture_wall(data, img_path, size=50):
h, w = data.shape
imgs = os.listdir(img_path)
random_imgs =iter(np.random.choice(imgs, size=data.sum()))
new_img = Image.new('RGB',(size * w, size * h),"white")for y, x inzip(*np.where(data)):
img_name =next(random_imgs)
src_img = Image.open(f'{img_path}/{img_name}')
src_img = src_img.resize((size, size), Image.ANTIALIAS)
new_img.paste(src_img,(x * size, y * size))return new_img
defdownload_img(url):
r = requests.get(url)return Image.open(BytesIO(r.content))
測試一下:
url ="https://staticc./static/2020-11-03/f18f814d52768eb29111c0be52b14ca2_preview.png"
im = download_img(url)
data = get_mask_data(im)
create_picture_wall(data,r"C:\Users\ASUS\Nox_share\ImageShare\avatar")