使用拉普拉斯检测图像中的圆圈

时间:2016-06-15 09:18:26

标签: python opencv matplotlib computer-vision gaussian

我正在尝试检测眼睛后方的圆盘和杯子(眼底),以便稍后计算某些事情。所以这是一张眼睛的图像:

enter image description here

我只是试图使用OpenCV和python检测磁盘,或者图像右侧较大的黄色圆圈,以及第一个圆圈内的较小的黄色圆圈,这样我最终可以执行某些计算。

到目前为止,我尝试使用拉普拉斯过滤来使圆圈更加突出。

这是我的代码:

import cv2
import numpy as np
from matplotlib import pyplot as plt
from pylab import *

# loading image
img0 = cv2.imread('01_g.jpg',)

# converting to gray scale
gray = cv2.cvtColor(img0, cv2.COLOR_BGR2GRAY)

# remove noise
img = cv2.GaussianBlur(gray,(3,3),0)

# convolute with proper kernels
laplacian = cv2.Laplacian(img,cv2.CV_64F)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)  # x
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5)  # y
magnitude = sqrt(sobelx**2+sobely**2)

plt.subplot(2,2,1),plt.imshow(img,cmap = 'gray')
plt.title('Original'), plt.xticks([]), plt.yticks([])

plt.subplot(2,2,2),plt.imshow(laplacian,cmap = 'gray')
plt.title('Laplacian'), plt.xticks([]), plt.yticks([])

plt.subplot(2,2,3),plt.imshow(sobelx,cmap = 'gray')
plt.title('Sobel X'), plt.xticks([]), plt.yticks([])

plt.subplot(2,2,4),plt.imshow(sobely,cmap = 'gray')
plt.title('Sobel Y'), plt.xticks([]), plt.yticks([])

plt.show()

这是我得到的结果: enter image description here

正如你所看到的,拉普拉斯过滤器根本没有帮助 - 事实上,杯子和圆盘甚至都看不到。 sobelx和sobely至少给出了一些外圈(盘)的轮廓

我也尝试过laplacian的绝对值:

final = np.absolute(laplacian)
plt.imshow(final, cmap = 'gray')
plt.show()

我得到了这个结果:

enter image description here

我还尝试使用此代码应用Difference of Gaussians method

#difference of gaussians

blur1 = cv2.GaussianBlur(img,(3,3),1)
blur2 = cv2.GaussianBlur(img,(5,5),1.1)
difference = blur2 - blur1
plt.imshow(difference, cmap = 'gray')
plt.show()

但这也不会让我到处都是。我真的很感激如何在这张图片中检测杯子和磁盘。

1 个答案:

答案 0 :(得分:1)

修改 如图所示的先前MSER方法未能找到圆形斑点,但它突出显示该区域。所以我尝试Difference-of-Gaussians(DoG)进行blob检测,结果很好。您可以尝试高斯内核大小及其sigma。请注意,在应用DoG之前,我已经对图像进行了下采样并通过扩张移除了血管结构。对DoG图像进行阈值处理可以为您提供blob。

此外,我注意到您感兴趣的区域是图像的全局最大值(对于不同的图像可能不是这样)。也许你可以将这些知识与你的算法结合起来。

dog

阈值化的DoG

thresh

Global Max

max

Dog方法的代码(c ++)

Mat im = imread("8Lzuq.jpg", 0);
Mat dw;

pyrDown(im, dw);
pyrDown(dw, dw);
pyrDown(dw, dw);

Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(7, 7));
morphologyEx(dw, dw, CV_MOP_DILATE, kernel);

Mat g1, g2, dog, bw;
GaussianBlur(dw, g1, Size(31, 31), 21, 21);
GaussianBlur(dw, g2, Size(65, 65), 31, 31);
dog = g1 - g2;
normalize(dog, dog, 0, 255, NORM_MINMAX);

threshold(dog, bw, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);

Point mx;
minMaxLoc(dw, NULL, NULL, NULL, &mx);

circle(dw, mx, 20, Scalar(255, 255, 255), 2);

MSER方法

我尝试对彩色图像进行下采样,对其进行扩张,然后在各个通道中检测MSER s。虽然它没有将磁盘概述为一个完美的圆圈,但结果看起来不错。

蓝色频道:

b bmser

绿色频道:

g gmser

红色频道:

r rmser

检测彩色图像中的MSER效果不佳。

c ++中的代码

Mat im = imread("8Lzuq.jpg");
Mat dw;

pyrDown(im, dw);
pyrDown(dw, dw);
pyrDown(dw, dw);

Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(7, 7));
morphologyEx(dw, dw, CV_MOP_DILATE, kernel);

Mat ch[3];
split(dw, ch);

MSER mser;
vector<vector<Point>> regions;

mser(ch[2], regions);
Mat regionsMat = Mat::zeros(dw.rows, dw.cols, CV_8U);

for (size_t i = 0; i < regions.size(); i++)
{
    for (Point pt: regions[i])
    {
        uchar& val = regionsMat.at<uchar>(pt);
        if (val > 0)
        {
            val += 1;
        }
        else
        {
            val = 1;
        }
    }

}

imwrite("reg.jpg", regionsMat*50);