使用OpenCV Python使用模糊水平集进行视网膜液分割

问题描述

正在进行视网膜OCT扫描,并希望使用模糊水平集方法对视网膜液进行分割。为此,我将输入扫描转换为灰度,然后将其传递给模糊级别的Chan-Vese分割算法。应用此细分后,我想将输出传递到findContours()方法进行边界检测。

图像输入和应用Chan-Vese分割算法的代码如下:

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,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,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'

解决方法

正如其中一项注释中正确提到的那样,该问题是由于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)