Как определить, находится ли 2D-массив внутри другого 2D-массива?

Поэтому с помощью элемента переполнения стека у меня есть следующий код:

data = "needle's (which is a png image) base64 code goes here" decoded = data.decode('base64') f = cStringIO.StringIO(decoded) image = Image.open(f) needle = image.load() while True: screenshot = ImageGrab.grab() haystack = screenshot.load() if detectImage(haystack, needle): break else: time.sleep(5) 

Я написал следующий код, чтобы проверить, находится ли игла в стоге сена:

 def detectImage(haystack, needle): counter = 0 for hayrow in haystack: for haypix in hayrow: for needlerow in needle: for needlepix in needlerow: if haypix == needlepix: counter += 1 if counter == 980: #the needle has 980 pixels return True else: return False 

Проблема в том, что я получаю эту ошибку для строки 3: объект PixelAccess не является итерируемым

Мне было предложено, чтобы было легче скопировать и иглу, и стог сена в массив numpy / scipy. И тогда я могу просто использовать функцию, которая проверяет, находится ли игла 2D-массива внутри сена.

Мне нужна помощь:

1) преобразование этих массивов в массивы numpy.

2) функция, которая проверяет, находится ли игла 2D-массива внутри сена. Моя функция не работает.

Это изображения:
Игла:
игла
Стог:
стог сенастог сена

3 Solutions collect form web for “Как определить, находится ли 2D-массив внутри другого 2D-массива?”

Вы можете использовать matchTemplate в opencv для определения позиции:

 import cv2 import numpy as np import pylab as pl needle = cv2.imread("needle.png") haystack = cv2.imread("haystack.jpg") diff = cv2.matchTemplate(haystack, needle, cv2.TM_CCORR_NORMED) x, y = np.unravel_index(np.argmax(diff), diff.shape) pl.figure(figsize=(12, 8)) im = pl.imshow(haystack[:,:, ::-1]) ax = pl.gca() ax.add_artist(pl.Rectangle((y, x), needle.shape[1], needle.shape[0], transform=ax.transData, alpha=0.6)) 

вот результат:

введите описание изображения здесь

Чтобы преобразовать изображение в массив numpy, вы должны просто сделать это:

 import numpy as np from PIL import Image needle = Image.open('needle.png') haystack = Image.open('haystack.jpg') needle = np.asarray(needle) haystack = np.asarray(haystack) 

Чтобы вы начали с поиска иглы, обратите внимание, что это даст вам список всех мест, где находится угол:

 haystack = np.array([[1,2,3],[3,2,1],[2,1,3]]) needle = np.array([[2,1],[1,3]]) np.where(haystack == needle[0,0]) #(array([0, 1, 2]), row-values # array([1, 1, 0])) col-values 

Затем вы можете посмотреть все угловые совпадения и посмотреть, совпадает ли с ней:

 h,w = needle.shape rows, cols = np.where(haystack == needle[0,0]) for row, col in zip(rows, cols): if np.all(haystack[row:row+h, col:col+w] == needle): print "found it at row = %i, col = %i"%(row,col) break else: print "no needle in haystack" 

Ниже приведена более надежная версия, которая находит наилучшее совпадение, и если она соответствует лучшему, чем некоторый процент, считается найденной иглой. Возвращает координату угла, если найден, None если нет.

 def find_needle(needle, haystack, tolerance=.80): """ input: PIL.Image objects output: coordinat of found needle, else None """ # convert to grayscale ("L"uminosity) for simplicity. needle = np.asarray(needle.convert('L')) haystack = np.asarray(haystack.convert('L')) h,w = needle.shape H,W = haystack.shape L = haystack.max() best = (None, None, 1) rows, cols = np.where((haystack - needle[0,0])/L < tolerance) for row, col in zip(rows, cols): if row+h > H or col+w > W: continue # out of range diff = np.mean(haystack[row:row+h, col:col+w] - needle)/L if diff < best[-1]: best = (diff, row, col) return best if best[-1] < tolerance else None 

Наконец, мне удалось выполнить только однократную реализацию поиска по взаимной корреляции … Перекрестная корреляция вычисляется с использованием теоремы взаимной корреляции и БПФ.

 from __future__ import division import numpy as np from PIL import Image import matplotlib.pyplot as plt def cross_corr(a, b): a_rows, a_cols = a.shape[:2] b_rows, b_cols = b.shape[:2] rows, cols = max(a_rows, b_rows), max(a_cols, b_cols) a_f = np.fft.fft2(a, s=(rows, cols), axes=(0, 1)) b_f = np.fft.fft2(b, s=(rows, cols), axes=(0, 1)) corr_ab = np.fft.fft2(a_f.conj()*b_f, axes=(0,1)) return np.rint(corr_ab / rows / cols) def find_needle(haystack, needle, n=10): # convert to float and subtract 128 for better matching haystack = haystack.astype(np.float) - 128 needle = needle.astype(np.float) - 128 target = np.sum(np.sum(needle*needle, axis=0), axis=0) corr_hn = cross_corr(haystack, needle) delta = np.sum(np.abs(corr_hn - target), axis=-1) return np.unravel_index(np.argsort(delta, axis=None)[:n], dims=haystack.shape[:2]) haystack = np.array(Image.open('haystack.jpg')) needle = np.array(Image.open('needle.png'))[..., :3] plt.imshow(haystack, interpolation='nearest') dy, dx = needle.shape[:2] candidates = find_needle(haystack, needle, 1) for y, x in zip(*candidates): plt.plot([x, x+dx, x+dx, x, x], [y, y, y+dy,y+dy, y], 'g-', lw=2) plt.show() 

Таким образом, самая высокая оценка – настоящая игла:

введите описание изображения здесь

 >>> print candidates (array([553], dtype=int64), array([821], dtype=int64)) 
  • Как использовать Matlab's imresize в python
  • Среднее скользящее среднее
  • Как вычислить ошибку для полиномиального подгонки (в наклоне и перехвате)
  • Отчёт о двух выборочной статистике KS из двух предварительно вычисленных гистограмм
  • ImportError: нет модуля с именем array_import ----- scipy
  • Самый быстрый 2D сверток или фильтр изображений в Python
  • Поверните ключи словаря в имена переменных с одинаковыми значениями в Python из .mat файлов Matlab, используя scipy.io.loadmat
  • Как я могу «разделить» на два значения?
  • Python - лучший язык программирования в мире.