QImage: есть ли ленивый метод копирования? - PullRequest
2 голосов
/ 05 июня 2011

Я пытался использовать QImage для загрузки изображения и проверки равенства с подизображением шаблона, которое перемещается по всему изображению. Код такой:

for i in range(image.height() - backgroundMask.height() + 1):
        for j in range(image.width() - backgroundMask.width() + 1):
            subsection = image.copy(j, i, j + backgroundMask.width() - 1, i + backgroundMask.height() - 1)
            if subsection == backgroundMask:
                print 'equality action here'
            else:
                print 'non-equality action here'

Проблема в том, что для этого требуется слишком много времени. Подобная операция с использованием Python Imaging Library была слишком быстрой. Двумя основными операциями являются copy () и operator == (). Я думаю, что основное время тратится на copy (), поскольку он выполняет копирование только там. Если бы это была просто ленивая операция копирования при записи, то это было бы быстрее.

Есть ли способ сделать это быстрее?

1 Ответ

0 голосов
/ 05 июня 2011

Более быстрый способ сделать это - сравнить пиксели вручную - копии, которые вы делаете, расточительны. Предположим, вы хотите найти backgroundMask как образ «image». Вы начинаете в верхнем левом углу. Теперь вы обнаружите, что пиксель (0, 0) изображения не соответствует (0, 0) backgroundMask. Если вы сравниваете пиксели вручную, вы просто переходите к (0, 1) изображения и сравниваете его с (0, 0) и так далее. Но в вашем случае вы уже потратили впустую годы, копируя ширину x высоту пикселей уже.

start = time.time()
for i in xrange(image.height() - backgroundMask.height() + 1):
    for j in xrange(image.width() - backgroundMask.width() + 1):
        success = True
        for y in xrange(backgroundMask.height()):
            for x in xrange(backgroundMask.width()):
                if image.pixel(j + x, i + y) != backgroundMask.pixel(x, y):
                    success = False
                    break
            if not success:
                break

        if success:
            print 'match'
        else:
            print 'no match'

По общему признанию, доступ к пикселям медленен в Python, а оператор равенства написан на C. Но он все еще значительно быстрее, чем вы опубликовали. Для изображения, которое я попробовал, ваш код занял 27 секунд, а мой - 0,8.

Однако лучшим решением, вероятно, является преобразование QImage в образ PIL, если эта функция там реализована. Преобразование между изображениями QImages и PIL простое и хорошо документированное.

...