血管图像处理问题

13 python opencv image image-processing

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

        clahe = cv2.createCLAHE(clipLimit=100.0, tileGridSize=(100,100))
        self.cl1 = clahe.apply(self.result_array)
        self.cl1 = 255 - self.cl1
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

然后我使用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)
Run Code Online (Sandbox Code Playgroud)

这是结果:

在此输入图像描述

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

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

在此输入图像描述

Ros*_*chi 11

获得非常好的结果是一个难题(你可能不得不以某种方式模拟血管的结构和噪音),但你可能仍然比过滤更好.

在Canny边缘检测器的启发下,解决这类问题的一种技术是使用两个阈值 - 如果|| [hi,low]将像素分类为p响应r属于血管.(&&其中一个邻居在).Vr > hir > lopV

此外,当涉及滤波时,双边滤波和均值滤波都适用于噪声图像.

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)
Run Code Online (Sandbox Code Playgroud)

低门槛 低阈值图像 嗨门槛 嗨阈值图像

准备和清理:

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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

初始面具 初始面具

删除小blob:

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 )
Run Code Online (Sandbox Code Playgroud)

精致面膜 去除小斑点后

形态清理:

opening = cv2.morphologyEx(current, cv2.MORPH_OPEN, kernel7)   
cl1[np.where(opening == 0)] = 0
Run Code Online (Sandbox Code Playgroud)

结果 结果

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


Art*_*tem 6

怎么样:高通(图像减去高斯光滑与西格玛12),然后阈值(126),然后小物体抑制(小于300像素的物体被删除)?

(我用你的最后一张图片)

在此输入图像描述

在此输入图像描述

在此输入图像描述