我有一个图像。我想检测我用红线标记的四个孔。
我在下面的链接中有所有图片。 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()
中精确调整了灵敏度和半径,但我仍然无法检测到所有圆圈。
如果你能给我一些解决这个问题的想法,我将不胜感激。
由于
答案 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');