使用拉普拉斯算子检测图像中的圆圈
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);
我正在尝试检测眼睛后部(眼底)的圆盘和杯子,以便稍后计算某些东西。所以这是眼睛的图像:
我只是想使用 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);