Какой самый быстрый способ центрировать объект в 2d матрице с python - PullRequest
0 голосов
/ 28 марта 2020

Справочная информация: Я получил изображение в градациях серого с глубины камеры. Из этого изображения вычитается фон. Фон был установлен до того, как представляющий интерес объект был помещен в поле зрения камеры. Остается только объект. Это означает, что остальные пиксели имеют значение 0. Я хочу, чтобы этот объект был в центре изображения. Этот объект может иметь любую форму. Я придумал следующий алгоритм. Но это медленно, и я думаю, что, возможно, есть более быстрый путь. Также я думаю, что он может быть оптимизирован, чтобы НЕ иметь метод для каждой оси. Так что _getShiftForHeight и _getShiftForWidth в основном делают то же самое. но на другой оси. (В ближайшем будущем я также хочу применить тот же алгоритм к 3d и, возможно, также к 4d).

Вопрос: Какой самый быстрый способ центрировать объект произвольной формы в 2d матрица (изображение), где значения объекта> 0, а остальные 0?

Python код:

import numpy as np
from scipy.ndimage.interpolation import shift

def ShiftToCenter2d(matrix):
  toShiftHorizontally = _getShiftForWidth(matrix)
  toShiftVertically = _getShiftForHeight(matrix)
  return shift(matrix, [toShiftVertically, toShiftHorizontally])

def _getShiftForWidth(matrix):
  (height, width) = matrix.shape
  weightCenterPerRow = np.zeros(height)
  for r in range(height):
    columnsWithValue = 0
    sumOfIndex = 0
    for c in range(width):
      if matrix[r, c] != 0:
        sumOfIndex += c
        columnsWithValue += 1
    if sumOfIndex > 0:
      weightCenterPerRow[r] = sumOfIndex / columnsWithValue
  weightCenterPerRowBinary = np.where(weightCenterPerRow > 0, 1, 0)
  rowsWithValues = np.sum(weightCenterPerRowBinary)
  centerWidthOfBlob = np.sum(weightCenterPerRow) / rowsWithValues
  centerWidthOfImage = (width - 1) / 2
  return centerWidthOfImage - centerWidthOfBlob

def _getShiftForHeight(matrix):
  (height, width) = matrix.shape
  weightCenterPerColumn = np.zeros(width)
  for c in range(width):
    rowsWithValue = 0
    sumOfIndex = 0
    for r in range(height):
      if matrix[r, c] != 0:
        sumOfIndex += r
        rowsWithValue += 1
    if sumOfIndex > 0:
      weightCenterPerColumn[c] = sumOfIndex / rowsWithValue
  weightCenterPerColumnBinary = np.where(weightCenterPerColumn > 0, 1, 0)
  columnsWithValues = np.sum(weightCenterPerColumnBinary)
  centerHeightOfBlob = np.sum(weightCenterPerColumn) / columnsWithValues
  centerHeightOfImage = (height - 1) / 2
  return centerHeightOfImage - centerHeightOfBlob
...