首页 > 解决方案 > 如何将像素/numpy-array 转换为矢量点?

问题描述

我想将灰度图片的像素值转换为矢量点,以便像素的灰度值确定相应点的半径。但是我完全卡住了,这个项目必须在周日完成,我现在真的很绝望

背景:对于我的大学课程“python 简介”,我想用 python 构建一个“rasterbator”(https://rasterbator.net/)的无耻副本(但以更原始的方式)。

我该如何解决这个问题?: 我使用 PIL 加载图像,使其成为灰度图像并将其转换为 numpy 数组。然后我将数组分割成许多小正方形数组(每个预期点一个段),计算每个数组的平均值并将其重新组合到一个数组中,该数组现在比原始数组小得多。到那时,我能够做到(但我花了很长时间)。现在我想用点“替换”像素并创建几个 PDF,这样您就可以打印它,将它粘合在一起并制作一张大海报。

这种方法可行吗?还是我在叫错树?

我是一个该死的python初学者。python的问题是对我来说,有太多我不知道的模块。可能答案真的很简单,但我根本不知道在哪里看。如果有人能告诉我,如果我正朝着正确的方向前进或指向正确的方向,我将不胜感激。

提前谢谢了

这是我到目前为止管理的代码(虽然不多)

from PIL import Image as img
import numpy as np

greyscale = np.asarray(img.open("test.jpg").convert("L")) #load picture into array and make it greyscale

end_width = 1500 # chosen width of final picture in mm (will be with kwargs later on)
dot_size = 13 #chosen dot-size of final pictutre in mm (will be with kwargs later on)
estimate_dot_count_x = int(np.ceil(end_width/dot_size)) # estimates the "horizontal resolution"

pixel_in_segment = int(np.ceil(greyscale.shape[1]/estimate_dot_count_x)) #calculates the edge length of a segment
W=pixel_in_segment #just for shorter formular later on 

estimate_dot_count_y = int(np.ceil(greyscale.shape[0]/pixel_in_segment)) # estimates the "vertical resolution"
final_dot_count_x=int(np.ceil(greyscale.shape[1]/W)) #final horizontal resolution for shape of new array
final_dot_count_y=int(np.ceil(greyscale.shape[0]/W)) #final vertical resolution for shape of new array
#slice array into multiple pieces
tiles = [greyscale[x:x+W,y:y+W] for x in range(0,greyscale.shape[0],W) for y in range(0,greyscale.shape[1],W)]
#calculate mean values of each segment an safe it to list
average_list = []
for pixel in tiles:
    result=int(np.mean(pixel))
    average_list.append(result)
#convert list back into an array
downscale=np.asarray(average_list, dtype=int).reshape(final_dot_count_y,final_dot_count_x)

编辑: 不知何故,我设法将数组绘制到矢量点:

#inverse and normalize gray value so That I can multiply with max dot size
for ix,iy in np.ndindex(downscale.shape):
    downscale[ix,iy]= float(1-downscale[ix,iy]*(1/255))

reportlab 是我一直在寻找的关键...

from reportlab.lib.units import mm
from reportlab.pdfgen import canvas
#making dots
def printing(c):
    c.translate(spacing*0.5,imh-(spacing*0.5))
    for ix,iy in np.ndindex(downscale.shape):
       c.circle(iy*(spacing), ix*(-spacing), downscale[ix, iy]*max_dot_size, stroke=1, fill=1)
c = canvas.Canvas("hello.pdf", pagesize=(imwidth, imhight))
printing(c)
c.showPage()
c.save()

这就提出了一个问题:我如何告诉reportlab,我想以通用打印机格式(“letter”或“A4”)将这个大画布(尺寸为2m x1.5m)打印到多页上?

标签: arrayspython-3.ximagevector-graphicsreportlab

解决方案


而不是“将图像切成小方块并计算每个方块的平均值” ......如果你想要 80 个点通过 60 个点向下,只需像这样使用resize()

im_resized = im.resize((80, 60))

推荐阅读