Gürültülü Görüntü Verilerinde Bir Dairenin Saptanması


17

Aşağıdaki gibi görünen bir görüntü var: resim açıklamasını buraya girin

Dairenin yarıçapını (veya çapını) bulmaya çalışıyorum. Dairesel Hough dönüşümü (matlab ile imfindcircles(bw,[rmin rmax],'ObjectPolarity','bright')) kullanarak ve bir daire veya bir elips (daha az gürültülü veriler için oldukça iyi çalışan ev yapımı fonksiyona uyarak) denedim .

Ayrıca, daha net bir daire elde etmek için bazı görüntü işleme denedim, örneğin, aşağıya bakın:

se = strel('disk', 2);
bw = imdilate(bw, se);
bw = bwareaopen(bw,100000); 
bw =  edge(bw); 

resim açıklamasını buraya girin

Ancak, işlenen görüntüyü her iki tekniğe de (Hough ve circle \ ellipse fitting) beslediğimde, ikisi de daireyi iyi bir şekilde algılamayı başaramaz.

İşte yazdığım daire bulucunun kod pasajı (matlab) [row col] = find (bw); kontur = bwtraceboundary (bw, satır (1), sütun (1)], 'N', bağlantı, sayı_ noktaları);

    x = contour(:,2);
    y = contour(:,1);

    % solve for parameters a, b, and c in the least-squares sense by
    % using the backslash operator
    abc = [x y ones(length(x),1)] \ -(x.^2+y.^2);
    a = abc(1); b = abc(2); c = abc(3);

    % calculate the location of the center and the radius
    xc = -a/2;
    yc = -b/2;
    radius  =  sqrt((xc^2+yc^2)-c);

Alternatif yaklaşımlar takdir edilecektir ...


Hough dönüşümü dolu bir disk değil, bir daire arar. dolu diski boş bir daireye dönüştürmek için önce kenar algılaması yapmanız gerekir. çevrelerinizin özellikleri nelerdir? boyut sabit mi? elips olabilirler mi? noktalar farklı şekilde dağıtılabilir mi?
endolith

Denedim (düzenlenmiş örneğe bakın), çok gürültülü veya yeterince dairesel değil mi? Ek olarak, boyut sabittir ve kamera açısı hatası nedeniyle küçük eliptikliğe sahip olabilir (gerçekte mükemmel dairesel bir pencere olsa da).
bla

boyut ve şekil sabitse, dolu bir disk şablonunun orijinal nokta görüntüsü ile çapraz korelasyonu gibi bir şey deneyebilirsiniz
endolith

Cevabımın yanında, bunu görüntü işleme borunuzun çok daha sonraki bir aşamasında yapmaya çalışıyor olabileceğinizi düşünüyorum. Bize sorun hakkında daha fazla bilgi verebilir ve önceki adımları gösterebilir misiniz?
Andrey Rubshtein

Yanıtlar:


13

İşte benim çözümüm, @ Yoda'nın fikrine yakın, ama bazı adımları değiştirdim.

  • Tüm pikselleri 7x7 mahallelerinde en az 6 piksel olacak şekilde işaretleyin
  • Tüm lekeleri çıkarın, ancak en büyüğü
  • Delikleri doldurun
  • Kenar algılamayı uygula
  • Hough dönüşümünü kullanarak çevre bulma

resim açıklamasını buraya girin resim açıklamasını buraya girin resim açıklamasını buraya girin resim açıklamasını buraya girin resim açıklamasını buraya girin

İlgili Matlab kodu. Kodumda daireler .m dosyası için Hough dönüşümü kullanıyorum .

function FindCircle()
    close all;
    im = imread('C:\circle.png');
    im = im(:,:,2);

    ims = conv2(double(im), ones(7,7),'same');
    imbw = ims>6;
    figure;imshow(imbw);title('All pixels that there are at least 6 white pixels in their hood');

    props = regionprops(imbw,'Area','PixelIdxList','MajorAxisLength','MinorAxisLength');
    [~,indexOfMax] = max([props.Area]);
    approximateRadius =  props(indexOfMax).MajorAxisLength/2;

    largestBlobIndexes  = props(indexOfMax).PixelIdxList;
    bw = false(size(im));
    bw(largestBlobIndexes) = 1;
    bw = imfill(bw,'holes');
    figure;imshow(bw);title('Leaving only largest blob and filling holes');
    figure;imshow(edge(bw));title('Edge detection');

    radiuses = round ( (approximateRadius-5):0.5:(approximateRadius+5) );
    h = circle_hough(edge(bw), radiuses,'same');
    [~,maxIndex] = max(h(:));
    [i,j,k] = ind2sub(size(h), maxIndex);
    radius = radiuses(k);
    center.x = j;
    center.y = i;

    figure;imshow(edge(bw));imellipse(gca,[center.x-radius  center.y-radius 2*radius 2*radius]);
    title('Final solution (Shown on edge image)');

    figure;imshow(im);imellipse(gca,[center.x-radius  center.y-radius 2*radius 2*radius]);
    title('Final solution (Shown on initial image)');

end

1
Hough dönüşümü, mavi daireyi çözmesini ve bulmasını sağlayan ne yapıyor? Görüntüdeki farklı konumlara farklı yarıçaplı birçok daire yansıtıyor ve en uygun olanı mı buluyor?
Spacey

@Mohammad, olağan daire dedektörüdür. Binning ve oylama kullanır.
Andrey Rubshtein

Bu cevabın ilk adımından sonra Hızlı Radyal Simetri Dönüşümünü (FRST) de kullanabilirsiniz.
Geniedesalpages

10

Görüntü işleme kullanarak bunu yapmak oldukça basittir. Aşağıdakiler Mathematica'da bir kavram kanıtıdır . Bunu MATLAB'a çevirmeniz gerekecek.

  • İlk olarak, eksenleri kırpın ve sadece görüntünün bir kısmını tutun. Ben bu değişkeni diyorum img.
  • Görüntüyü ikileştirin ve genişletin, ardından bir dolgu dönüşümü yapın. Ayrıca, ana bloba bağlı olmayan başıboş küçük bileşenleri de çıkarıyorum. Size aşağıdaki gibi bir şey vermelidir:

    filled = Binarize@img ~Dilation~ 3 // FillingTransform // DeleteSmallComponents
    

  • Daha sonra, bu blobun centroidini ve blobun eşdeğer disk yarıçapını bulun (openCV, MATLAB, bunu yapmak için eşdeğer komutlara sahiptir)

    {center, radius} = 1 /. ComponentMeasurements[filled, {"Centroid", "EquivalentDiskRadius"}]
    
  • Bu kadar! Şimdi orijinal görüntüyü ve üst ortası ve yarıçapı olan bir daireyi nasıl oturduğunu görmek için çizin:

    Show[img, Graphics[{Red, Circle[center, radius]}]]
    


Müthiş cevap! Genişletme ve doldurma dönüşümünü genişletebilir misiniz?
Spacey

@Mohammad Dilatasyon temel işlemdir ve kolayca wiki makalesi ile açıklanabilir olacaktır. Dönüşüm doldurma, "deliklere" veya başka bir deyişle, daha yüksek değerli piksellerle çevrili piksel kümelerine doldurur. Burada
Lorem Ipsum

Ah üzgünüm, yanlış yazdım. Dilatasyon dönüşümüne biraz aşinayım, aslında 'doldurma dönüşümü'nü genişletip genişletemeyeceğinizi merak ediyordum. Tam olarak hangi kural setini kullanıyor? Bununla ilgili bilgi bulamıyorum. Belki başka bir isimle gidiyor?
Spacey

@yoda, cevabınız için teşekkür ederim, ama soruyu okursanız genişlemeyi denedim ve uydurduğumu fark ettiniz. Kenarları algılamadan önce oluşturulan görüntü sizinkine benzer. Biraz uyum sağladım, doğru değil. Aynı şey uyumunuz için, takılan dairenin üst kısmının çok büyük olduğunu görebilirsiniz, çünkü muhtemelen dairenin üst kısmındaki gürültülü noktayı dikkate alırsınız. Ayrıca (soruda belirtildiği gibi) bir elips takmaya çalıştım, sorun, uyumun yeterince iyi olmaması. Bence daha iyi bir yol, çemberin daha iyi bir kısmını (yay) kullanmaktır.
bla

@nate "Takılı dairenin üst kısmı" ve "dairenin daha iyi kısmı" ile ne demek istediğinizi anlamıyorum. Farklı metrikler kullanabilirsiniz ... sınırlayıcı kutu, ana eksen uzunluğu, küçük eksen uzunluğu, centroidden ortalama mesafe, centroidden ortalama mesafe, vb. Her şey ne istediğinize bağlıdır.
Lorem Ipsum
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.