使用opencv中的轮廓检测检测视网膜图像中的视盘?
Detect optic disk in a retina image using contour detection in opencv?
我有以下视网膜图像,我试图在视盘周围画一个圆圈(视网膜图像中的白色圆形)。这是原始图像:
然后我应用了自适应阈值 cv2.findcontour:
import cv2
def detectBlob(file):
# read image
img = cv2.imread(file)
imageName = file.split('.')[0]
# convert img to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# do adaptive threshold on gray image
thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 101, 3)
# apply morphology open then close
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
blob = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (20,20))
blob = cv2.morphologyEx(blob, cv2.MORPH_CLOSE, kernel)
# invert blob
blob = (255 - blob)
# Get contours
cnts,hierarchy = cv2.findContours(blob, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# write results to disk
result = img.copy()
cv2.drawContours(result, cnts, -1, (0, 0, 255), 3)
cv2.imwrite(imageName+"_threshold.jpg", thresh)
cv2.imwrite(imageName+"_blob.jpg", blob)
cv2.imwrite(imageName+"_contour.jpg", result)
detectBlob('16.png')
这是阈值的样子:
这是轮廓的最终输出:
理想情况下,我正在寻找这样的输出:
您需要识别更大的结构。理想情况下,您需要一个大约为视盘半径 1/4 的结构尺寸来平衡结果和处理时间(用更大的尺寸进行实验直到可以接受)。
或者你可以对图像进行降采样(降低分辨率并使图片变小),这或多或少是一回事,即使你在视盘边界上失去了精度。
自适应阈值失败,因为过滤器尺寸太小。虽然我们没有弄清楚这一点,但背景中的波浪非常扰动。
通过将图像分辨率降低 16 倍并应用范围为 99x99 的自适应滤波器,我获得了一个有趣的结果。
我有以下视网膜图像,我试图在视盘周围画一个圆圈(视网膜图像中的白色圆形)。这是原始图像:
然后我应用了自适应阈值 cv2.findcontour:
import cv2
def detectBlob(file):
# read image
img = cv2.imread(file)
imageName = file.split('.')[0]
# convert img to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# do adaptive threshold on gray image
thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 101, 3)
# apply morphology open then close
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
blob = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (20,20))
blob = cv2.morphologyEx(blob, cv2.MORPH_CLOSE, kernel)
# invert blob
blob = (255 - blob)
# Get contours
cnts,hierarchy = cv2.findContours(blob, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# write results to disk
result = img.copy()
cv2.drawContours(result, cnts, -1, (0, 0, 255), 3)
cv2.imwrite(imageName+"_threshold.jpg", thresh)
cv2.imwrite(imageName+"_blob.jpg", blob)
cv2.imwrite(imageName+"_contour.jpg", result)
detectBlob('16.png')
这是阈值的样子:
这是轮廓的最终输出:
理想情况下,我正在寻找这样的输出:
您需要识别更大的结构。理想情况下,您需要一个大约为视盘半径 1/4 的结构尺寸来平衡结果和处理时间(用更大的尺寸进行实验直到可以接受)。
或者你可以对图像进行降采样(降低分辨率并使图片变小),这或多或少是一回事,即使你在视盘边界上失去了精度。
自适应阈值失败,因为过滤器尺寸太小。虽然我们没有弄清楚这一点,但背景中的波浪非常扰动。
通过将图像分辨率降低 16 倍并应用范围为 99x99 的自适应滤波器,我获得了一个有趣的结果。