0

我正在研究一个 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将提高性能。寻找任何建议以加快此操作。谢谢。

4

0 回答 0