Deteksi Lingkaran pada Data Gambar Bising

17

Saya memiliki gambar yang terlihat seperti di bawah ini: masukkan deskripsi gambar di sini

Saya mencoba menemukan jari-jari (atau diameter) lingkaran. Saya telah mencoba menggunakan circular Hough transform (via matlab's imfindcircles(bw,[rmin rmax],'ObjectPolarity','bright')), dan dengan memasang lingkaran atau elips (fungsi buatan sendiri yang berfungsi dengan baik untuk data yang kurang berisik, lihat di bawah).

Saya juga sudah mencoba beberapa pemrosesan gambar untuk mendapatkan lingkaran yang lebih jelas, misalnya, lihat di bawah:

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

masukkan deskripsi gambar di sini

Namun, ketika saya memberi makan gambar yang diproses ke teknik (pas Hough dan lingkaran \ elips) tidak satu pun dari mereka berhasil mendeteksi lingkaran dengan cara yang layak.

Berikut cuplikan kode finder lingkaran yang saya tulis (matlab) [row col] = find (bw); contour = bwtraceboundary (bw, row (1), col (1)], 'N', konektivitas, num_points);

    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);

Pendekatan alternatif akan dihargai ...

bla
sumber
Hough transform mencari lingkaran, bukan disk yang terisi. Anda harus melakukan deteksi tepi terlebih dahulu untuk mengubah cakram yang terisi menjadi lingkaran kosong. apa sajakah properti lingkaran Anda? apakah ukurannya konstan? bisakah mereka elips? dapatkah titik-titik didistribusikan secara berbeda?
endolit
Saya mencoba (lihat contoh yang diedit), apakah terlalu berisik atau, tidak cukup melingkar? Selain itu, ukurannya konstan, dan mungkin memiliki elipsisitas yang kecil (meskipun pada kenyataannya ini adalah jendela bundar sempurna) karena kesalahan sudut kamera.
bla
jika ukuran dan bentuknya konstan, Anda dapat mencoba sesuatu seperti korelasi silang dari template disk yang diisi dengan gambar titik asli
endolith
Di samping jawaban saya, saya pikir Anda mungkin mencoba melakukan ini pada tahap yang lebih lambat dari pipa pemrosesan gambar Anda. Bisakah Anda memberi tahu kami lebih lanjut tentang masalahnya, dan menunjukkan beberapa langkah sebelumnya?
Andrey Rubshtein

Jawaban:

13

Ini solusi saya, dekat dengan ide @ Yoda, tapi saya mengubah beberapa langkah.

  • Tandai semua piksel sedemikian rupa sehingga setidaknya ada 6 piksel di lingkungan 7x7 mereka
  • Hapus semua gumpalan, tapi yang terbesar
  • Isi lubang
  • Terapkan deteksi tepi
  • Temukan lingkaran menggunakan transformasi Hough

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

Berikut adalah kode Matlab yang relevan. Saya menggunakan transformasi Hough untuk file .m dalam kode saya.

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
Andrey Rubshtein
sumber
1
Apa yang dilakukan transformasi Hough di sini yang membuatnya menyelesaikan dan menemukan lingkaran biru? Apakah ini memproyeksikan banyak lingkaran jari-jari yang berbeda pada posisi yang berbeda pada gambar dan menemukan yang paling cocok?
Spacey
@Mohammad, itu adalah pendeteksi lingkaran yang biasa. Ini menggunakan binning dan voting.
Andrey Rubshtein
Anda juga dapat menggunakan Fast Radial Symmetry Transform (FRST) setelah langkah pertama dalam jawaban ini.
Geniedesalpages
10

Cukup mudah untuk melakukannya menggunakan pemrosesan gambar. Berikut ini adalah bukti konsep dalam Mathematica . Anda harus menerjemahkannya ke MATLAB.

  • Pertama, pangkas sumbu dan hanya simpan bagian gambarnya saja. Saya menyebut variabel ini img.
  • Binarize gambar dan melebarkannya, diikuti oleh transformasi pengisian. Saya juga menghapus komponen kecil yang tidak terhubung ke gumpalan utama. Seharusnya memberi Anda sesuatu seperti berikut:

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

  • Selanjutnya, cari centroid gumpalan ini dan jari-jari disk setara gumpalan (openCV, MATLAB semua memiliki perintah yang setara untuk melakukan ini)

    {center, radius} = 1 /. ComponentMeasurements[filled, {"Centroid", "EquivalentDiskRadius"}]
    
  • Itu dia! Sekarang plot gambar asli dan lingkaran dengan pusat di atas dan jari-jari untuk melihat bagaimana itu cocok:

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

Lorem Ipsum
sumber
Jawaban yang luar biasa! Bisakah Anda memperluas transformasi dilasi & pengisian?
Spacey
@Mohammad Pelebaran adalah operasi dasar dan akan mudah dijelaskan oleh artikel wiki. Mengisi mentransformasi mengisi dalam "lubang" atau dengan kata lain, set piksel yang dikelilingi oleh piksel bernilai lebih tinggi. Lihat bagian "Informasi lebih lanjut" di sini
Lorem Ipsum
Ah maaf, saya salah mengetik. Saya agak akrab dengan transformasi pelebaran, saya benar-benar bertanya-tanya apakah Anda dapat memperluas pada 'pengisian transformasi'. Aturan apa yang digunakan dengan tepat? Sepertinya saya tidak dapat menemukan informasi yang berkaitan dengan itu. Mungkin itu dengan nama lain?
Spacey
@Yoda, terima kasih atas jawabannya, tetapi jika Anda membaca pertanyaan Anda akan melihat saya sudah mencoba pelebaran, dan pas. Gambar yang dihasilkan sebelum saya mendeteksi tepi mirip dengan milik Anda. Saya mendapatkan beberapa fit, itu tidak akurat. Hal yang sama sesuai untuk Anda, Anda dapat melihat bahwa bagian atas lingkaran yang dipasang terlalu besar, mungkin karena Anda memperhitungkan titik bising pada bagian atas di atas lingkaran. Saya juga mencoba mencocokkan elips (seperti yang dinyatakan dalam pertanyaan), masalahnya adalah bahwa kecocokannya tidak cukup baik. Saya pikir mungkin cara yang lebih baik adalah dengan menggunakan bagian yang lebih baik dari lingkaran (busur) untuk melakukan fit.
bla
@nate Saya tidak mengerti apa yang Anda maksud dengan "bagian atas lingkaran yang pas" dan "bagian yang lebih baik dari lingkaran". Anda dapat menggunakan metrik yang berbeda ... kotak pembatas, panjang sumbu utama, panjang sumbu minor, jarak rata-rata dari centroid, jarak median dari centroid, dll. Semuanya tergantung pada apa yang Anda inginkan.
Lorem Ipsum