Я написал функцию Cython, которая расширяет двоичное изображение (массив numpy) на 1 пиксель. Поэтому я хочу, чтобы просто расширить область, где значение массива является: 1. Вот мой наивный подход:Производительность: расширение бинарного изображения (морфологическое расширение)
def expand_1px (numpy.ndarray[numpy.uint8_t, ndim = 2] A):
cdef int h = A.shape[0]
cdef int w = A.shape[1]
cdef numpy.ndarray[numpy.uint8_t, ndim = 2] RES = numpy.zeros([h, w], dtype = numpy.uint8)
# These Two lines below were originally missing
cdef int y, x
cdef unsigned char prev, cur
for x in range (0, w):
for y in range (1, h):
prev = A[y-1,x]
cur = A[y,x]
if cur > prev:
RES[y-1, x] = 1
if cur < prev:
RES[y,x] = 1
for y in range (0, h):
for x in range (1, w):
prev = A[y,x-1]
cur = A[y,x]
if cur > prev:
RES[y, x-1] = 1
if cur < prev:
RES[y,x] = 1
return numpy.bitwise_or(A,RES)
Это работает правильно, но является жалким медленно. Функция расширения OpenCV() равна ~ 30 раз быстрее, чем мой вариант Cython, и дает тот же результат. Я использую это так:
kernel = numpy.ones((3,3), dtype="uint8")
kernel[0,0] = 0
kernel[2,2] = 0
kernel[0,2] = 0
kernel[2,0] = 0
...
IMG = cv2.dilate(IMG,kernel,iterations = 1)
Q:
- Как может быть вариант OpenCV так быстро? Что это на самом деле?
- Как я могу заставить свою функцию Cython работать так быстро?
Update:
Такое плохое выступление было из-за отсутствия 'CDEF' деклараций, мой плохой. Добавление этой функции делает разницу:
cdef int y, x
cdef unsigned char prev, cur
Тем не менее, разница в производительности составляет около 30 раз, что также вид dissapointing. Любые советы для дальнейшего совершенствования?
* «Как я могу заставить свою функцию Cython работать так быстро?» * Вы можете начать с объявления большего количества (возможно, всех) ваших локальных переменных (.eg 'x',' y', 'prev',' cur') с соответствующим типом С; см. http://docs.cython.org/src/quickstart/cythonize.html –
@WarrenWeckesser Спасибо. Вы, конечно, конечно, я знал, что, вероятно, совершу ошибку в noob. Тем не менее это ~ 30 раз медленнее, чем вариант OpenCV, я обновлю вопрос. –
Вы использовали параметр командной строки '-a', чтобы команда cython генерировала раскрашенную HTML-версию источника? Темно-желтые линии - это линии, которые приводят к вызовам Python вместо генерации чистого C. Для достижения максимальной производительности вы хотите настроить код cython, чтобы в цикле не было желтого. (Эти петли выглядят довольно просто, поэтому, если все переменные имеют C-объявления, вполне вероятно, что у вас нет вызовов python, оставшихся в циклах.) –