如果您拥有图像处理工具箱,则可以使用名为cornermetric的函数来实现Harris角检测器或Shi和Tomasi的最小特征值方法。该函数自MATLAB版本R2008b以来一直存在于图像处理工具箱的6.2版中。
使用此功能,我提出了与其他答案略有不同的方法。以下解决方案基于一个想法:以每个“真正”的角点为中心的圆形区域将比实际在边缘上的错误角点上方的圆形区域重叠多少。该解决方案还可以处理在同一角处检测到多个点的情况...
第一步是加载数据:
rawImage = imread('oxyjj.png');
rawImage = rgb2gray(rawImage(7:473, 9:688, :));
subplot(2, 2, 1);
imshow(rawImage);
title('Raw image');
接下来,使用
cornermetric
计算角点度量。请注意,我通过原始多边形掩蔽了角点度量,以便我们寻找在多边形内部的角点(即尝试找到多边形的角像素)。然后使用
imregionalmax
查找局部最大值。由于可能存在具有相同角点度量的大于1个像素的聚类,因此我添加噪声到极值并重新计算,以便每个极大区域只得到1个像素。然后使用
bwlabel
对每个极大区域进行标记:
cornerImage = cornermetric(rawImage).*(rawImage > 0);
maxImage = imregionalmax(cornerImage);
noise = rand(nnz(maxImage), 1);
cornerImage(maxImage) = cornerImage(maxImage)+noise;
maxImage = imregionalmax(cornerImage);
labeledImage = bwlabel(maxImage);
接下来,使用圆形结构元素(使用strel
创建)对标记区域进行膨胀操作(使用imdilate
):
diskSize = 5;
dilatedImage = imdilate(labeledImage, strel('disk', diskSize));
subplot(2, 2, 2);
imshow(dilatedImage);
title('Dilated corner points');
现在标记的角落区域已经被膨胀,它们将部分重叠原始多边形。在多边形边缘的区域将有约50%的重叠,而在角上的区域将有约25%的重叠。函数
regionprops
可用于查找每个标记区域的重叠面积,因此可以将具有最少重叠量的4个区域视为真正的角:
maskImage = dilatedImage.*(rawImage > 0);
stats = regionprops(maskImage, 'Area');
[sortedValues, index] = sort([stats.Area]);
cornerLabels = index(1:4);
maskImage = ismember(maskImage, cornerLabels);
subplot(2, 2, 3);
imshow(maskImage);
title('Regions of minimal overlap');
现在,我们可以使用find
和ismember
获取角落的像素坐标:
[r, c] = find(ismember(labeledImage, cornerLabels));
subplot(2, 2, 4);
imshow(rawImage);
hold on;
plot(c, r, 'r+', 'MarkerSize', 16, 'LineWidth', 2);
title('Corner points');
![这里输入图片描述](https://istack.dev59.com/ALvh0.webp)
以下是一个菱形区域的测试:
![这里输入图片描述](https://istack.dev59.com/oekLc.webp)
bwboundaries
输出。我认为线简化技术被提到了:) - Amro