【问题标题】:Image processing issues with blood vessels血管的图像处理问题
【发布时间】:2016-08-11 05:35:06
【问题描述】:

我正在尝试从图像中提取血管,为此,我首先对图像进行均衡化,应用 CLAHE 直方图获得以下结果:

        clahe = cv2.createCLAHE(clipLimit=100.0, tileGridSize=(100,100))
        self.cl1 = clahe.apply(self.result_array)
        self.cl1 = 255 - self.cl1

然后我正在使用 OTSU 阈值来提取血管,但做得不好:

self.ret, self.thresh = cv2.threshold(self.cl1, 0,255,cv2.THRESH_BINARY + cv2.THRESH_OTSU)
        kernel = np.ones((1,1),np.float32)/1
        self.thresh = cv2.erode(self.thresh, kernel, iterations=3)
        self.thresh = cv2.dilate(self.thresh, kernel, iterations=3)

结果如下:

显然有很多噪音。我尝试过使用中值模糊,但它只是在某些地方将噪声聚集并使其变成一个斑点。如何去除噪音以获取血管?

这是我试图从中提取血管的原始图像:

【问题讨论】:

  • 请附上原始图像和预期输出。
  • 我没有想要的输出,抱歉。我已附上原件。
  • 您会尝试将 tileGridSize=(8,8) 设置为更类似于 (20,20) 的值吗?我认为euqlizing有点过于激进。它不会完全解决问题,但可能会带来更好的结果。
  • 是的,我已经尝试过了,你是对的,它确实改善了结果,但没有多大意义。
  • 哦,好吧。我不熟悉 OpenCV,我可以解释一下我将如何尝试解决它。第 1 步:创建每个像素周围的噪声级别图。第二步:计算中值噪声。第 3 步:对于每个像素,将原始图像的亮度乘以噪声水平(来自地图第 1 步)减去中值+阈值。

标签: python image opencv image-processing


【解决方案1】:

获得真正好的结果是一个难题(您可能必须以某种方式对血管结构和噪声进行建模),但您可能仍然可以做得比过滤更好。

受 Canny 边缘检测器启发,解决此类问题的一种技术是使用两个阈值 - [hi,low] 并将像素 p 与响应 r 分类为属于血管 V if @ 987654335@ || (r > lo && p 的邻居之一在V)。

此外,在滤波方面,双边滤波和均值偏移滤波都适用于噪声图像。

kernel3 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
kernel5 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
kernel7 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(7,7))
t_lo = 136
t_hi = 224

blured = cv2.pyrMeanShiftFiltering(img, 3, 9)
#blured = cv2.bilateralFilter(img, 9, 32, 72)

clahe = cv2.createCLAHE(clipLimit=128.0, tileGridSize=(64, 64))
cl1 = clahe.apply(blured)
cl1 = 255 - cl1

ret, thresh_hi = cv2.threshold(cl1, t_hi, 255, cv2.THRESH_TOZERO)
ret, thresh_lo = cv2.threshold(cl1, t_lo, 255, cv2.THRESH_TOZERO)

低阈值图像 嗨阈值图像

准备和清理:

current = np.copy(thresh_hi)
prev = np.copy(current)
prev[:] = 0
current = cv2.morphologyEx(current, cv2.MORPH_OPEN, kernel5)
iter_num = 0
max_iter = 1000

这不是最有效的方法...但易于实施:

while np.sum(current - prev) > 0 and iter_num < max_iter:
    iter_num = iter_num+1
    prev = np.copy(current)
    current = cv2.dilate(current, kernel3)
    current[np.where(thresh_lo == 0)] = 0

初始掩码

去除小斑点:

contours, hierarchy = cv2.findContours(current, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
    area = cv2.contourArea(contour)
    if area < 256:
        cv2.drawContours( current, [contour], 0, [0,0,0], -1 )

去除小斑点后

形态清理:

opening = cv2.morphologyEx(current, cv2.MORPH_OPEN, kernel7)   
cl1[np.where(opening == 0)] = 0

结果

这绝不是最佳选择,但我认为它应该为您提供足够的工具来开始。

【讨论】:

    【解决方案2】:

    怎么样: 高通(图像减去 sigma 12 的高斯平滑),然后是阈值(126),然后是小物体抑制(小于 300 像素的物体被去除)?

    (我使用了你的上一张图片)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-04
      • 2021-01-23
      • 2019-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-08
      相关资源
      最近更新 更多