如何在OpenCV中使用岭检测滤波器

8
我正在尝试使用opencv-python中的岭/谷滤波器。我刚刚查看了openCV官方网站上的文档,文档告诉我要使用out = cv.ximgproc_RidgeDetectionFilter.getRidgeFilteredImage( _img[, out] )
然而,在尝试后,这个函数似乎在cv2(python)中不存在。有没有其他方法可以使用openCV或任何其他可用方法来完成这个任务?
3个回答

12

岭是图像的二阶导数矩阵(也称为 Hessian 矩阵)的特征值。

利用上述信息,您可以使用 scikit-image 提供的功能轻松编写岭检测器。

from skimage.features import hessian_matrix, hessian_matrix_eigvals
def detect_ridges(gray, sigma=3.0):
    hxx, hyy, hxy = hessian_matrix(gray, sigma)
    i1, i2 = hessian_matrix_eigvals(hxx, hxy, hyy)
    return i1, i2

这里,i1返回局部最大值的山脊,i2返回局部最小值的山脊。您可以尝试不同的sigma值以获得适当的解决方案。

例如:

enter image description here

实际上,在Python/OpenCV中,您可以像这样做:

image = cv2.imread('retina.tif')
ridge_filter = cv2.ximgproc.RidgeDetectionFilter_create()
ridges = ridge_filter.getRidgeFilteredImage(image)

cv2.ximgproc.RidgeDetectionFilter_create的参数包括:

@param ddepth  Specifies output image depth. Defualt is CV_32FC1
@param dx Order of derivative x, default is 1 .   
@param dy  Order of derivative y, default is 1 .   
@param ksize Sobel kernel size , default is 3 .   
@param out_dtype Converted format for output, default is CV_8UC1 .   
@param scale Optional scale value for derivative values, default is 1 .   
@param delta  Optional bias added to output, default is 0 .   
@param borderType Pixel extrapolation  method, default is BORDER_DEFAULT

源代码 - https://docs.opencv.org/trunk/d4/d36/classcv_1_1ximgproc_1_1RidgeDetectionFilter.html


1
该模块名为skimage.feature(不是skimage.features)。 - onewhaleid

4

目前(scikit-image 1.14.1),接受的答案已经不能使用。

这里有一个已经可以使用的版本:

import cv2
import matplotlib.pyplot as plt
from skimage.feature import hessian_matrix, hessian_matrix_eigvals

src_path = 'Fundus_photograph_of_normal_left_eye.jpg'

def detect_ridges(gray, sigma=1.0):
    H_elems = hessian_matrix(gray, sigma=sigma, order='rc')
    maxima_ridges, minima_ridges = hessian_matrix_eigvals(H_elems)
    return maxima_ridges, minima_ridges

def plot_images(*images):
    images = list(images)
    n = len(images)
    fig, ax = plt.subplots(ncols=n, sharey=True)
    for i, img in enumerate(images):
        ax[i].imshow(img, cmap='gray')
        ax[i].axis('off')
    plt.subplots_adjust(left=0.03, bottom=0.03, right=0.97, top=0.97)
    plt.show()

img = cv2.imread(src_path, 0) # 0 imports a grayscale
if img is None:
    raise(ValueError(f"Image didn\'t load. Check that '{src_path}' exists."))

a, b = detect_ridges(img, sigma=3.0)

plot_images(img, a, b)

眼底图

图片来源: https://en.wikipedia.org/wiki/Fundus_photography#/media/File:Fundus_photograph_of_normal_left_eye.jpg


3
基于“Steger, C., 1998. An unbiased detector of curvilinear structures. IEEE Transactions on Pattern Analysis and Machine Intelligence, 20(2), pp.113–125.”论文的脊线检测算法有一个版本。它不使用openCV,因此我希望不会偏离主题,但您可以根据您的目的修改代码。
这是链接: https://gitlab.gwdg.de/sphire/ridge_detection 您可以直接通过pip安装它。 https://pypi.org/project/ridge-detection/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接