Python -OpenCV функция заливки; странные ошибки типа - PullRequest
1 голос
/ 20 марта 2020

Я пытаюсь реализовать собственную версию функции MatLab imhmin () в Python с использованием OpenCV и (естественно) NumPy. Если вы не знакомы с этой функцией MatLab, она чрезвычайно полезна для сегментации. Документация MatLab может объяснить это гораздо лучше, чем я:

https://it.mathworks.com/help/images/ref/imhmin.html

Вот что я имею до сих пор:

(Ради для краткости, я не включил функцию local_min. Она принимает один параметр изображения и возвращает изображение того же размера, где локальные минимумы равны 1 с, а все остальное равно 0.)

from volume import show
import cv2
import numpy

def main():
    arr = numpy.array( [[5,5,5,5,5,5,5],
                        [5,0,3,1,4,2,5],
                        [5,5,5,5,5,5,5]] ) + 1

    res = imhmin(arr, 3)

    print(res)


def imhmin(src, h):
    # TODO: speed up function by cropping image

    edm = src.copy()

    # d is the domain / all values contained in the array
    d = numpy.unique(edm)

    # for the index of each local minima (sorted gtl)
    indices = numpy.nonzero(local_min(edm)) # get indices
    indices = numpy.dstack((indices[0], indices[1]))[0].tolist() # zip
    # sort based on the value of edm[] at that index
    indices.sort(key = lambda _: edm[_[0],_[1]], reverse = True)

    for (x,y) in indices:
        start = edm[x,y] # remember original value of minima

        # for each in a list of heights greater than the starting height
        for i in range(*numpy.where(d==edm[x,y])[0], d.shape[0]-1):
            # prevent exceeding target height
            step = start + h if (d[i+1] - start > h) else d[i+1]

            #-------------- WORKS UNTIL HERE --------------#

            # complete floodFill syntax:
            # cv2.floodFill(image, mask, seed, newVal[, loDiff[, upDiff[, flags]]]) → retval, rect

            # fill UPWARD onto image (and onto mask?)
            cv2.floodFill(edm, None, (y,x), step, 0, step-d[i], 4)

            # fill DOWNWARD NOT onto image
            # have you overflowed?


if __name__ == "__main__":
    main()

Что отлично работает пока не доберется до линии затопления. Он возвращает эту ошибку обратно:

Traceback (most recent call last):
  File "edm.py", line 94, in <module>
    main()
  File "edm.py", line 14, in main
    res = imhmin(arr, 3)
  File "edm.py", line 66, in imhmin
    cv2.floodFill(edm, None, (y,x), step, 0, step-d[i], 4)
TypeError: Layout of the output array image is incompatible with cv::Mat (step[ndims-1] != elemsize or step[1] != elemsize*nchannels)

Сначала я подумал, что, может быть, способ, которым я выложил параметры, был неправильным из-за того, что в трассировке указано step, но я попытался изменить имя этой переменной и пришли к выводу, что step - это имя некоторой переменной в коде OpenCV. Речь идет о массиве вывода, и я не использую маску, поэтому что-то должно быть не так с массивом edm.

. Я могу устранить эту ошибку, заменив строку залива этой:

cv2.floodFill(edm.astype(numpy.double), None, (y,x), step, 0, step-d[i], 4)

Разница в том, что я типизирую массив numpy в массив с плавающей точкой. Тогда я остаюсь с этой ошибкой:

Traceback (most recent call last):
  File "edm.py", line 92, in <module>
    main()
  File "edm.py", line 14, in main
    res = imhmin(arr, 3)
  File "edm.py", line 64, in imhmin
    cv2.floodFill(edm.astype(numpy.double), None, (y,x), step, 0, step-d[i], 4)
TypeError: Scalar value for argument 'newVal' is not numeric

Здесь я начал подозревать, что что-то серьезно не так, потому что step "очевидно" будет здесь целым числом (возможно, это не очевидно, но я попытался напечатать его, и похоже, что это просто целое число, а не массив из одного целого числа или чего-то странного в этом роде.) , Я получил почти то же самое сообщение об ошибке о параметре upDiff, поэтому я просто произвел его также, приведя к следующей строке кода:

cv2.floodFill(edm.astype(numpy.double), None, (y,x), float(step), 0, float(step-d[i]), 4)

Я знаю, что это не так Я не хотел делать что-то, но я просто хотел посмотреть, что произойдет. Что случилось, я получил эту страшно выглядящую ошибку:

Traceback (most recent call last):
  File "edm.py", line 92, in <module>
    main()
  File "edm.py", line 14, in main
    res = imhmin(arr, 3)
  File "edm.py", line 64, in imhmin
    cv2.floodFill(edm.astype(numpy.double), None, (y,x), float(step), 0, float(step-d[i]), 4)
cv2.error: OpenCV(3.4.2) /opt/concourse/worker/volumes/live/9523d527-1b9e-48e0-7ed0-a36adde286f0/volume/opencv-suite_1535558719691/work/modules/imgproc/src/floodfill.cpp:587: error: (-210:Unsupported format or combination of formats)  in function 'floodFill'

Я даже не знаю, с чего начать. Я использовал функцию залива OpenCV много раз и никогда не сталкивался с подобными проблемами. Кто-нибудь может дать какие-либо идеи?

Заранее спасибо

Антонио

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...