Сегментация жидкости сетчатки с использованием набора нечетких уровней с использованием OpenCV Python

Я работаю над ОКТ-сканами сетчатки и хочу сегментировать жидкость сетчатки, используя метод Fuzzy Level Set. Для этой цели я преобразовываю входное сканирование в оттенки серого и передаю его алгоритму сегментации Чана-Везе для нечеткого уровня. После применения этой сегментации я хочу передать вывод методу findContours() для определения границ.

Код ввода изображения и применения алгоритма сегментации Чана-Везе выглядит следующим образом:

from skimage.segmentation import chan_vese
img = cv2.imread(img_name)
md_img = apply_median_filter(img)
gray = cv2.cvtColor(md_img, cv2.COLOR_BGR2GRAY)

chv = chan_vese(gray, mu=0.25, lambda1=1, lambda2=1, tol=1e-3, max_iter=200,
               dt=0.5, init_level_set="checkerboard", extended_output=True)

ls_img = chv[1].copy()
out_img2, areas = find_ret_contours(ls_img)

Входное изображение здесь ls_img имеет форму (390, 508) и, безусловно, является изображением в градациях серого.

Вызываемая здесь функция определяется следующим образом:

def find_ret_contours(gray):
  rows, cols = gray.shape
  out_img = md_img.copy()
  **contours, hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)**
  areas = []
  for cntr in contours:
    flag = 1
    area = cv2.contourArea(cntr)
    areas.append(area)

    if area < 200 or area > 200:
      out_img = cv2.drawContours(out_img, [cntr], 0, (0,255,0), 3) ## -1 indicates drawing ALL, then the color

  return out_img, areas

Трассировка ошибки приведена ниже:

---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
<ipython-input-79-1c419739b649> in <module>()
      2 #ls_img = np.array(ls_img, dtype=np.uint8)
      3 #gray_ls = cv2.cvtColor(ls_img, cv2.COLOR_BGR2GRAY)
----> 4 out_img2, areas = find_ret_contours(ls_img)
      5 #plt.imshow(cv[1])
      6 #ls_img.shape

<ipython-input-72-8f79b475aa3b> in find_ret_contours(gray)
      2   rows, cols = gray.shape
      3   out_img = md_img.copy()
----> 4   contours, hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
      5   areas = []
      6   for cntr in contours:

error: OpenCV(4.1.2) /io/opencv/modules/imgproc/src/contours.cpp:197: error: (-210:Unsupported format or combination of formats) [Start]FindContours supports only CV_8UC1 images when mode != CV_RETR_FLOODFILL otherwise supports CV_32SC1 images only in function 'cvStartFindContours_Impl'

person Muhammad Usman    schedule 03.09.2020    source источник
comment
Можешь print(gray.dtype, gray.shape) до cv2.findContours ?   -  person ZdaR    schedule 03.09.2020
comment
@ЗдаР float64 (390, 508)   -  person Muhammad Usman    schedule 03.09.2020
comment
Проблема в том, что переменная ls_img содержит отрицательные значения. Метод findContours работает для изображений, где значение каждого пикселя находится в диапазоне от 0 до 255.   -  person Ahx    schedule 03.09.2020


Ответы (1)


Как правильно указано в одном из комментариев, проблема была связана с отрицательными значениями в ls_img. Поэтому проблема решается путем масштабирования всех значений изображения в диапазоне 0-255 и взятия их абсолютных значений. Ниже приведен обновленный код:

data = chv[1].copy()

im_max = 255
data = abs(data.astype(np.float64) / data.max())
data = im_max * data # Now scale by 255
ls_img = data.astype(np.uint8)

temp = apply_k_mean_clustering(ls_img)
out_img2, areas = find_ret_contours(temp)
person Muhammad Usman    schedule 03.09.2020