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

Detecting circles in an image using laplacian

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

我只是想使用 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()

这是我得到的结果:

如您所见,拉普拉斯滤波器根本没有帮助——事实上,杯子和圆盘甚至都不可见。 sobelx和sobely至少给出了一些外圈(圆盘)的轮廓

拉普拉斯算子的绝对值我也试过:

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

我得到了这个结果:

我也尝试过使用此代码应用 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()

但这也没有让我有任何收获。如果能帮助我检测这张图片中的杯子和圆盘,我将不胜感激。

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

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

阈值 DoG

全局最大值

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 方法

我尝试对彩色图像进行下采样,将其放大,然后在各个通道中检测 MSERs。结果看起来不错,虽然它没有将圆盘勾勒成一个完美的圆。

蓝色通道:

绿色通道:

红色通道:

检测彩色图像中的 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);