는 또한 imfindcircles
를 통해 Circular Hough Transform을 제안 할 수 있습니다. 그러나 적어도 R2012a 버전이 필요합니다. 따라서 R2012a 버전이 없으면 작동하지 않습니다.
완벽을 기하기 위해, 내가 가지고 있다고 가정하겠습니다. 이미지를 그대로 놔두고 싶다면 좋은 방법입니다. Hough Transform이 무엇인지 모르는 경우 이미지에서 직선을 찾는 방법입니다. circular Hough Transform은 이미지에서 원을 찾는 것을 목표로하는 특별한 경우입니다.
원형 Hough Transform의 추가 된 장점은 이미지의 부분 원을 감지 할 수 있다는 것입니다. 즉, 이미지에서 연결되어있는 영역을 별도의 원으로 감지 할 수 있습니다.
[centers,radii] = imfindcircles(A, radiusRange);
A
객체의 바이너리 이미지 것, 그리고 radiusRange
는 탐지 할 원의 최소 및 최대 반경을 지정하는 두 가지 요소의 배열입니다 : 당신은 어떻게 imfindcircles
전화 거라고하면 다음과 같은 방식이다 당신의 이미지에서. 출력은 :
centers
: 당신은 이미지에서 검출되는 각각의 원의 중심 좌표 (x,y)
알려주는 N x 2
어레이 - x
컬럼 인 및 y
가 로우 인.
radii
: 감지 된 각 해당 센터에 대해 감지 된 각 원의 반경도 제공합니다. 이것은 N x 1
배열입니다.
Sensitivity
과 같이 유용 할 수있는 imfindcircles
의 추가 매개 변수가 있습니다. 민감도가 높으면 이미지에 표시되는 것과 같이 더 균일하지 않은 원형 모양을 감지 할 수 있습니다. 그들은 완벽한 원형이 아니지만 둥근 모양입니다. 기본 감도는 0.85입니다. 좋은 결과를 얻으려면 0.9로 설정합니다. 또한 이미지를 가지고 노는 것은 반경이 50 픽셀에서 150 픽셀 사이 인 것을 발견했습니다. 그러므로 나는 이것을했다 :
im = im2bw(imread('http://dennlinger.bplaced.net/t06-4.jpg'));
[centers,radii] = imfindcircles(im, [50 150], 'Sensitivity', 0.9);
첫 번째 코드 행은 StackOverflow에서 직접 이미지를 읽는다. 업로드 한 이미지가 uint8
이므로이 값을 logical
또는 검은 색과 흰색으로 변환하십시오. 이 이미지는 im
에 저장됩니다. 다음으로 우리가 설명한 방법으로 imfindcircles
이라고 부릅니다.
이제 감지 된 원을 시각화하려면 imshow
을 사용하여 이미지를 표시 한 다음 viscircles
을 사용하여 이미지에서 원을 그립니다. 기본적으로
imshow(im);
viscircles(centers, radii, 'DrawBackgroundCircle', false);
viscircles
는 윤곽 이상 흰색 배경으로 원을 그립니다. 이미지에 흰색 원이 있고 허위 컨투어링을 표시하고 싶지 않기 때문에이 기능을 사용하지 않으려합니다. 이것은 내가 위의 코드로 무엇을 얻을 수 있습니다 :
따라서, 당신이 떨어져이 걸릴 수 있습니다 무엇 centers
및 radii
변수입니다. centers
은 감지 된 각 원의 중심을 제공하며 radii
은 각 원의 반지름을 알려줍니다. 당신이 regionprops
이 무엇을하는지 시뮬레이션하려면
이제, 우리는 발견의 모든 서클을 반복하고 물리적으로 원이 ID 번호가 표시 될 2 차원지도에 그들을 그릴 수 있습니다.따라서, 우리는 같은 것을 할 수 있습니다
[X,Y] = meshgrid(1:size(im,2), 1:size(im,1));
IDs = zeros(size(im));
for idx = 1 : numel(radii)
r = radii(idx);
cen = centers(idx,:);
loc = (X - cen(1)).^2 + (Y - cen(2)).^2 <= r^2;
IDs(loc) = idx;
end
우리는 먼저 meshgrid
를 사용하여 점의 직사각형 그리드를 정의하고 이미지와 동일한 크기 모두 0의 ID를 배열을 초기화합니다. 다음으로, 각 원의 반경과 각 원에 대해이 점의 중심에 지정된 원을 정의합니다.이 원은 주어진 반경에 대해 확장됩니다. 그런 다음 이들을 ID 배열의 위치로 사용하고 해당 특정 원에 대한 고유 ID로 설정합니다. IDs
의 결과는 bwlabel
의 출력과 비슷합니다. 당신이 idx
원 곳의 위치를 추출 할 경우 따라서, 당신은 할 것 :
데모 목적을 위해
cir = IDs == idx;
, 이것은 우리가 ID를 확장하면 그것은 내 맞도록 같은 ID를 배열 모습입니다 공개하는 범위 [0-255]
그러므로
imshow(IDs, []);
회색의 서로 다른 음영의 각각의 음영 원,617,869,248 검출 된 고유 원을 나타내고.
그러나 회색으로 된 음영은 배경에 혼합되어 특정 동전에 약간 모호합니다. 우리가 시각화 할 수있는 또 다른 방법은 ID 배열에 다른 색상 맵을 적용하는 것입니다. cool
색상 맵을 사용하여 총 색상 수를 배경의 고유 서클 +1에 사용할 수 있습니다. 따라서, 우리는 같은 것을 할 수 있습니다
cmap = cool(numel(radii) + 1);
RGB = ind2rgb(IDs, cmap);
imshow(RGB);
위의 코드는 각 원은 cool
컬러 맵에 고유 한 색상에 매핑됩니다 있도록 컬러 맵을 생성합니다. 다음 줄은 각 ID가 ind2rgb
인 색과 연관되는 매핑을 적용하고 마지막으로 이미지를 표시합니다.
imfindcircles는 이미지 처리 도구 상자의 일부입니다. –
빠른 답변에 감사드립니다. 나는 그 기능을 발견했고 그것은 꽤 우아한 방법이라고 생각한다. 한 가지 더 간단한 질문이 남아 있습니다. 이제 연결된 구성 요소에 레이블을 지정하려고하므로 연결된 모든 구성 요소에 원의 모든 픽셀을 추가하고 싶습니다. 이것을 어떻게 할 수 있습니까? – dennlinger
나는 (지금 당장) 나는 여백보다 큰 모든 흰색 영역을 연결된 구성 요소 (bwconncomp)에 간단하게 추가하고 단순히 잘못 인식 된 동전을 나누거나 편집하려고한다고 덧붙여 야합니다. – dennlinger