如何用Matplotlib/OpenCV-Python生成深度学习用随机闭合曲线灰度图?
用Matplotlib和OpenCV生成透光液滴灰度图方案
一、Matplotlib实现完全可行
Matplotlib可以轻松实现你需要的所有特征,步骤如下:
- 灰色背景:初始化画布时直接指定背景色,或者生成图像后填充灰度值。
- 生成嵌套闭合曲线:基于你提供的随机偏差轮廓,通过缩放原曲线得到3个不同大小的嵌套闭合轮廓(比如分别乘以1.2、1.0、0.8的缩放系数)。
- 填充纯色:对每个轮廓填充不同灰度的纯色,对应亮晕、液滴主体、阴影/聚焦光区域。
- 添加模糊效果:将Matplotlib绘制的图像转为numpy数组后,用
scipy.ndimage.gaussian_filter实现模糊。 - 细节调整:
- 亮晕:最外层轮廓填充浅灰色(如
#dddddd),模糊后形成扩散的亮边。 - 深色阴影:在液滴一侧裁剪部分轮廓,填充深灰色(如
#333333),模糊后模拟阴影。 - 聚焦光:在液滴另一侧绘制窄条高亮区域(如
#ffffff),模糊后模拟透光聚焦效果。
- 亮晕:最外层轮廓填充浅灰色(如
Matplotlib示例代码
import numpy as np import matplotlib.pyplot as plt from scipy.ndimage import gaussian_filter # 生成随机偏差的液滴轮廓 H = 10 rho = np.random.rand(H)*np.logspace(-0.5,-2.5,H) phi = np.random.rand(H)* 2*np.pi t = np.linspace(0,2*np.pi,101) r = np.ones(len(t)) for h in range(H): r = r + rho[h]*np.sin(h*t+phi[h]) x = r * np.cos(t) y = r * np.sin(t) # 生成3个嵌套轮廓(缩放原曲线) x_halo, y_halo = x * 1.2, y * 1.2 # 亮晕轮廓 x_core, y_core = x * 1.0, y * 1.0 # 液滴主体轮廓 x_shadow, y_shadow = x * 0.9, y * 0.9 # 阴影区域基础轮廓 # 创建画布,设置灰色背景 fig, ax = plt.subplots(figsize=(5,5), facecolor='#888888') ax.set_xlim(-1.5, 1.5) ax.set_ylim(-1.5, 1.5) ax.axis('off') # 绘制亮晕(浅灰填充+后续模糊) ax.fill(x_halo, y_halo, color='#dddddd') # 绘制液滴主体(中灰填充) ax.fill(x_core, y_core, color='#777777') # 绘制深色阴影:裁剪轮廓的左侧部分 mask = x_shadow < 0 ax.fill(x_shadow[mask], y_shadow[mask], color='#333333') # 绘制聚焦光:右侧窄条高亮区域 mask_light = (x_core > 0.7) & (np.abs(y_core) < 0.3) ax.fill(x_core[mask_light], y_core[mask_light], color='#ffffff') # 将图像转为numpy数组并添加模糊 fig.canvas.draw() img = np.array(fig.canvas.renderer.buffer_rgba())[:,:,0] # 取灰度通道 img_blur = gaussian_filter(img, sigma=2) # 显示结果 plt.figure(figsize=(5,5)) plt.imshow(img_blur, cmap='gray') plt.axis('off') plt.show()
二、OpenCV同样可以实现
OpenCV支持通过坐标点集定义轮廓,结合其绘图、填充和模糊函数,完全满足需求:
- 定义轮廓:将你生成的x,y坐标转换为OpenCV兼容的整数点集(注意OpenCV原点在左上角,需做坐标平移和翻转)。
- 灰色背景:创建固定大小的灰度数组,填充灰色值(如128)。
- 填充闭合曲线:用
cv2.fillPoly填充不同轮廓为指定灰度值。 - 模糊效果:使用
cv2.GaussianBlur对图像做模糊处理。 - 细节调整:
- 亮晕:外层轮廓填充浅灰(如220),模糊后形成扩散效果。
- 深色阴影:生成液滴一侧的局部轮廓,填充深灰(如50),模糊后模拟阴影。
- 聚焦光:在液滴另一侧绘制窄条高亮区域(如255),模糊后模拟透光聚焦。
OpenCV示例代码
import numpy as np import cv2 # 生成随机偏差的液滴轮廓 H = 10 rho = np.random.rand(H)*np.logspace(-0.5,-2.5,H) phi = np.random.rand(H)* 2*np.pi t = np.linspace(0,2*np.pi,101) r = np.ones(len(t)) for h in range(H): r = r + rho[h]*np.sin(h*t+phi[h]) x = r * np.cos(t) y = r * np.sin(t) # 图像尺寸与坐标转换(OpenCV原点在左上角) img_size = 500 scale = 150 # 缩放系数,适配图像尺寸 offset = img_size // 2 # 坐标偏移,将轮廓移到图像中心 # 转换为OpenCV的轮廓格式(整数点集) def convert_to_contour(x, y): pts = np.column_stack((x*scale + offset, -y*scale + offset)).astype(np.int32) return pts.reshape((-1,1,2)) contour_halo = convert_to_contour(x*1.2, y*1.2) contour_core = convert_to_contour(x*1.0, y*1.0) contour_shadow = convert_to_contour(x*0.9, y*0.9) # 创建灰色背景图像 img = np.full((img_size, img_size), 128, dtype=np.uint8) # 填充亮晕(浅灰) cv2.fillPoly(img, [contour_halo], 220) # 填充液滴主体(中灰) cv2.fillPoly(img, [contour_core], 100) # 填充深色阴影:裁剪左侧轮廓 mask_shadow = contour_shadow[:,:,0] < offset contour_shadow_cropped = contour_shadow[mask_shadow].reshape((-1,1,2)) cv2.fillPoly(img, [contour_shadow_cropped], 50) # 绘制聚焦光:右侧窄条高亮区域 mask_light = (contour_core[:,:,0] > offset + 100) & (np.abs(contour_core[:,:,1] - offset) < 45) contour_light = contour_core[mask_light].reshape((-1,1,2)) cv2.fillPoly(img, [contour_light], 255) # 添加模糊效果 img_blur = cv2.GaussianBlur(img, (11,11), 2) # 显示结果 cv2.imshow('Droplet', img_blur) cv2.waitKey(0) cv2.destroyAllWindows()
内容的提问来源于stack exchange,提问作者Mr. Who
相关产品推荐
相关产品推荐

