在图像中查找圆形圆圈

时间:2015-07-27 12:52:44

标签: image-processing

我有一个图像。我想检测我用红线标记的四个孔。

我在下面的链接中有所有图片。 https://www.dropbox.com/sh/mlrm51qx8s1mcw0/AABu_dLm8RbvPO60H4CJ7I3ka?dl=0

inputImage的(Input_Image.bmp)

预处理图像(PreprocessedImage.bmp)

工作图像(检测到的孔)(DetectedHoles.bmp)

非工作图像(仅检测到3个孔)(NoNWorking.bmp)

最初,这是我对输入图像进行的预处理 输入图像:Input_Image.bmp

hcontadj=vision.ContrastAdjuster;
Extracted_Rim_ContrasT_Adj=step(hcontadj,Extracted_Rim);
J = adapthisteq(Extracted_Rim);
Sharp_Img=imsharpen(J);
se=strel('disk',300);
imtop_op=imtophat(Sharp_Img,se);


 hgamma = ...
     vision.GammaCorrector(90.0,'Correction','De-gamma');
%  hgamma = ...
%      vision.GammaCorrector(12.0,'Correction','Gamma');
 y = step(hgamma, imtop_op);

h1 = imfilter(y,fspecial('gaussian',60,5));
H2=h1.*6.0;

se = strel('disk',14);
% Perform a morphological close operation on the image.
closeBW = imclose(H2,se);
figure, imshow(closeBW);

上述处理后获得的输出图像 PreprocessedImage.bmp

imfindcircles()和viscircles()用于查找[center,Raddi]并分别用蓝色标记圆圈。

 [centers, radii] = imfindcircles(New_Open_Img,[32  100],'Sensitivity',0.81,'ObjectPolarity','dark');

    [h,x,y]=viscircles(centers, radii,'EdgeColor','b');

在上述两个函数imfindcircles()和viscircles()之后获得的输出图像是 DetectedHoles.bmp

仅检测到三个孔的非工作图像 NoNWorking.bmp 。在这种情况下,未正确检测到所有四个圆圈。

我在imfindcircles()中精确调整了灵敏度和半径,但我仍然无法检测到所有圆圈。

如果你能给我一些解决这个问题的想法,我将不胜感激。

由于

1 个答案:

答案 0 :(得分:2)

我假设您正在使用Matlab,遗憾的是我没有在这里安装Matlab,但是我可以在python中给你一个答案,它应该直接转换为Matlab。

我认为你通过使用Hough变换圈子(imfindcircles)可以朝着一个好的方向前进。但是设置半径范围是正确的至关重要。特别是如果您希望处理的图像相似。如果您上传的图像具有代表性,则半径应在10到15之间(甚至可能过于慷慨,因为您要检测的圆圈宽度仅为25px左右)。

除了使用形态学操作预处理图像之外,我还会使用边缘检测器。我用canny边缘探测器BW1 = edge(I,'Canny');尝试了它。如果这样做,您也会检测中间的圆圈,您可以在后处理步骤中将其删除。您只需检查哪个圆圈既不向上或向下,也不向左或向右最远。

基于python / skimage的代码(稍微改变了示例代码:http://scikit-image.org/docs/dev/auto_examples/plot_circular_elliptical_hough_transform.html):

import numpy as np
import matplotlib.pyplot as plt

from skimage import data, color
from skimage.transform import hough_circle
from skimage.feature import peak_local_max, canny
from skimage.draw import circle_perimeter
from skimage.util import img_as_ubyte
from skimage.io import imread


# Load picture and detect edges
image = imread('test.jpeg')[..., 0]
edges = canny(image, sigma=3, low_threshold=10, high_threshold=50)

fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(20, 10))

# Detect two radii
hough_radii = np.arange(13, 15, 2)
hough_res = hough_circle(edges, hough_radii)

centers = []
accums = []
radii = []

for radius, h in zip(hough_radii, hough_res):
    # For each radius, extract 5 circles
    num_peaks = 5
    peaks = peak_local_max(h, num_peaks=num_peaks)
    centers.extend(peaks)
    accums.extend(h[peaks[:, 0], peaks[:, 1]])
    radii.extend([radius] * num_peaks)

# Draw the most prominent 5 circles
image = color.gray2rgb(image)
for idx in np.argsort(accums)[::-1][:]:
    center_x, center_y = centers[idx]
    radius = radii[idx]
    cx, cy = circle_perimeter(center_y, center_x, radius)
    image[cy, cx] = (220, 20, 20)

ax.imshow(image, cmap=plt.cm.gray)

笔记本(带结果):https://gist.github.com/groakat/0e04d10a08fc05bff7e1

在Matlab中它应该像

I = imread('test.jpeg');

BW1 = edge(I,'Canny');

[centers, radii, metric] = imfindcircles(BW1,[10 15]);

centersStrong5 = centers(1:5,:);
radiiStrong5 = radii(1:5);
metricStrong5 = metric(1:5);


imshow(I)
viscircles(centersStrong5, radiiStrong5,'EdgeColor','b');