除了暴力匹配二进制图像之外,还有其他选择吗?

问题描述 投票:0回答:1

这个 opencv/numpy 代码可以工作,但是慢了 1000 倍。基本上我有一个白色方块,和另一个稍微旋转和平移的图像。该代码通过暴力尝试 10 度和 10 像素内的所有角度和平移来恢复姿势。

我尝试查找单应性,但结果很糟糕。这段代码得到了完美的结果,但速度太慢了。我需要它在使用 python 的情况下运行速度提高 100 到 1000 倍。

我想知道如何大幅加快此代码的速度,或者使用另一种方法来恢复图像旋转 5 度并平移约 5,7 像素的事实

import cv2
import numpy as np
import random
import math
import time

# Create a 240x224 black image (image01) with a 64-pixel black margin
image01 = np.zeros((224, 240), dtype=np.uint8)
image01[64:160, 64:176] = 255  # Add a white square within the margin

# Copy image01 to image02
image02 = image01.copy()

# Rotate image02 by 5 degrees and translate it 5 pixels up and 7 pixels left
rows, cols = image02.shape
M = cv2.getRotationMatrix2D((cols / 2, rows / 2), 5, 1)
M[0, 2] -= 7
M[1, 2] -= 5
image02 = cv2.warpAffine(image02, M, (cols, rows))

# Create scaled-down copies of image01 and image02
scaling_factor = 1/1
img1 = cv2.resize(image01, None, fx=scaling_factor, fy=scaling_factor)
img2s = cv2.resize(image02, None, fx=scaling_factor, fy=scaling_factor)

# Define parameters for the search
rotation_range = range(-10, 11, 1)
translation_range = range(-10, 11)

# Create a list to store the results
results = []

start = time.time()

for rotation_angle in rotation_range:
    # Rotate img2
    img2 = img2s.copy()
    M_rotation = cv2.getRotationMatrix2D((img2.shape[1] / 2, img2.shape[0] / 2), rotation_angle, 1)
    
    img2_rotated = cv2.warpAffine(img2, M_rotation, (img2.shape[1], img2.shape[0]))

    for dx in translation_range:
        for dy in translation_range:
            # Translate img2_rotated
            M_translation = np.float32([[1, 0, dx], [0, 1, dy]])
            img2_transformed = cv2.warpAffine(img2_rotated, M_translation, (img2.shape[1], img2.shape[0]))

            diff = cv2.absdiff(img1, img2_transformed)
            non_zero_pixels = np.sum(diff[diff == 255])
            
            
            results.append((rotation_angle, (dx, dy), non_zero_pixels))

print(time.time() - start)
# Sort the results based on the number of non-zero pixels
sorted_results = sorted(results, key=lambda x: x[2])

# Show the top 10 results
for i, (rotation_angle, (dx, dy), non_zero_pixels) in enumerate(sorted_results[:10], 1):
    dx = dx/scaling_factor
    dy = dy/scaling_factor
    print(f"Top {i} - Rotation: {rotation_angle}°, Translation: ({dx}, {dy}), Non-zero pixels: {non_zero_pixels}")

实际图像看起来与此类似(随机斑点)

python numpy optimization gpu homography
1个回答
0
投票

我有点着急,所以我发布了查找 x,y 偏移量的代码:

def get_coords(array, locs):
    return np.array([array[i] for i in locs])

def find_center(img):
    ys, xs = np.nonzero(img)
    corner_indices = [np.argmin(xs),np.argmax(xs),np.argmin(ys),np.argmax(ys)]
    corner_xs = get_coords(xs,corner_indices)
    corner_ys = get_coords(ys,corner_indices)
    return np.array((corner_xs[:2].mean(), corner_ys[2:].mean()))# in (x,y) format

print(find_center(img2)-find_center(img1))

您也可以使用类似的公式来计算旋转(今天晚些时候将更新答案以包含该公式)

© www.soinside.com 2019 - 2024. All rights reserved.