首页 > 解决方案 > 为什么 cv2.getRectSubPix 中心会出现这种意外行为?

问题描述

我正在使用cv2.getRectSubPix,并且在设置中心时得到了一些意想不到的结果:

import cv2
import numpy as np

src = np.reshape(range(4), (2, 2)).astype('float32')
print(src)
>> [[0. 1.]
>>  [2. 3.]]

patch = cv2.getRectSubPix(src, patchSize=(1, 1), center=(0, 1))
print(patch)
>> [[2.]]

根据文档,计算应如下:

patch[x, y] = src[x + center.x - (dst.cols  - 1) * 0.5, y + center.y - (dst.rows - 1) * 0.5]
patch[0, 0] = src[0 +     0    - (    1     - 1) * 0.5, 0 +     1    - (    1    - 1) * 0.5]
patch[0, 0] = src[0, 1]

然而,patch[0, 0] = 2,而src[0, 1] = 1

看来您必须切换center.yand center.x,并且一切正常。为什么是这样?

标签: pythonopencv

解决方案


默认情况下,NumPy 以行优先顺序存储数组元素。因此,访问元素的正确顺序是src[y, x]patch[y, x]。当然,当getRectSubPix参数patchSize=(w, h)center=(x, y)以该顺序给出时,这会更加令人困惑。

getRectSubPix这是正确遵循链接计算的小部分重新实现:

import cv2
import numpy as np


# Attention: Interpolation for non-integer coordinates is omitted here!
def getRectSubPix_NoInterpolation(src, patchSize, center):
    dst_cols, dst_rows = patchSize
    center_x, center_y = center
    p = np.zeros((dst_rows, dst_cols), src.dtype)
    for y in range(dst_rows):                                           # Iterate rows first
        for x in range(dst_cols):                                       # Iterate columns second
            p[y, x] = src[int(y + center_y - (dst_rows - 1) * 0.5),     # Access y first
                          int(x + center_x - (dst_cols - 1) * 0.5)]     # Access x second
    return p


src = np.reshape(range(6), (3, 2)).astype('float32')
print(src)
#  [[0. 1.]
#   [2. 3.]
#   [4. 5.]]

ps = (1, 1)
c = (1, 2)          # That's src[2, 1] = 5!

cv2_patch = cv2.getRectSubPix(src, ps, c)
print(cv2_patch)
#  [[5.]]

patch = getRectSubPix_NoInterpolation(src, ps, c)
print(patch)
#  [[5.]]

推荐阅读