Görüntüdeki simetrik bölgeleri / desenleri bulma


14

Bir insan arka yüzeyinin ortalama eğriliğini temsil eden bir dizi görüntüm var.

Yapmak istediğim görüntüyü, görüntünün başka bir bölümünde benzer, yansıyan "muadilleri" olan noktalar için "taramak" (büyük olasılıkla orta hatta simetriktir, ancak mutlaka deformiteler olabileceğinden). Bazı görüntü dikiş teknikleri, görüntüler arasındaki benzer noktaları "otomatik olarak algılamak" için bunu kullanır, ancak bunları aynı görüntünün her iki tarafı için de algılamak istiyorum.

Nihai amaç, simetrik "yarıya" uyarlanabilir şekilde arkaya bölünen sürekli, büyük olasılıkla kavisli, uzunlamasına bir çizgi bulmaktır.

Aşağıda örnek bir görüntü bulunmaktadır. Tüm bölgelerin simetrik olmadığına dikkat edin (özellikle görüntünün merkezinin hemen üzerinde kırmızı dikey "şerit" sağa doğru sapar). Bu bölge kötü bir puan almalı ya da her neyse, ama sonra yerel simetri, daha uzağa yerleştirilmiş simetrik noktalardan tanımlanacaktır. Her durumda, herhangi bir algoritmayı uygulama alanma uyarlamak zorunda kalacağım, ama peşimde olduğum şey bir korelasyon / evrişim / kalıp eşleştirme stratejisidir, bence etrafta bir şeyler olmalı.

(DÜZENLE: aşağıda daha fazla resim ve biraz daha açıklama var)

resim açıklamasını buraya girin

EDIT: istendiği gibi, iyi davranışlı ve sorunlu daha tipik görüntüler dahil edeceğim. Ancak, renk eşlemeli görüntüler yerine, bunlar gri tonlamalı görüntülerdir, böylece renk, doğrudan renkli görüntü ile gerçekleşmeyen veri iletişimiyle ilgilidir (yalnızca iletişim için sağlanır). Gri görüntüler, renkli görüntülerle karşılaştırıldığında kontrastsız gibi görünse de, veri gradyanları oradadır ve istenirse bazı uyarlanabilir kontrast ile ortaya çıkarılabilir.


1) Çok simetrik bir konunun görüntüsü:

resim açıklamasını buraya girin


2) Aynı konunun farklı bir anda görüntüsü. Daha fazla "özellik" (daha fazla degradeler) olmasına rağmen, daha önce olduğu kadar simetrik "hissetmez":

resim açıklamasını buraya girin


3) Orta hatta daha yaygın içbükey orta hat yerine dışbükeylikleri (daha hafif bölgelerle gösterilen kemik çıkıntıları) olan ince bir genç konu:

resim açıklamasını buraya girin


4) Omurga sapması olan X-Ray ile genç bir kişi (asimetrilere dikkat edin):

resim açıklamasını buraya girin


5) Tipik "eğimli" nesne (çoğunlukla kavisli orta hat çevresinde simetrik olmasına ve düzgün bir şekilde "deforme" olmamasına rağmen):

resim açıklamasını buraya girin


Herhangi bir yardım çok açığız!


Neden sadece omurgayı bölücü olarak kullanmıyorsunuz?
Jim Clay

@JimClay: Ben omurga görüntü geri kalanının simetri gerçek eksenine göreli ölçülen kısmı şüpheli
Endolit

"Bazı görüntü dikiş teknikleri bunu, görüntüler arasındaki benzer noktaları" otomatik olarak algılamak "için kullanır. Görüntünün ters çevrilmiş bir kopyasını oluşturun ve sonra bunlardan birini kullanın. :)
endolith

Görüntüyü Y ekseni boyunca yansıtıp kayıt algoritması kullanamaz mısınız? Çünkü esnek / parametrik olmayan kayıt algoritmaları üzerine inşa edebileceğiniz çok sayıda araştırma var.
Niki Estner

JimClay, omurga bulmak istediğim şey, nerede olduğunu bilmiyorum; Endolith, sorum bana bu algoritmalardan bazılarının isimlerini söylemeyi içeriyor, henüz bulamadım. Ve Nikie, bütün mesele bu, ama bu algoritmaların hiçbirini BİLMİYORUM, bu yüzden ilk etapta soruyu soruyorum: o)
heltonbiker

Yanıtlar:


9

Yorumlarda söylediğim gibi, tıbbi görüntü kaydı birçok araştırmanın mevcut olduğu bir konudur ve ben uzman değilim. Okuduğum kadarıyla, yaygın olarak kullanılan temel fikir, iki görüntü (sizin durumunuzda bir görüntü ve ayna görüntüsü) arasında bir eşleme tanımlamak, ardından eşleme uygulanırsa pürüzsüzlük ve görüntü benzerliği için enerji terimlerini tanımlamak ve son olarak standart (veya bazen uygulamaya özgü) optimizasyon tekniklerini kullanarak bu eşlemeyi optimize edin.

Bunu göstermek için Mathematica'da hızlı bir algoritmayı hackledim. Bu, tıbbi bir uygulamada kullanmanız gereken bir algoritma değil , sadece temel fikirlerin bir gösterisidir.

İlk olarak, görüntünüzü yüklüyorum, yansıtıyorum ve bu görüntüleri küçük bloklara ayırıyorum:

src = ColorConvert[Import["http://i.stack.imgur.com/jf709.jpg"], 
   "Grayscale"];
mirror = ImageReflect[src, Left -> Right];
blockSize = 30;
partsS = ImagePartition[src, {blockSize, blockSize}];
partsM = ImagePartition[mirror, {blockSize, blockSize}];
GraphicsGrid[partsS]

Mathematica grafikleri

Normalde, yaklaşık bir katı kayıt yapardık (örneğin, anahtar noktaları veya görüntü anları kullanarak), ancak görüntünüz neredeyse ortalanmış, bu yüzden bunu atlayacağım.

Bir bloğa bakarsak ve bu ayna görüntüsü muadili ise:

{partsS[[6, 10]], partsM[[6, 10]]}

Mathematica grafikleri

Benzer olduklarını görebiliyoruz, ama değişti. Vardiya miktarı ve yönü bulmaya çalıştığımız şeydir.

Eşleşme benzerliğini ölçmek için, kareli öklid mesafesini kullanabilirim:

ListPlot3D[
  ImageData[
   ImageCorrelate[partsM[[6, 10]], partsS[[6, 10]], 
    SquaredEuclideanDistance]]]

Mathematica grafikleri

ne yazık ki, bu verileri kullanarak optimizasyon doğrudan düşündüğümden daha zordu, bu yüzden bunun yerine 2. dereceden bir yaklaşım kullandım:

fitTerms = {1, x, x^2, y, y^2, x*y};

fit = Fit[
   Flatten[MapIndexed[{#2[[1]] - blockSize/2, #2[[2]] - 
        blockSize/2, #1} &, 
     ImageData[
      ImageCorrelate[partsM[[6, 10]], partsS[[6, 10]], 
       SquaredEuclideanDistance]], {2}], 1], fitTerms, {x, y}];

Plot3D[fit, {x, -25, 25}, {y, -25, 25}]

Mathematica grafikleri

İşlev, gerçek korelasyon işleviyle aynı değildir, ancak ilk adım için yeterince yakındır. Bunu her blok çifti için hesaplayalım:

distancesFit = MapThread[
   Function[{part, template},
    Fit[Flatten[
      MapIndexed[{#2[[2]] - blockSize/2, #2[[1]] - blockSize/2, #1} &,
        ImageData[
        ImageCorrelate[part, template, 
         SquaredEuclideanDistance]], {2}], 1], 
     fitTerms, {x, y}]], {partsM, partsS}, 2];

Bu bize optimizasyon için ilk enerji terimimizi verir:

variablesX = Array[dx, Dimensions[partsS]];
variablesY = Array[dy, Dimensions[partsS]];

matchEnergyFit = 
  Total[MapThread[#1 /. {x -> #2, y -> #3} &, {distancesFit, 
     variablesX, variablesY}, 2], 3];

variablesX/Yher blok için ofsetleri içerir ve matchEnergyFitorijinal görüntü ile yansıtılan görüntü arasındaki kareli öklid farkını, ofsetler uygulayarak yaklaşık olarak gösterir.

Bu enerjiyi tek başına optimize etmek kötü sonuçlar verir (hiç yakınsa). Ayrıca, ofsetlerin pürüzsüz olmasını istiyoruz, burada blok benzerliği ofset hakkında hiçbir şey söylemez (örneğin düz bir çizgi boyunca veya beyaz arka planda).

Böylece pürüzsüzlük için ikinci bir enerji terimi belirledik:

smoothnessEnergy = Total[Flatten[
    {
     Table[
      variablesX[[i, j - 1]] - 2 variablesX[[i, j]] + 
       variablesX[[i, j + 1]], {i, 1, Length[partsS]}, {j, 2, 
       Length[partsS[[1]]] - 1}],
     Table[
      variablesX[[i - 1, j]] - 2 variablesX[[i, j]] + 
       variablesX[[i + 1, j]], {i, 2, Length[partsS] - 1}, {j, 1, 
       Length[partsS[[1]]]}],
     Table[
      variablesY[[i, j - 1]] - 2 variablesY[[i, j]] + 
       variablesY[[i, j + 1]], {i, 1, Length[partsS]}, {j, 2, 
       Length[partsS[[1]]] - 1}],
     Table[
      variablesY[[i - 1, j]] - 2 variablesY[[i, j]] + 
       variablesY[[i + 1, j]], {i, 2, Length[partsS] - 1}, {j, 1, 
       Length[partsS[[1]]]}]
     }^2]];

Neyse ki, Mathematica'da kısıtlı optimizasyon yerleşiktir:

allVariables = Flatten[{variablesX, variablesY}];
constraints = -blockSize/3. < # < blockSize/3. & /@ allVariables;
initialValues = {#, 0} & /@ allVariables;
solution = 
  FindMinimum[{matchEnergyFit + 0.1 smoothnessEnergy, constraints}, 
   initialValues];

Sonuca bakalım:

grid = Table[{(j - 0.5)*blockSize - dx[i, j], (i - 0.5)*blockSize - 
      dy[i, j]}, {i, Length[partsS]}, {j, Length[partsS[[1]]]}] /. 
   solution[[2]];
Show[src, Graphics[
  {Red,
   Line /@ grid,
   Line /@ Transpose[grid]
   }]]

Mathematica grafikleri

Önceki 0.1faktör smoothnessEnergy, pürüzsüzlük enerjisinin görüntü eşleme enerji terimi ile ilişkili olarak aldığı nispi ağırlıktır. Bunlar farklı ağırlıklar için sonuçlardır:

Mathematica grafikleri

Olası iyileştirmeler:

  • Dediğim gibi, önce katı bir kayıt yapın. Beyaz bir arka plan ile, basit görüntü anları tabanlı kayıt iyi çalışmalıdır.
  • Bu sadece bir adım. Bulduğunuz ofsetleri bir adımda kullanabilir ve ikinci bir adımda iyileştirebilirsiniz, belki daha küçük bir arama penceresi veya daha küçük blok boyutları ile
  • Bunu hiç bloklar olmadan yaptıkları makaleleri okudum, ancak piksel başına bir ofseti optimize ettim.
  • Farklı pürüzsüzlük işlevlerini deneyin

cevap sadece eğlence için okumak için çok uzun, ama son görüntü oldukça gösterge niteliğindedir: şaşırtıcı görünüyor: D
penelope

Bu cevap çok aydınlatıcıydı. Yutmak için biraz zamana ihtiyacım olacak, ama muhtemelen katı olmayan kayıt tekniği kullanmam gerekecek. Neyse ki bazı kavramsal detaylar sağladınız, bu yüzden en kötü durumda benzer bir yaklaşım bulabilirim. Bu arada soruyu daha fazla resimle güncelleyeceğim. Şimdilik teşekkürler!
heltonbiker

4

İlginç soru. İlk olarak, belki de ilgi kilit nokta dedektörü ve eşleştirmeye dayalı yaklaşımlardan sonrasınız. Bu, SIFT (Ölçek Değişmez Özellik Dönüşümü), SURF, ORB, vb ... veya sadece Harris operatörüne (csce.uark.edu/~jgauch/library/Features/Harris.1988.pdf) dayanan daha basit bir yaklaşımı içerir. ). Ne denediğini açık değil, bu yüzden burada naif olduğum için üzgünüm.

Dedi ki, sadece eğlence için Matematiksel Morfoloji (MM) ile daha basit bir yaklaşım alalım :) Tüm adımların görselleştirme için görüntüler sonunda.

Örnek resminizi alıp ImageMagick kullanarak L a b * colorspace'e dönüştürdüm ve sadece L * bandını kullandım:

convert x.jpg -colorspace Lab -separate %d.png

0.png L * bandına karşılık gelir. Şimdi, gerçek görüntü verileri var eminim, ama jpg sıkıştırma eserler ve ne ile ilgileniyorum. Bu sorunu kısmen ele almak için, morfolojik bir açıklık ve ardından yarıçap 5'in düz bir diski ile morfolojik bir kapanma gerçekleştirdim. Bu, MM ile gürültüyü azaltmanın temel bir yoludur ve disk yarıçapı görüntünün büyük bir kısmının değişmediği göz önüne alındığında. Daha sonra fikrim, diğer davalar için başarısız olma şansı yüksek olan bu tek görüntüye dayanıyordu. İlgi alanınız daha koyu (renkli görüntünüzde "daha sıcak") ile görsel olarak ayırt edilir, bu yüzden istatistiksel olarak dayalı bir binarizerin iyi performans gösterebileceğini düşündüm. Otsu'nun otomatik olan yaklaşımını kullandım.

Bu noktada, ilgilenilen merkezi bölgeyi açıkça görselleştirmek mümkündür. Sorun şu ki, benim yaklaşımımda, kapalı bir bileşen olmasını istedim ama öyle değil. En büyük olandan daha küçük olan her bağlı bileşeni atayarak başlıyorum (arka planı bunlardan biri olarak saymamak). Eğer ikilileştirme sonucu iyi ise, bunun diğer durumlarda çalışma şansı daha yüksektir. Örnek görüntünüzde, arka plana bağlı bir bileşen vardır, bu nedenle atılmaz, ancak sorunlara neden olmaz.

Eğer hala beni takip ediyorsanız, gerçek sözde merkezi ilgi bölgesini henüz bulamadık. İşte benim almam. Kişi ne kadar kavisli olursa olsun (aslında bazı sorunlu vakaları görebiliyorum), bölge dikey bir çizgiye benziyor. Bu amaçla, dikey uzunluğu 100 olan bir morfolojik açıklık gerçekleştirerek mevcut görüntüyü basitleştiririm. Bu uzunluk tamamen keyfidir, ölçekleme sorunlarınız yoksa bu belirlemek zor bir değer değildir. Şimdi yine bileşenleri atıyoruz, ancak bu adımda biraz daha dikkatliydim. Küçük bölgeleri düşündüğüm şeyi atmak için görüntünün tamamlayıcısıyla alana göre açmayı kullandım, bu daha kontrollü bir şekilde granülometrik analiz (MM'den de) şeklinde bir şey gerçekleştirerek yapılabilir.

Şimdi kabaca üç parçamız var: görüntünün sol kısmı, orta kısmı ve görüntünün sağ kısmı. Merkezi kısmın üçün daha küçük bileşeni olması beklenir, bu yüzden önemsiz bir şekilde elde edilir.

İşte nihai sonuç, sağ alt resim, orijinali ile sadece soldaki görüntüdür. Bireysel figürlerin hepsi aynı hizada değil, acele ettiğim için üzgünüm.

http://i.imgur.com/XRhYv.png


İlginiz için çok teşekkür ederim, ancak yaklaşımınız verilerimin belirli özelliklerini göz önünde bulundurmalıdır (bir şikayet değil, sadece detaylandırma): 1) Gerçek veriler, ıraksak kırmızı-sarı ile renklendirilmiş 2B bir yüzer dizidir. Python matplotlib yeşil renk haritası. Renk verileriyle çalışmanın kavramsal olarak doğru olacağını düşünmüyorum, görüntüler sadece iletişim amaçlı gösteriliyor; 2) Gerçek veriler yüzey eğriliği (konveks ve içbükey) ile ilgilidir; kırmızı kısımlar içbükey ve yeşil kısımlar dışbükeydir. Simetrik eksen mutlaka içbükey bir bölgeye düşmez.
heltonbiker

Çok yakında biraz daha fazla görüntü ekleyeceğim (ve bunu gri tonlamalı olanlarla değiştireceğim), böylece görüntülerin kendileri test için kullanılabilir, böylece renk nedeniyle dinamik aralık bozulması tehlikesi ortadan kaldırılır.
heltonbiker

Veriler maalesef henüz mevcut değil. Gri tonlamalı görüntüler en iyi ihtimalle yaklaşık bir değerdir.
mmgp

Yaklaşmanın büyük olasılıkla yeterli olduğuna inanıyorum, ancak gerçek verileri sağlamayı umursamıyorum. Bazı genel DropBox indirme bağlantıları gönderebilirim, sadece hangi dosya biçiminde olduğunu bilmiyorum.
heltonbiker
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.