我正在研究一个 python 脚本,它使用 MagickWand 绑定库将 DXF 文件从 AutoCAD 转换为高分辨率的双层 TIFF 文件。该脚本完全按预期工作,但我正在寻找提高性能的方法。
这是脚本:
import dxfgrabber
import cv2
import numpy as np
import sys
from wand.image import Image
RESOLUTION_DPI = 1000
def drawPolyLines(pl):
if(pl.is_closed):
points = []
for pt in pl.points:
points += [[xToPix(pt[0]),yToPix(pt[1])]]
points = np.array(points,np.int32)
cv2.fillPoly(canvas,[points],0,cv2.LINE_8)
dxf = dxfgrabber.readfile("812b.dxf")
shapes = dxf.entities.get_entities()
in_limMin = dxf.header['$LIMMIN']
in_limMax = dxf.header['$LIMMAX']
pix_limMin = tuple([int(z * RESOLUTION_DPI) for z in in_limMin])
pix_limMax = tuple([int(z * RESOLUTION_DPI) for z in in_limMax])
#Translate x,y values to pixels
def xToPix(coord):
return int((coord*RESOLUTION_DPI))
def yToPix(coord, ymax=pix_limMax[1]):
return int(ymax - (coord*RESOLUTION_DPI))
canvas = np.zeros((pix_limMax[1],pix_limMax[0]), np.uint8)
canvas.fill(1)
for shape in shapes:
if shape.dxftype == 'POLYLINE':
drawPolyLines(shape)
with Image.from_array(canvas) as img:
img.resolution = RESOLUTION_DPI
img.compression='rle'
img.type='bilevel'
img.depth = 1
img.save(filename='result.tif')
转换一个文件大约需要 30 秒,我正在寻求改进。按累积时间排序的 cProfile 显示以下内容:
$ python -m cProfile -s 'cumtime' test.py
324966 function calls (322147 primitive calls) in 37.550 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
488/1 0.001 0.000 37.557 37.557 {built-in method builtins.exec}
1 0.000 0.000 37.557 37.557 test.py:1(<module>)
3 0.000 0.000 31.180 10.393 image.py:1013(wrapped)
1 30.500 30.500 30.500 30.500 image.py:2451(type)
1 4.329 4.329 4.329 4.329 image.py:9251(save)
1 1.485 1.485 1.487 1.487 image.py:8754(from_array)
1 0.681 0.681 0.681 0.681 image.py:1629(depth)
16 0.001 0.000 0.446 0.028 __init__.py:1(<module>)
208/5 0.002 0.000 0.229 0.046 <frozen importlib._bootstrap>:986(_find_and_load)
207/5 0.001 0.000 0.228 0.046 <frozen importlib._bootstrap>:956(_find_and_load_unlocked)
197/6 0.001 0.000 0.225 0.038 <frozen importlib._bootstrap>:650(_load_unlocked)
160/6 0.000 0.000 0.225 0.037 <frozen importlib._bootstrap_external>:777(exec_module)
290/6 0.000 0.000 0.221 0.037 <frozen importlib._bootstrap>:211(_call_with_frames_removed)
330/3 0.001 0.000 0.179 0.060 {built-in method builtins.__import__}
198/23 0.000 0.000 0.173 0.008 <frozen importlib._bootstrap>:1017(_handle_fromlist)
197/58 0.000 0.000 0.161 0.003 <frozen importlib._bootstrap>:549(module_from_spec)
22/3 0.000 0.000 0.159 0.053 <frozen importlib._bootstrap_external>:1099(create_module)
22/3 0.029 0.001 0.159 0.053 {built-in method _imp.create_dynamic}
1 0.000 0.000 0.158 0.158 __init__.py:41(readfile)
1 0.000 0.000 0.158 0.158 __init__.py:52(readfile_as_asc)
1 0.000 0.000 0.116 0.116 __init__.py:61(_read_encoded_file)
1 0.110 0.110 0.110 0.110 {method 'fill' of 'numpy.ndarray' objects}
如您所见,几乎整个运行时间都花在了将图像类型设置为双层的结果调用中。SetImageType()
当从内部调用该方法时,我已经深入研究了 MagickWand 源代码并发现了一个死胡同MagickImage.MagickSetImageType()
。我想知道是否存在将每个像素转换为单个位值的阈值操作。这可能很耗时,并且在这种情况下毫无意义,因为矩阵的值只有 0 或 1。不幸的是,opencv 绘制方法需要 8 位整数类型,我不知道是否有另一种数据类型可以输入 MagickWand将提高性能。寻找任何建议以加快此操作。谢谢。