Görüntü İşleme: 'Coca-Cola Can' Tanıma için Algoritma İyileştirme


1658

Son birkaç yıldır üzerinde çalıştığım en ilginç projelerden biri, görüntü işleme ile ilgili bir projeydi . Amaç, Coca-Cola 'kutularını' tanıyabilmek için bir sistem geliştirmekti ('kutu' kelimesini vurguladığımı, neden bir dakika içinde göreceğinizi unutmayın). Aşağıda, yeşil dikdörtgende ölçek ve döndürme ile tanınan kutuyla birlikte bir örnek görebilirsiniz .

Şablon eşleme

Projeyle ilgili bazı kısıtlamalar:

  • Arka plan çok gürültülü olabilir.
  • Kutu herhangi biri olabilir ölçeği ya da dönme (makul sınırlar içinde) ya da yönlendirme.
  • Görüntünün bir dereceye kadar bulanıklığı olabilir (konturlar tamamen düz olmayabilir).
  • Orada görüntüde Coca-Cola şişeleri olabilir ve algoritma sadece algılamalıdır kutu !
  • Görüntünün parlaklığı çok değişebilir (bu nedenle renk algılamaya "çok fazla" güvenemezsiniz).
  • Kutu kısmen yanlarındaki veya ortadan gizli ve muhtemelen kısmen şişenin arkasına gizlenebilir.
  • Resimde hiç kutu olamaz , bu durumda hiçbir şey bulamazsınız ve bunu söyleyen bir mesaj yazmalısınız.

Böylece böyle zor şeyler ile sonuçlanabilir (bu durumda algoritmam tamamen başarısız oldu):

Toplam başarısız

Bu projeyi bir süre önce yaptım ve bunu yaparken çok eğlendim ve iyi bir uygulama yaptım. Uygulamamla ilgili bazı ayrıntılar:

Dil : C ++ ile OpenCV kütüphanesi kullanılarak yapılır.

Ön işleme : Görüntü ön işleme için, yani görüntüyü algoritmaya vermek için daha ham bir forma dönüştürmek için 2 yöntem kullandım:

  1. Renk alanını RGB'den HSV'ye değiştirmek ve "kırmızı" tonu, turuncuya benzer renkleri önlemek için belirli bir eşiğin üzerinde doygunluğu ve koyu tonları önlemek için düşük değeri filtrelemek temelinde filtreleme yapmak. Sonuçta, tüm beyaz piksellerin bu eşikle eşleşen pikselleri temsil ettiği ikili siyah beyaz bir görüntü elde edildi. Açıkçası görüntüde hala çok fazla bok var, ancak bu, çalışmak zorunda olduğunuz boyut sayısını azaltır. İkili görüntü
  2. Gürültüyü azaltmak için medyan filtreleme (tüm komşuların medyan piksel değerini alarak ve pikseli bu değerle değiştirin) kullanarak gürültü filtreleme.
  3. 2 emsal adımdan sonra tüm öğelerin konturlarını elde etmek için Canny Kenar Algılama Filtresi'ni kullanma . Kontur algılama

Algoritma : Bu görev için seçtiğim algoritma , özellik çıkarma hakkındaki bu harika kitaptan alındı ve Genelleştirilmiş Hough Dönüşümü (normal Hough Dönüşümü'nden oldukça farklı) olarak adlandırıldı. Temelde birkaç şey söylüyor:

  • Uzayda bir nesneyi, analitik denklemini bilmeden tanımlayabilirsiniz (burada durum budur).
  • Görüntünüzü temel olarak her ölçek faktörü ve döndürme faktörü kombinasyonu için test edeceğinden, ölçekleme ve döndürme gibi görüntü deformasyonlarına karşı dayanıklıdır.
  • Algoritmanın "öğreneceği" bir temel model (şablon) kullanır.
  • Kontur görüntüsünde kalan her piksel, modelden öğrendiklerine dayanarak nesnenizin merkezi (yerçekimi açısından) olacağı düşünülen başka bir piksel için oy kullanacaktır.

Sonunda, oyların bir ısı haritası ile sonuçlanırsınız, örneğin burada kutunun konturunun tüm pikselleri yerçekimi merkezi için oy verecek, böylece aynı pikselde çok sayıda oyunuz olacak. ve ısı haritasında aşağıdaki gibi bir tepe göreceksiniz:

GHT

Bunu yaptıktan sonra, basit bir eşik tabanlı sezgisel tarama, size ölçek ve dönüşü türetebileceğiniz ve daha sonra küçük dikdörtgeni etrafınıza çizebileceğiniz merkez pikselin konumunu verebilir (son ölçek ve dönüş faktörü açıkça orijinal şablon). Teoride en azından ...

Sonuçlar : Şimdi, bu yaklaşım temel vakalarda çalışırken, bazı alanlarda ciddi bir şekilde eksikti:

  • Son derece yavaş ! Bunu yeterince vurgulamıyorum. 30 test görüntüsünü işlemek için neredeyse tam bir gün gerekiyordu, çünkü bazı kutular çok küçük olduğu için rotasyon ve çeviri için çok yüksek bir ölçeklendirme faktörüne sahiptim.
  • Şişeler görüntüde olduğunda tamamen kayboldu ve bir nedenden dolayı neredeyse her zaman şişeyi kutu yerine buldular (belki de şişeler daha büyük olduğundan, daha fazla piksele sahipti, bu yüzden daha fazla oy verildi)
  • Bulanık görüntüler de iyi değildi, çünkü oylar merkezdeki rastgele yerlerde piksel olarak sona erdi, böylece çok gürültülü bir ısı haritası ile sona erdi.
  • Çeviri ve döndürmede varyans elde edildi, ancak yönelimde değil, yani doğrudan kamera hedefine bakmayan bir kutunun tanınamadığı anlaşıldı.

Eğer bana iyileştirmeye yardımcı olabilir spesifik kullanarak algoritma OpenCV münhasıran çözmek için, özellikleri dört özel bahsedilen sorunlar?

Umarım bazı insanlar da ondan bir şeyler öğrenir, sonuçta sadece soru soranların değil öğrenmesi gerektiğini düşünüyorum. :)


45
Bu sorunun dsp.stackexchange.com veya stats.stackexchange.com adresinde daha uygun olduğu söylenebilir ve kesinlikle bu sitelerde de yeniden sormayı düşünmelisiniz.
ely

49
Burada yapılacak ilk şey , farklı başarısızlık vakalarının neden olduğunu analiz etmektir. Örneğin, şişelerin kazandığı, görüntülerin bulanık olduğu yerlerin örneklerini izole edin ve Hough gösterimleri ile algılamasını istedikleri arasındaki farkı öğrenmek için bazı istatistiksel analizler yapın. Alternatif yaklaşımlar hakkında bilgi edinmek için bazı harika yerler burada ve burada
ely

7
@stacker iyi bir noktaya değiniyor. Hız için, yönlendirilmiş gradyanların histogramları gibi hesaplaması ucuz olan özelliklere sahip olmak istersiniz. Gerçekten naif bir ilk yaklaşım, bazı eğitim görüntülerinde bir grup kutu dikdörtgenini manuel olarak etiketlemek ve bu artı rastgele negatif örnekleri bir SVM veya karar ağacı sınıflandırıcısını eğitmek için kullanmak olacaktır. Eğitim daha uzun sürecek, ancak yeni görüntüler üzerinde yürütme çok daha hızlı olacak. Doğru referansları eklemek için daha fazla boş zaman aldığımda bu yöntemi yazmayı planlıyorum.
ely

9
ReCAPTCHA'ya benzer bir yaklaşıma ne dersiniz ? ;)
George Duckett

39
Bu neden dsp.stackexchange.com'dan taşındı ? Görünüşe göre bu site stackoverflow o_O
BlueRaja - Danny Pflughoeft

Yanıtlar:


672

Alternatif bir yaklaşım, ölçek değişmez özellik dönüşümü (SIFT) veya Hızlandırılmış Sağlam Özellikleri (SURF) kullanarak unsurları (anahtar noktaları) ayıklamaktır .

OpenCV 2.3.1'de uygulanmaktadır .

Bilinen bir nesneyi bulmak için Features2D + Homografi'deki özellikleri kullanarak güzel bir kod örneği bulabilirsiniz

Her iki algoritma da ölçeklendirme ve döndürmeye değişmez. Özelliklerle çalıştıklarından, tıkanıklığı da ele alabilirsiniz (yeterli anahtar noktası görünür olduğu sürece).

Resim açıklamasını buraya girin

Görüntü kaynağı: eğitim örneği

İşleme SIFT için birkaç yüz ms sürer, SURF biraz daha hızlıdır, ancak gerçek zamanlı uygulamalar için uygun değildir. ORB, rotasyon değişmezliği açısından daha zayıf olan FAST kullanır.

Orijinal belgeler


6
@Stacker ile hemfikirim - SIFT mükemmel bir seçim. Ölçek ve döndürme işlemlerine karşı çok sağlamdır. Perspektif deformasyonuna karşı biraz sağlamdır (istifleyici tarafından önerildiği gibi geliştirilebilir: istenen nesnenin farklı perspektif görünümlerine sahip bir şablon veritabanı). Deneyimlerime göre Aşil topuğu, güçlü aydınlatma varyasyonları ve çok pahalı hesaplama olurdu. Herhangi bir Java uygulaması bilmiyorum. OpenCV uygulamasının farkındayım ve gerçek zamanlı performans için uygun bir GPU c ++ / Windows ( SiftGPU ) uygulaması kullandım.

31
Uyarı notu: SIFT / SURF'u ve benim yaptıklarımı sevdiğim kadar patentli. Bu , AFAIK coğrafi konumu da dahil olmak üzere çeşitli koşullara bağlı olarak bir sorun olabilir .
Agos

12
Bu nedenle, patent sorunu olmayan OpenCV'nin ORB veya FREAK'ını deneyin. ORB, SIFT'den çok daha hızlıdır. ORB, deneyimimdeki ölçek ve ışık varyasyonları ile biraz zayıf ama kendiniz test edin.
Rui Marques

66
Bunu bir cevap olarak nasıl kabul edebilirsiniz ... Özellik tanımlayıcıların hiçbiri şişeleri bir teneke kutudan ayıramaz ... Hepsi değişmez yerel desen tanımlayıcılarını görüntüler. Ben SIFT, SURF, ORB, FREAK vb özellik eşleştirme size yardımcı olabilir katılıyorum ama .. Oklüzyonlar, Şişe vs Can vb gibi sorunun diğer bölümleri hakkında umarım bu aslında tam bir çözüm değildir umarım GOOGLED sorununuzu muhtemelen ilk sonuç sadece bu cevap olacaktır.
G453

11
@ G453 kesinlikle haklısın! Muhtemelen
SHIFT'in

383

İşleri hızlandırmak için, rastgele bir görüntü / nesne bulmanızın istenmediğinden, özellikle de Coca-Cola logosuna sahip olandan yararlanabilirsiniz. Bu önemlidir, çünkü bu logo çok farklıdır ve frekans alanında, özellikle RGB'nin kırmızı kanalında karakteristik, ölçek değişmez bir imzası olmalıdır. Yani, yatay bir tarama çizgisinin (yatay olarak hizalanmış bir logoda eğitilmiş) karşılaştığı kırmızı-beyaz-kırmızı arasında değişen desen, logonun merkezi ekseninden geçerken belirgin bir "ritime" sahip olacaktır. Bu ritim farklı ölçeklerde ve yönlerde "hızlanacak" veya "yavaşlayacaktır", ancak orantılı olarak eşdeğer olmaya devam edecektir. Logo aracılığıyla hem yatay hem de dikey olarak birkaç düzine tarama çizgisini tanımlayabilir / tanımlayabilirsiniz, yıldız patlaması desen. Bunlara "imza tarama satırları" deyin.

İmza tarama çizgisi

Hedef görüntüde bu imzayı aramak, görüntüyü yatay şeritler halinde taramak için basit bir konudur. Kırmızı kanalda yüksek bir frekans arayın (kırmızı bir bölgeden beyaz bir bölgeye geçmeyi gösterir) ve bir kez bulunduğunda, eğitim oturumunda tanımlanan frekans ritimlerinden birini takip edip etmediğine bakın. Bir eşleşme bulunduğunda, tarama çizgisinin logodaki yönünü ve yerini anında öğreneceksiniz (eğitim sırasında bu şeyleri takip ederseniz), bu nedenle logonun sınırlarını oradan belirlemek önemsizdir.

Bu, doğrusal olarak verimli bir algoritma olmasaydı şaşırırdım ya da neredeyse böyle değildi. Açıkçası kutu şişe ayrımcılığınıza hitap etmiyor, ancak en azından logolarınız olacak.

(Güncelleme: I) (kola için logo bitişik kahverengi sıvı olmazdı şişe tanınması için -, olup içeride . Boş bir şişe durumunda, şişe Veya, bir bakmak istiyorum kapağı daima olacaktır logo ile aynı temel şekil, boyut ve mesafe ve tipik olarak beyaz veya kırmızı olacaktır.Logoya göre bir kapağın olması gereken düz renkli eliptik bir şekil arayın.Kabuk kusursuz değil, ama buradaki amacınız kolay olanları hızlı bul .)

(Görüntü işleme günlerimden bu yana birkaç yıl geçti, bu yüzden bu öneriyi üst düzey ve kavramsal tuttum. Bir insan gözünün nasıl çalışabileceğini - veya en azından beynimin nasıl çalıştığını biraz tahmin edebilirim!)


24
Bu harika bir öneri, özellikle bu algoritmanın muhtemelen birçok yanlış negatifi olsa bile oldukça hızlı olması gerektiğini seviyorum. Gizli hedeflerimden biri, bu tespiti robotik için gerçek zamanlı olarak kullanmak, böylece iyi bir uzlaşma olabilir!
Charles Menguy

42
Evet, çoğu zaman gerçek zamanlı, gerçek dünya modelleme görevleri için yaklaşık algoritmaların gerekli olduğu (hassasiyetle karakterize edilen bir alanda) unutulur . ( Tezimi bu konsepte dayandırdım .) Sınırlı bölgeler için zaman gerektiren algoritmalarınızı kaydedin (yanlış pozitifleri budamak için). Ve unutmayın: Robotikte genellikle tek bir görüntü ile sınırlı değilsiniz. Mobil bir robot olduğunu varsayarsak, hızlı bir alg, karmaşık algların birine harcadığından daha kısa sürede farklı açılardan düzinelerce görüntüyü arayabilir ve yanlış negatifleri önemli ölçüde azaltır.
kmote

29
Coca-Cola logolarının son derece hızlı tespiti için bir barkod tarayıcısının ne kadarını kullanma fikrini seviyorum . 1!
Li-aung Yip

8
Bu durumda imza arama sorunu, kutuyu diğer tarafa çevirirsek, yani imzayı gizlersek, algoritmanın kutuyu algılayamayacağıdır.
karlphillip

34
@karlphillip: İmzayı, yani logoyu gizlerseniz, logoyu aramaya dayalı herhangi bir yöntem başarısız olur.
Li-aung Yip

162

Eğlenceli bir sorun: şişe resminize baktığımda bunun da bir kutu olduğunu düşündüm. Ancak, bir insan olarak, farkı söylemek için yaptığım şey, o zaman da bir şişe olduğunu fark ettim ...

Kutuları ve şişeleri birbirinden ayırmak için önce şişeleri taramaya ne dersiniz? Bir tane bulursanız, kutulara bakmadan önce etiketi maskeleyin.

Zaten teneke kutu yapıyorsanız uygulamak çok zor değil. Gerçek dezavantajı, işlem sürenizi iki katına çıkarmasıdır. (Ama gerçek dünya uygulamalarını düşünerek, yine de şişe yapmak isteyeceksiniz ;-)


5
Evet, ben de düşündüm ama yapacak fazla vaktim yoktu. Bir şişeyi nasıl tanıyacaksınız, çünkü ana kısmı ölçekli bir kutuya benzeyecek mi? Kırmızı fişi de aramayı düşünüyordum ve şişelenmiş merkezle hizalanıp hizalanmadığını görüyordum, ama bu çok sağlam görünmüyor.
Charles Menguy

42
"Coca cola" ya paralel kırmızı bir kapak (veya halka) varsa, büyük olasılıkla bir şişedir.
Lukasz Madon

@linker Algoritmanızı teneke kutular için nasıl eğitdiniz? Kutu örnekleriniz var mıydı? Şişe örnekleri ile eğitime ne dersiniz?
siamii

1
Bu algoritmanın gücü, üzerinde çalışmak için sadece bir şablona ihtiyaç duymanız ve daha sonra tüm dönüşümleri diğer potansiyel kutularla eşleştirmek için uygulamasıdır. Eğitmek için bu şablonun ikili ve kontur tabanlı bir sürümünü kullanıyordum, bu yüzden kutu ve şişe arasındaki tek fark fiş olurdu, ancak yerçekimi merkezinin kenarda bir yerde olacağı için daha yanlış pozitifler getireceğinden korkuyorum veya şişenin dışında. Sanırım denemeye değer. Ama bu benim işleme süresini iki katına çıkacak ve ben ağlamaya gidiyorum;)
Charles MENGUY

7
Aslında bu makul bir yön. Ben biraz farklı ifade ediyorum: Önce tüm adayları bulun ve sonra her aday için bir şişe, kutu veya başka bir şey olup olmadığını belirleyin.
MSalters

131

İnsanların ikinci görüntüde bir şişe ve bir teneke kutu arasında ayrım yapması bile zor değil mi (şişenin şeffaf bölgesinin gizli olması şartıyla)?

Çok küçük bir bölge haricinde neredeyse aynıdırlar (yani, şişenin sargısı aynı genişlikte iken kutunun üstündeki genişlik biraz küçüktür, ancak küçük bir değişiklik değil mi?)

Aklıma ilk gelen şişe kırmızı üst kontrol etmek oldu. Ancak, şişenin üst kısmı yoksa veya kısmen gizlenmişse (yukarıda belirtildiği gibi) hala bir sorundur.

Düşündüğüm ikinci şey şişenin şeffaflığıydı. OpenCV, görüntüde saydam nesneler bulma konusunda bazı çalışmalara sahiptir. Aşağıdaki bağlantıları kontrol edin.

Camı ne kadar doğru algıladıklarını görmek için özellikle buna bakın:

Uygulama sonuçlarına bakın:

Resim açıklamasını buraya girin

CVPR 2006 tarafından K. McHenry ve J. Ponce tarafından yazılan "Cam Bulmak İçin Bir Jeodezik Aktif Kontur Çerçevesi" kitabının uygulanması olduğunu söylüyorlar .

Durumunuzda biraz yardımcı olabilir, ancak şişe doldurulursa sorun tekrar ortaya çıkar.

Bence burada şişelerin şeffaf gövdesini veya yanal olarak şişe olan iki saydam nesneye bağlı kırmızı bir bölgeyi arayabilirsiniz. (İdeal olarak çalışırken, aşağıdaki gibi bir görüntü.)

Resim açıklamasını buraya girin

Şimdi sarı bölgeyi, yani şişenin etiketini çıkarabilir ve kutuyu bulmak için algoritmanızı çalıştırabilirsiniz.

Her neyse, bu çözümün diğer çözümlerde olduğu gibi farklı sorunları da var.

  1. Sadece şişeniz boş olduğunda çalışır. Bu durumda, iki siyah renk arasındaki kırmızı bölgeyi aramanız gerekecektir (Coca Cola sıvısı siyahsa).
  2. Şeffaf kısım kapalıysa başka bir sorun.

Ama yine de, resimlerde yukarıdaki sorunlardan hiçbiri yoksa, bu daha iyi bir yol gibi görünüyor.


+1 Bunu düşündüm ve bu yaklaşımı uygulama yolumdaydı. Bununla birlikte, @linker daha eğitimli tahminler yapmayı deneyebilmemiz için imaj kümesini paylaşmalıdır.
karlphillip

evet .. daha fazla resim olmanın iyi olduğunu düşünüyorum.
Abid Rahman K

Sadece şişeler / teneke kutular için etiketlere sahip olup olmadığımızı ve şişe kapağı veya şeffaflığın diğer ayırt edici faktörlerinden hiçbirini veya alt / üst tenekeyi dikkate aldığımızı düşünmek - Şişenin genişliği tenekenin genişliğinden farklıdır.
Ken

Şişe için logonun önüne bir kutu yerleştirilirse ne olur?
AlgoRythm

51

Darren Cook'un ve istifleyicinin bu soruna cevaplarını gerçekten çok seviyorum . Düşüncelerimi bunlarla ilgili bir yorum haline getirmenin ortasındaydım, ama yaklaşımımın buradan ayrılmayacak kadar cevap biçimli olduğuna inanıyorum.

Özetle, uzayda belirli bir yerde bir Coca-Cola logosunun bulunduğunu belirleyen bir algoritma belirlediniz. Şimdi, keyfi yönlendirmeler ve keyfi ölçeklendirme faktörleri için, Coca-Cola kutularını , bu ikonik logo ile ilişkili şişeler , reklam panoları , reklamlar ve Coca-Cola gereçlerinin dahil olduğu diğer nesnelerden ayırmak için uygun bir buluşsal yöntem belirlemeye çalışıyorsunuz . Sorun ifadenizde bu ek durumların çoğunu çağırmadınız, ancak algoritmanızın başarısı için hayati önem taşıdıklarını hissediyorum.

Buradaki sır, bir kutunun hangi görsel özellikleri içerdiğini veya negatif boşluk yoluyla, kutular için mevcut olmayan diğer Kok ürünleri için hangi özelliklerin mevcut olduğunu belirlemektir. Bu amaçla, mevcut üst yanıt , bir şişe kapağı, sıvı veya benzer görsel buluşsal yöntemlerin varlığıyla ancak "şişe" tanımlanmamışsa "can" ı seçmek için temel bir yaklaşım çizer.

Sorun şu ki bu yıkılıyor. Bir şişe, örneğin, boş olabilir ve bir kapağın varlığından yoksun olabilir, bu da yanlış pozitifliğe yol açabilir. Ya da ek özellikleri karıştırılmış olan kısmi bir şişe olabilir ve bu da yine yanlış tespiti sağlar. Söylemeye gerek yok, bu zarif değil, aynı zamanda amaçlarımız için de etkili değil.

Bu amaçla, teneke kutular için en doğru seçim kriterleri aşağıdaki gibi görünmektedir:

  • Sorunuzda çizdiğiniz nesne siluetinin şekli doğru mu? Varsa +1.
  • Doğal veya yapay ışığın varlığını varsayarsak, şişede bunun alüminyumdan yapılmış olup olmadığını gösteren bir krom anahat tespit eder miyiz? Varsa +1.
  • Nesnenin aynasal özelliklerinin , ışık kaynaklarımıza ( ışık kaynağı algılamaya ilişkin açıklayıcı video bağlantısı) göre doğru olduğunu belirliyor muyuz ? Varsa +1.
  • Logonun topolojik görüntü eğriliği, nesnenin yönü, nesnenin yan yana konumlandırılması (örneğin, düzlemsel bir yüzey dahil) dahil ancak bunlarla sınırlı olmamak üzere, nesneyi bir kutu olarak tanımlayan diğer özellikleri belirleyebilir miyiz? bir masa gibi veya diğer kutular bağlamında) ve bir çekme tırnağının varlığı? Öyleyse, her biri için +1.

Sınıflandırmanız aşağıdaki gibi görünebilir:

  • Her aday maçı için bir Coca Cola logosunun varlığı tespit edildiğinde gri bir kenarlık çizin.
  • +2 üzerindeki her maç için kırmızı bir kenarlık çizin.

Bu, kullanıcıya tespit edilenleri görsel olarak vurgular ve doğru bir şekilde karıştırılmış teneke kutular olarak algılanabilecek zayıf pozitifleri vurgular.

Her mülkün tespiti çok farklı bir zaman ve mekan karmaşıklığı taşır ve her yaklaşım için, http://dsp.stackexchange.com adresinden hızlı bir geçiş , amaçlarınız için en doğru ve en verimli algoritmayı belirlemek için makul olandan daha fazladır. Buradaki amacım, tamamen ve basit bir şekilde, aday tespit alanının küçük bir kısmını geçersiz kılarak bir şeyin bir kutu olup olmadığını tespit etmenin , bu soruna en sağlam veya etkili çözüm olmadığını vurgulamaktır ve ideal olarak, uygun önlemleri almalısınız. buna göre.

Ve hey, Hacker News gönderisini tebrik ediyoruz ! Genel olarak, bu, aldığı tanıtımına layık oldukça müthiş bir sorudur. :)


2
Bu en azından denemeye değer ilginç bir yaklaşım, gerçekten sorunla ilgili mantığınızı seviyorum
Charles Menguy

Düşündüğüm şey bu: belirli türden yanlış pozitifleri göz ardı etmeyin. Bir kola yapabilen şeyin daha fazla özelliğini yönetin. Ama merak ediyorum: ezilmiş bir kutu hakkında ne yapıyorsun? Demek istediğim, eğer bir kola kutusuna basarsan hala bir kola olabilir. Ama artık aynı şekle sahip olmayacak. Yoksa bu sorun AI-Complete mi?
Ian

41

Şekle bakıyor

Kutu / şişenin kırmızı kısmının şeklindeki bir parıltı alın. Şişe etiketinin düz olmasına rağmen kutunun en üstte nasıl hafifçe söndüğüne dikkat edin. Kırmızı kısmın genişliğini uzunluğu boyunca karşılaştırarak bu ikisi arasında ayrım yapabilirsiniz.

Öne çıkanlara bakmak

Şişe ve tenekeleri ayırt etmenin bir yolu malzemedir. Bir şişe plastikten, bir kutu alüminyum metalden yapılmıştır. Yeterince iyi aydınlatılmış durumlarda, spekülasyona bakmak, bir kutu etiketinden bir şişe etiketi söylemenin bir yolu olacaktır.

Anlayabildiğim kadarıyla, bir insan iki etiket türü arasındaki farkı böyle söylerdi. Aydınlatma koşulları zayıfsa, yine de ikisini ayırt etmede bir belirsizlik vardır. Bu durumda, şeffaf / yarı saydam şişenin kendisinin varlığını tespit edebilmeniz gerekir.


Fikri seviyorum, ama gerçekten iyi aydınlatma koşullarına ihtiyacınız var gibi görünüyor. Hem kutu hem de şişenin olduğu örnek görüntüde, bu ayrım yapmak biraz zor gibi görünüyor.
Charles Menguy

Örneğinizde, plastik etiket için spekulumun kutudaki çok parlak noktalardan çok daha dağınık olduğuna dikkat edin? Böyle söyleyebilirsin.
tskuzzy

Görüyorum ki, bu durumda algoritmanızdaki speküaliteyi yakalamak için ne tür bir renk alanı gösterimi kullanırsınız? Bu RGB veya HSV almak için oldukça zor görünüyor
Charles MENGUY

3
Işık kaynağı kutunun arkasında olsaydı? Bence vurgulamayı göremezsiniz.
Rui Marques

37

Lütfen Zdenek Kalal'ın Predator takipçisine bir göz atın . Biraz eğitim gerektirir, ancak izlenen nesnenin farklı yönlere ve ölçeklere nasıl baktığını ve bunu gerçek zamanlı olarak aktif olarak öğrenebilir!

Kaynak kodu sitesinde mevcuttur. Bu öyle MATLAB , ama belki de zaten bir topluluk üyesi tarafından yapılan bir Java uygulaması vardır. C # TLD izci bölümünü başarıyla yeniden uyguladım. Doğru hatırlarsam TLD, kilit noktası dedektörü olarak Ferns kullanıyor. İzleyici tarafından kaybolduysa, nesneyi yeniden almak için SURF veya SIFT kullanıyorum (zaten @stacker tarafından öneriliyor). İzleyicinin geri bildirimi, zamanla nesnenin çok yüksek hassasiyetle yeniden alınmasını sağlayan dinamik bir eleme / sörf şablonları listesi oluşturmayı kolaylaştırır.

İzleyicimin C # uygulamamla ilgileniyorsanız, sormaya çekinmeyin.


İlginç görünen bağlantı için teşekkürler. Eğitim ile ilgili olarak, makul sonuçlar elde etmek için makul olacak eğitim setinin büyüklüğü nedir? Eğer c # bile bir uygulama varsa bu da çok yararlı olacaktır!
Charles Menguy

TLD araştırırken, C # uygulaması arayan başka bir kullanıcı buldum --- işinizi Github'a koymamak için herhangi bir neden var mı? stackoverflow.com/questions/29436719/…
spillner

2
NB Yıllar, sonra, bağlantı artık öldü
J Evans

33

Yalnızca kısıtlamalarınızdan birinde olmayan bir kamerayla sınırlı değilseniz, belki de Xbox Kinect gibi bir menzil sensörü kullanmaya geçebilirsiniz . Bu sayede görüntünün derinlik ve renk temelli uyumlu segmentasyonunu gerçekleştirebilirsiniz. Bu, görüntüdeki nesnelerin daha hızlı ayrılmasını sağlar. Daha sonra sadece anahat veya renginden ziyade teneke kutu şeklini eşleştirmek için ICP eşleştirme veya benzer teknikler kullanabilirsiniz ve silindirik olduğu göz önüne alındığında, hedefin daha önce 3D taraması varsa bu herhangi bir yönlendirme için geçerli bir seçenek olabilir. Bu teknikler, özellikle hız sorununuzu çözmesi gereken özel bir amaç için kullanıldığında oldukça hızlıdır.

Ayrıca, kesinlikle doğruluk veya hız için değil, eğlence için kutunun şeklini tanımlamak için renk bölümlü görüntünüzde eğitimli bir sinir ağı kullanabilirsiniz. Bunlar çok hızlıdır ve genellikle% 80/90 oranında doğru olabilir. Her görüntüdeki kutuyu manuel olarak tanımlamanız gerekeceğinden, eğitim biraz uzun bir süreç olacaktır.


3
Aslında bunu yazıda açıklamamıştım, ancak bu ödev için yaklaşık 30 görüntü seti verildi ve tarif edildiği gibi çeşitli durumlarda hepsiyle eşleşecek bir algoritma yapmak zorunda kaldım. Tabii ki sonunda algoritmayı test etmek için bazı görüntüler tutuldu. Ama Kinect sensörleri fikrini seviyorum ve konuyla ilgili daha fazla okumak isterim!
Charles Menguy

Sinir ağına sahip eğitim setinin tatmin edici sonuçlara ulaşması kabaca ne olur? Bu yöntemle güzel olan şey, hemen hemen her şeyi eşleştirmek için sadece bir şablona ihtiyacım var.
Charles Menguy

2
Görüntü
kümeniz

Evet, veri kümesi üzerinde antrenman yaparsam, karşı algoritmayı çalıştıracağım, mükemmel sonuçlar alacağım :) Ama bu ödev için, program sonunda öğretmen tarafından bir dizi düzenlenen görüntü üzerinde test edildi. . Sağlam olacak ve eğitim verilerine uymayacak bir şey yapmak istiyorum.
Charles Menguy

Eğitim seti sayısı değişir, ancak birkaç şeye dikkat etmelisiniz: Aşırı eğitmeyin, muhtemelen doğruluğunuzun nasıl gittiğini gösteren bir test seti istersiniz. Ayrıca eğitim seti sayısı, kullanacağınız katman sayısına bağlı olacaktır.
Fantastik Bay Fox

24

Kırmızı dikdörtgenleri tespit ederim: RGB -> HSV, filtre kırmızı -> ikili görüntü, kapat (dilate sonra aşındır, imclosematlab olarak bilinir )

Sonra en büyükten en küçüğe dikdörtgenlere bakın. Bilinen bir konumda / ölçekte daha küçük dikdörtgenleri olan dikdörtgenlerin her ikisi de kaldırılabilir (şişe oranlarının sabit olduğu varsayılarak, daha küçük dikdörtgen bir şişe kapağı olacaktır).

Bu size kırmızı dikdörtgenler bırakacaktır, o zaman bir şekilde kırmızı bir dikdörtgen mi yoksa kola kutusu mu olduğunu belirlemek için logoları tespit etmeniz gerekir. OCR gibi ama bilinen bir logoya sahip misiniz?


2
Bu, taşındığı kısa sürede DSP'de tartışıldığı gibi, bazı şişelerin tıkaçları olmayabilir;) veya fiş kısmen gizlenebilir.
Charles Menguy

22

Bu çok naif bir fikir olabilir (veya hiç işe yaramayabilir), ancak tüm kok kutularının boyutları sabittir. Aynı görüntü hem bir teneke kutu hem de bir şişe içeriyorsa, bunları boyut değerlendirmeleriyle ayırabilirsiniz (şişeler daha büyük olacaktır). Şimdi eksik derinlik nedeniyle (yani 2B haritaya 3B haritalama) bir şişenin küçülmüş görünmesi ve boyut farkı olmaması mümkündür. Stereo görüntülemeyi kullanarak bazı derinlik bilgilerini kurtarabilir ve ardından orijinal boyutunu kurtarabilirsiniz.


3
Aslında hayır: boyut veya yönelim kısıtlaması yok (veya yönelim ama gerçekten idare etmedim), bu yüzden arka planda çok uzak bir şişe ve ön planda bir kutu olabilir ve kutu daha büyük olabilir şişe daha.
Charles Menguy

Ayrıca genişlik / yükseklik oranının şişe ve kutu için oldukça benzer olduğunu kontrol ettim, bu da gerçekten bir seçenek değil.
Charles Menguy

Etiket oranı (bir ticari marka olarak) aynıdır. Eğer (büyük) şişe resimde biraz daha uzakta ise, boyutu kutu ile aynı olacaktır.
littleadv

3
Biraz daha açıklamak gerekirse. Kutunun z = 0 ve şişenin z = -100 olduğunu varsayalım. Şişe çok geride olduğundan daha küçük görünecektir. Ancak şişenin z = -100'de olduğunu ve z = 0'da olabileceğini bilsem, her ikisi de z = 0'a çevrildiyse, teneke kutu / şişenin beklenen boyutunu hesaplayabilirim. Şimdi aynı derinliktedirler ve bu nedenle boyuta göre kararlar verebilirim.
Sharad

2
Bu sadece bir yorum, bir cevap değil, ama cevap olmak, yukarıdaki 120 oyla bir cevap olarak yorumdan çok daha yakın.
17'de Fattie

22

Hmm, aslında bir şey üzerinde olduğumu düşünüyorum (bu şimdiye kadarki en ilginç soru gibi - bu yüzden kabul edilebilir bir cevap bulunsa bile "mükemmel" cevabı bulmaya devam etmemek utanç verici olurdu) .. .

Logoyu bulduğunuzda, sorunlarınız yarıya iner. O zaman sadece logonun etrafındakiler arasındaki farkları anlamanız gerekir . Ayrıca, mümkün olduğunca az ekstra yapmak istiyoruz. Bence bu aslında bu kolay kısım ...

Logonun etrafında ne var ? Bir kutu için, aydınlatmanın etkilerine rağmen temel renginde hiçbir şekilde değişmeyen metal görebiliriz. Etiketin açısını bildiğimiz sürece, doğrudan üstünde ne olduğunu söyleyebiliriz, bu yüzden bunlar arasındaki farka bakıyoruz:

Burada, logonun üstünde ve altında tamamen karanlık, renk tutarlı. Bu açıdan nispeten kolay.

Burada, yukarıda ve aşağıda olan şey hafiftir, ancak yine de renkte tutarlıdır. Tamamen gümüş ve tamamen gümüş metal, genel olarak gümüş renklerin yanı sıra oldukça nadir görünüyor. Ek olarak, kutunun metal halkası olarak kabul edilebilecek bir yüzdeyi hesaplamak için, tüm uzunluğu boyunca şeklini izleyebilmeniz için önceden tanımlanmış olan kırmızıya yeterince yakın ve ince bir kayma içinde. Gerçekten, kutunun herhangi bir yerinde bunun küçük bir kısmına ihtiyacınız var, ancak bunun bir parçası olduğunu söylemek için hala bir denge bulmanız gerekiyor, ancak arkasında sadece metal bir şey olan boş bir şişe değil.

Ve son olarak, zor olan. Ama o kadar da zor değil, bir kez sadece kırmızı sargının üstünde (ve altında) görebildiğimiz şeyden geçtikten sonra. Şeffaftır, yani arkasında ne varsa gösterecektir. Bu iyi, çünkü arkasındaki şeylerin, kutunun gümüş dairesel metaliyle aynı renkte olması muhtemel değil. Arkasında, boş (veya berrak sıvı ile doldurulmuş) bir şişe veya tutarlı bir renk olduğunu söyleyen çok farklı şeyler olabilir, bu da ya sıvı ile dolu olduğu ya da şişenin sadece bir önünün önünde olduğu anlamına gelebilir. düz renk. Üst ve alt kısımlara en yakın olanlarla çalışıyoruz ve doğru renklerin doğru yerde olma şansı nispeten zayıf. Bunun bir şişe olduğunu biliyoruz, çünkü kutunun o önemli görsel unsuru yok,

(sonuncusu boş bir büyük coca cola şişesi bulabildiğim en iyisiydi - ilginç bir şekilde kapak VE halka sarı, bu da kapağın kızarıklığına muhtemelen güvenilmemesi gerektiğini gösteriyor)

Benzer bir gümüş tonunun şişenin arkasında olması, plastiğin soyutlanmasından sonra bile veya şişenin bir şekilde aynı gümüş sıvının gölgesi ile doldurulması nadir durumlarda, kabaca gümüşün şekli - bahsettiğim gibi daireseldir ve kutunun şeklini takip eder. Ancak görüntü işleme konusunda herhangi bir bilgim olmamasına rağmen, bu kulağa yavaş geliyor. Daha da iyisi, neden aynı gümüş renginde hiçbir şey olmadığından emin olmak için logonun kenarlarını bir kez kontrol ederek bunu çıkarmıyorsunuz ? Ah, ama bir kutunun arkasında aynı gümüş tonu varsa? Sonra, kutunun üst ve alt kısmına tekrar bakarak şekillere daha fazla dikkat etmeliyiz.

Her şeyin ne kadar kusursuz olması gerektiğine bağlı olarak, çok yavaş olabilir, ancak sanırım temel konseptim önce en kolay ve en yakın şeyleri kontrol etmektir. Diğer öğelerin şeklini çalışma çabasına gitmeden önce zaten eşleştirilmiş şeklin etrafındaki renk farklılıklarına (bunun zaten en önemsiz kısmı gibi görünüyor) gidin. Listelemek için gidiyor:

  • Ana cazibeyi bulun (kırmızı logo arka planı ve muhtemelen oryantasyon için logonun kendisi, kutunun geri çevrilmesi durumunda, sadece kırmızıya konsantre olmanız gerekir)
  • Yine çok farklı kızarıklık ile şekli ve yönü doğrulayın
  • Şeklin etrafındaki renkleri kontrol edin (hızlı ve ağrısız olduğundan)
  • Son olarak, gerekirse, doğru yuvarlaklık için ana cazibe etrafındaki renklerin şeklini doğrulayın.

Bunu yapamazsanız, muhtemelen kutunun üst ve alt kısmı örtülü demektir ve bir insanın kutu ile şişe arasında güvenilir bir ayrım yapmak için kullanabileceği tek şey oklüzyon ve yansımadır. işlemek için çok daha zor bir savaş olurdu . Bununla birlikte, daha da ileri gitmek için, diğer cevaplarda bahsedilen yarı saydam tarama tekniklerini kullanarak daha fazla şişe benzeri özellik olup olmadığını kontrol etmek için kutu / şişenin açısını takip edebilirsiniz.

İlginç ek kabuslar, şişenin arkasında, metalin etiketin üstünde ve altında gösterileceği kadar rahat bir şekilde oturan bir teneke kutu içerebilir, bu da kırmızının tüm uzunluğu boyunca taradığınız sürece başarısız olur. etiket - bu aslında bir sorundur çünkü kazara kutu da dahil olmak üzere bir şişeyi gerçekten algıladığınızı düşünmek yerine, sahip olabileceğiniz bir kutuyu tespit etmiyorsunuzdur. Cam yarı boş, bu durumda!


Bir feragatname olarak, bu sorunun dışında görüntü işleme konusunda hiçbir deneyimim yok veya hiç düşünmedim, ama o kadar ilginç ki beni bu konuda oldukça derin düşünmeye itti ve diğer tüm cevapları okuduktan sonra, bunun muhtemelen bunu yapmanın en kolay ve etkili yolu. Şahsen ben değil mutluyum aslında bu programlama düşünmek zorunda!

DÜZENLE

MS boya bir kutu kötü çizim Buna ek olarak, MS Paint'te yaptığım bu çizime bakın ... Kesinlikle korkunç ve oldukça eksik, ancak sadece şekil ve renklere dayanarak, muhtemelen ne olacağını tahmin edebilirsiniz. Özünde, tarama için uğraşması gereken tek şey bunlar. Bu çok farklı şekle ve renk kombinasyonuna çok yakın baktığınızda, başka ne olabilir ki? Ben boyamadım biraz, beyaz arka plan, "tutarsız bir şey" olarak kabul edilmelidir. Saydam bir arka planı olsaydı, hemen hemen her görüntünün üzerinden geçebilirdi ve hala görebiliyordunuz.


10
Kırmızının özel tonu çoğunlukla özneldir ve ışıklandırma hususlarından ve beyaz dengesinden güçlü bir şekilde etkilenir. Bunların ne kadar değişebileceğine şaşırabilirsiniz. Örneğin, bu dama tahtası yanılsamasını düşünün .
Ahtapot

2
@Octopus'un gönderdiği bağlantıda bir güncelleme: persci.mit.edu/gallery/checkershadow
Hat

Bir algı yanılsaması, web kameranızın gördüklerini etkilemez - yani kodunuzun aldığı şey - sadece bir insan gözünün beyne nasıl yardımcı olduğunu (?) Kandırır.
barny

17

Ben OpenCV farkında değilim ama mantıklı bir şekilde sorun bakarak şişe ve yani Coca Cola aradığınız görüntüyü değiştirerek olabilir ayırt edebilirsiniz düşünüyorum. Kova kola üstünde gümüş astar olduğu ve şişe durumunda böyle bir gümüş astar olmayacağı için kutunun üst kısmına kadar eklemelisiniz.

Ancak açıkçası bu algoritma, kutunun üst kısmının gizlendiği durumlarda başarısız olacaktır, ancak bu durumda insan bile ikisi arasında ayrım yapamayacaktır (şişenin / kutunun sadece coca cola kısmı görünürse)


1
Aynı düşünceye sahiptim, ancak kutunun üstündeki gümüş astarın, resimdeki kutunun açısına bağlı olarak önemli ölçüde değiştiğini düşünüyorum. Düz bir çizgi veya daire olabilir. Belki ikisini de referans olarak kullanabilir?
Alexis Dufrenoy

15

Ben meydan okumayı seviyorum ve bu sorunu çözen bir cevap vermek istedim.

  1. Logonun özelliklerini (anahtar noktaları, SIFT, SURF gibi tanımlayıcılar) ayıklayın
  2. Noktaları logonun model görüntüsü ile eşleştirin (Brute Force gibi Matcher'ı kullanarak)
  3. Rijit cismin koordinatlarını tahmin edin (PnP problemi - SolvePnP)
  4. Kapak konumunu rijit gövdeye göre tahmin edin
  5. Arkadan projeksiyon yapın ve şişenin kapağının görüntü piksel konumunu (ROI) hesaplayın (kameranın iç parametrelerine sahip olduğunuzu varsayıyorum)
  6. Kapağın orada olup olmadığını bir yöntemle kontrol edin. Varsa, o zaman bu şişe

Başlığın tespiti başka bir konudur. Karmaşık veya basit olabilir. Ben olsaydım, basit bir karar için YG'deki renk histogramını kontrol ederdim.

Lütfen, yanılıyorsam geribildirim verin. Teşekkürler.


13

Bu soruyu cevaplamak için birkaç yıl geç kaldım. Son 5 yılda son teknoloji CNN'ler tarafından sınırlarını zorlayan OpenCV'yi şimdi bu görevi yapmak için kullanmam! ( Özellikle soruda OpenCv özellikleri istediğinizi biliyorum ) Daha hızlı-RCNN'ler, YOLO, SSD vb. Şimdi bu problemi çözecek olsaydım (6 yıl sonra !!) Kesinlikle daha hızlı-RCNN kullanırdım .


5
OP, ConvNets'i eğitmek için muhtemelen en iyi senaryo olmayan 30 yüksek çözünürlüklü görüntü olduğunu söyledi. Sadece çok az değil (hatta artırılmış), yüksek çözünürlüklü kısım ConvNets'i yok edecekti.
Kostas Mouratidis

11

Konunuzdan bağımsız olsun veya olmasın, sorunuzu beğendim: P

İlginç bir kenara; Derecemde robotik ve bilgisayar vizyonunu ele aldığımız bir konuyu tamamladım. Dönem projemiz, tarif ettiğiniz projeye inanılmaz derecede benziyordu.

Çeşitli aydınlatma ve çevre koşullarında herhangi bir yönde kok şişelerini ve tenekeleri tespit etmek için bir Xbox Kinect kullanan bir robot geliştirmemiz gerekiyordu. Çözümümüz, houe circle dönüşümü ile birlikte Hue kanalında bir bant geçiren filtre kullanılmasını içeriyordu. Ortamı biraz kısıtlayabildik (robot ve Kinect sensörünü nereye ve nasıl konumlandıracağımızı seçebildik), aksi takdirde SIFT veya SURF dönüşümlerini kullanacaktık.

Bu konudaki blog yayınımda yaklaşımımızı okuyabilirsiniz :)


2
İlginç bir proje, ancak sadece çok özel kurulumunuz için geçerlidir.
Rui Marques

10

Nesneleri tanımak için kullanılan bir grup renk tanımlayıcısı vardır, aşağıdaki kağıt birçoğunu karşılaştırmaktadır. SIFT veya SURF ile birleştirildiğinde özellikle güçlüdürler. SURF veya SIFT tek başına bir coca cola görüntüsünde çok yararlı değildir, çünkü çok fazla ilgi noktası tanımıyorlar, yardımcı olmak için renk bilgilerine ihtiyacınız var. Bir projede SURF ile BIC (Sınır / İç Piksel Sınıflandırması) kullanıyorum ve nesneleri tanımak için harika çalıştı.

Web görüntüsü almak için renk tanımlayıcılar: karşılaştırmalı bir çalışma


10

Derin Öğrenme

Kola kutuları içeren en az birkaç yüz görüntü toplayın, etrafındaki sınırlayıcı kutuyu pozitif sınıflar olarak ekleyin, kola şişeleri ve negatif kolaları etiketleyen diğer kola ürünleri ve rastgele nesneler ekleyin.

Çok büyük bir veri kümesi toplamazsanız, küçük veri kümesi için derin öğrenme özelliklerini kullanma hilesini uygulayın. İdeal olarak, destek vektör makinelerinin (SVM) derin sinir ağları ile bir kombinasyonunu kullanmak.

Görüntüleri daha önce eğitilmiş bir derin öğrenme modeline (ör. GoogleNet) besledikten sonra, sınıflandırma yapmak için sinir ağının karar (son) katmanını kullanmak yerine, sınıflandırıcıyı eğitmek için önceki katmanların verilerini özellik olarak kullanın.

OpenCV ve Google Net: http://docs.opencv.org/trunk/d5/de7/tutorial_dnn_googlenet.html

OpenCV ve SVM: http://docs.opencv.org/2.4/doc/tutorials/ml/introduction_to_svm/introduction_to_svm.html


9

Sınıflandırma doğruluğunu organik olarak deneyimlerden öğrenen ve geliştiren bir programa ihtiyacınız var.

Derin öğrenmeyi öneririm, derin öğrenmeyle bu önemsiz bir problem haline gelir.

Tensorflow'da başlangıç ​​v3 modelini yeniden eğitebilirsiniz:

Inception'ın Yeni Kategoriler İçin Son Katmanını Yeniden Eğitim .

Bu durumda, bir nesneyi bir koka-kola olabilir veya olmayabilir olarak sınıflandırmak için evrişimli bir sinir ağı eğitimi alacaksınız.


2
Sosisli sandviç ya da sosisli değil?
YellowPillow

6

Tüm bu güzel çözümlere alternatif olarak, kendi sınıflandırıcıyı eğitebilir ve uygulamanızı hatalara karşı sağlam hale getirebilirsiniz. Örneğin, hedefinize çok sayıda olumlu ve olumsuz görüntü sağlayarak Haar Eğitimini kullanabilirsiniz .

Sadece tenekeleri çıkarmak yararlı olabilir ve saydam nesnelerin tespiti ile birleştirilebilir.


3

MVTec'ten HALCON adlı bir bilgisayar görme paketi varDemoları size iyi algoritma fikirleri verebilecek . Demo modunda çalıştırabileceğiniz ve daha sonra koddaki operatörlere bakıp bunları mevcut OpenCV operatörlerinden nasıl uygulayabileceğinize benzeyen çok sayıda örnek var.

Bu paketi, bu tür sorunlar için karmaşık algoritmaları hızlı bir şekilde prototiplemek ve daha sonra mevcut OpenCV özelliklerini kullanarak nasıl uygulayacağımı bulmak için kullandım. Özellikle sizin durumunuz için OpenCV'de find_scaled_shape_model operatörüne yerleştirilmiş işlevselliği uygulamaya çalışabilirsiniz . Bazı operatörler, OpenCV'de benzer bir şeyin nasıl yapıldığını bulmaya yardımcı olabilecek algoritma uygulamasıyla ilgili bilimsel makaleye işaret ediyor. Bu yardımcı olur umarım...


0

Gerçek zamanlı olmakla ilgileniyorsanız, ihtiyacınız olan şey ağır işlerle neyin taranacağını belirlemek için bir ön işleme filtresine eklemektir. İyi bir hızlı, çok gerçek zamanlı, daha kokulu şeylere geçmeden önce bir coca-cola kutusu olması muhtemel olan şeyleri taramanıza olanak tanıyan iyi bir hızlı, ön işleme filtresi şunun gibidir: sqrt(pow(red,2) + pow(blue,2) + pow(green,2))koka kola kutunuzdan belirli bir tolerans olan renk . Çok katı bir renk toleransı ile başlayın ve daha yumuşak renk toleranslarına ulaşmak için çalışın. Ardından, robotunuz mevcut çerçeveyi işlemek için ayrılan bir süre dolduğunda, şu anda bulunan şişeleri sizin amaçlarınız için kullanır. RGB renklerini sqrt(pow(red,2) + pow(blue,2) + pow(green,2))doğru yapmak için ayar yapmanız gerektiğini lütfen unutmayın .

Ayrıca, bu gona gerçekten aptal gibi görünüyor, ancak -oFastC kodunuzu derlerken derleyici optimizasyonunu açtığınızdan emin misiniz?


0

Belki çok uzun yıllar geç, ama yine de denemek için bir teori.

Kırmızı logo bölgesinin sınırlayıcı dikdörtgeninin şişenin / kutunun toplam boyutuna oranı farklıdır. Can durumunda, 1: 1 olmalıdır, oysa şişede (kapaklı veya kapaksız) farklı olacaktır. Bu ikisi arasında ayrım yapmayı kolaylaştırmalıdır.

Güncelleme: Logo bölgesinin yatay eğriliği, ilgili boyut farklarından dolayı Can ve Şişe arasında farklı olacaktır. Bu, robotunuzun kutu / şişeyi alması gerekiyorsa ve kavrama buna göre karar verirseniz özellikle yararlı olabilir.


-1

Aradığım ilk şey, bir görüntüde Kırmızı göz algılama yaparken, KIRMIZI gibi renk gibi, tespit edilecek belirli bir renk aralığı, etrafındaki alanı göz önünde bulunduran bazı özellikler ve eğer varsa diğer gözden uzak mesafe gibi aslında görüntüde görülebilir.

1: İlk karakteristik renk ve Kırmızı çok baskındır. Coca Cola Kırmızısını tespit ettikten sonra, ilgilenilen birkaç öğe var 1A: Bu kırmızı alan ne kadar büyük (gerçek bir kutu belirlemek veya yapmak için yeterli miktarda - 10 piksel muhtemelen yeterli değil), 1B: İçerir mi? Etiketin rengi - "Coca-Cola" veya dalga. 1B1: Etiket olma olasılığının yüksek olduğunu düşünecek kadar var mı?

Öğe 1 bir tür kısayol - görüntüde doe sümük varsa ön işlem - devam edin.

Bu durumda, görüntümün bu segmentini kullanabilir ve söz konusu alandan biraz daha fazla yakınlaştırma yapmaya başlayabilirim - temel olarak çevredeki bölgeye / kenarlara bakın ...

2: Yukarıdaki görüntü alanı kimliği 1'de verildiğinde - söz konusu öğenin çevresindeki noktaları [kenarlarını] doğrulayın. C: Bir kutu üst veya alt - gümüş gibi görünen bir şey var mı? B: Bir şişe şeffaf görünebilir, ancak bir cam masa da olabilir - cam masa / raf veya şeffaf bir alan da var - eğer varsa çoklu çıkışlar ortaya çıkar. Bir Şişenin kırmızı bir kapağı olabilir, olmayabilir, ancak şişenin üst / iplik vidalarının şekli veya bir kapağı olmalıdır. C: Bu A ve B'yi başarısız olsa bile, hala bir kutu - kısmi olabilir. Kısmi bir şişe / kısmi aynı görünebileceğinden, kısmi olduğunda daha karmaşıktır, bu nedenle Kırmızı bölge kenarının ölçümünün biraz daha işlenmesi kenarına .. küçük şişe benzer boyutta olabilir ..

3: Yukarıdaki analizden sonra, yazıya ve dalga logosuna baktığım zaman - çünkü aramamı kelimelerin bazı harfleri için yönlendirebilirim çünkü tüm metne sahip olmadığınız için metnin tümüne sahip olmayabilirsiniz. olabilir, dalga belirli noktalarda metne (mesafe olarak) hizalanacaktır, böylece bu olasılığı arayabilir ve dalganın o noktasında x harfinde hangi harflerin bulunması gerektiğini bilirim.


-9

Bu üzerinde çalıştığım eski bir proje. Javascript ile MAP resimlerinin kullanımı çok kolaydır. Size nesneyi öneriyorum, okudunuz ve nasıl kullanacağınızı biliyorsunuz. MAP görüntülerini kullanmak için JQuery ve diğer sistemlere ihtiyacımız yok.

    //Copyright Cherif yahiaoui, by ELEBAN.FR

//variables de flottement.
var myInstOne = null;
var globalize = null;

var eleban_preload_images = function (name, imgs, url){
try{
    var oThis = this;
    this.images = new Array();
    this.imageshover = new Array();
    this.imagesNames = new Array(imgs.split(";"));


        for(var i=0; i < this.imagesNames[0].length; i++){
            this.images[i] = new Image();
            this.imageshover[i] = new Image();
        }

    this.url = url;

    this.GetAbsoluteurl = function () {

    var img = new Image(); img.src = url;
    url = img.src; img = null; 
        this.url = url; 

    };

    this.Preload = function () {

        for(var i=0; i < this.imagesNames[0].length; i++){
            this.images[i].src = this.url+("btn-"+this.imagesNames[0][i]+".png");
            this.imageshover[i].src = this.url+("btn-"+this.imagesNames[0][i]+"-hover.png");
        }

    };
    this.GetAbsoluteurl();
    this.Preload();
}
finally {return;}
}

var g_preloaderhover = new eleban_preload_images("loaderhover","menu;malette;reservation;cabine;facebook;map;amis","./images/");


//variable arret flottement
var g_stopflo = false;

var myObjfloater = function(name, idname, itop, differ ) {
var oThis = this; // création d'une référence vers l'objet courant
this.name = name;
this.id =idname;
this.xstep= 0.3;
this.itime = 30;
this.obj = null;
this.y = itop;
this.yadd = 0;
this.up = true;
this.pause = false;
this.differ = differ;
this.coordsimage = null;
this.objimg = null;
this.initimages = false;
this.compteur = 0;
this.over = false;
this.timeoutstop = null;
try{
this.initimage = function(){
var img = this.obj.getElementsByTagName('img')[0];
this.coordsimage = new Array(img.width, img.height);
this.objimg = img;
this.initimages = true;
};


this.myMethod = function() {
if(!g_stopflo){
    if(this.differ != 0){ 
this.differ=this.differ-0.1; 
}else{

if(this.obj){
if(this.over == false){
    this.yadd=this.yadd+0.1; this.itime = this.itime + 10;
this.obj.style.visibility = "hidden";
this.y = ((this.up)? this.y - this.yadd : this.y + this.yadd);
this.obj.style.marginTop = this.y +"%" ;
this.obj.style.visibility = "visible";

if (this.yadd > this.xstep){ 
    this.up = (this.up)? false : true;
    this.yadd = -0.1; this.itime=180;
}
}
}else{
    if (document){
        if(document.getElementById) {
         this.obj = document.getElementById(this.id); 
        //this.y = this.obj.offsetTop;
        }else{
        if(document.getElementByTagName) { this.obj = document.getElementByTagName(this.id); this.y = this.obj.offsetTop;}
        }

    }
}
}
this.timeoutstop=setTimeout(function() { oThis.myMethod(); }, this.itime);
}    
};

this.callDelayed = function() {
    // utilisation de la référence vers l'objet
if(!g_stopflo){
    this.timeoutstop=setTimeout(function() { oThis.myMethod(); }, this.itime);
}
};
}
finally {return;}
};

// special creation des zones AREA
function eleban_createallarea(){
try{
var measur = new Array("w", "h");
measur["w"] = new Array(330,570,185,300,115,390,225);
measur["h"] = new Array(460,570,295,450,100,190,115);
var ititle = new Array("Voir les menus  et nos suggestions","Repas &agrave; emporter","R&eacute;servation d&rsquo;une table","Nous contacter","Nous rejoindre sur FaceBook","Calculer votre trajet","liste des amis");
var ihref = new Array("menus.html","emporter.html","reservation.html","contact.html","likebox.html","google.html","amis.html");
var b_map = new Array(0,1,2,3,4,5,6);
b_map[0] = "71,32,240,32,249,43,289,352,280,366,102,385,90,371,51,38";
b_map[1] = "66,52,95,14,129,56,115,91,100,93,112,273,128,284,122,366,176,343,193,296,191,194,147,189,145,166,201,111,199,84,545,105,532,354,509,388,412,478,32,401,77,383,87,375,82,286,95,269,94,221,24,195,11,165,9,120,89,123,89,94,78,92,77,92,77,93,75,93,77,93,76,93,79,92";
b_map[2] = "19,25,169,38,173,112,161,113,105,103,90,125,91,262,121,269,124,281,96,293,62,289,49,281,56,268,83,264,84,121,71,98,16,90";
b_map[3] = "60,0,216,1,226,20,225,403,168,421,42,410,45,10";
b_map[4] = "31,7,72,10,82,18,88,45,88,71,76,81,29,80,17,68,16,18";
b_map[5] = "91,40,141,38,178,27,184,4,211,5,223,24,240,23,386,135,229,121,103,180,6,156,49,94";
b_map[6] = "6,32,69,18,79,6,118,7,141,2,149,10,211,17,202,28,209,30,189,62,195,70,178,74,180,90,164,90,154,107,68,101,34,104,34,98,18,97,28,84,15,84,30,65";

if (document.getElementById){
for (var i=0; i<b_map.length;i++){
var obj = document.getElementById("pc_menu"+i);
    if(obj){
    var ct = '<img class=\"pc_menu\" src=\"'+g_preloaderhover.images[i].src+'\" alt=\"\" width=\"'+measur["w"][i]+'\" height=\"'+measur["h"][i]+'\" usemap=\"#MAP_INDEX'+i+'\" \/>';
    ct+='<map name=\"MAP_INDEX'+i+'\">';
    ct+='<area shape=\"poly\" coords=\"'+b_map[i]+'\" title=\"'+ititle[i]+'\" href=\"'+ihref[i]+'\" \/>';
    ct+='<\/map>';
    obj.innerHTML = ct;
    }
}
}
}
finally {return;}
}

//preload, creation et gestion de tous les evenements


var image_resizer = function(g_layer){


    b_org_elm = new Array("w",  "h");
    b_org_elm["w"] = new Array(330,570,185,300,115,390,225);
    b_org_elm["h"] = new Array(460,570,295,450,100,190,115);

    b_map = new Array(0,1,2,3,4,5,6);
    b_map[0] = new Array(71,32,240,32,249,43,289,352,280,366,102,385,90,371,51,38);
    b_map[1] = new Array(66,52,95,14,129,56,115,91,100,93,112,273,128,284,122,366,176,343,193,296,191,194,147,189,145,166,201,111,199,84,545,105,532,354,509,388,412,478,32,401,77,383,87,375,82,286,95,269,94,221,24,195,11,165,9,120,89,123,89,94,78,92,77,92,77,93,75,93,77,93,76,93,79,92);
    b_map[2] = new Array(19,25,169,38,173,112,161,113,105,103,90,125,91,262,121,269,124,281,96,293,62,289,49,281,56,268,83,264,84,121,71,98,16,90);
    b_map[3] = new Array(60,0,216,1,226,20,225,403,168,421,42,410,45,10);
    b_map[4] = new Array(31,6,70,10,78,18,84,23,88,44,88,70,78,80,75,81,33,82,23,76,18,69,16,22,21,13);
    b_map[5] = new Array(91,40,141,38,178,27,184,4,211,5,223,24,240,23,386,135,229,121,103,180,6,156,49,94);
    b_map[6] = new Array(6,32,69,18,79,6,118,7,141,2,149,10,211,17,202,28,209,30,189,62,195,70,178,74,180,90,164,90,154,107,68,101,34,104,34,98,18,97,28,84,15,84,30,65);


    b_layer = g_layer;

//gere mouseover
    this.mouseover = function(e){
        if (!e) var e = window.event;
        var tg = (window.event) ? e.srcElement : e.target
            if (tg.nodeName){
                if(tg.nodeName == "AREA"){
                var divpar = (tg.parentNode)? tg.parentNode.parentNode : tg.parentElement.parentElement;
                    if (divpar){
                        if(divpar.nodeName == "DIV"){
                            var iiobjimg = divpar.getElementsByTagName('img');
                                if (iiobjimg){
                                    ii = parseInt(divpar.id.substring(divpar.id.length-1,divpar.id.length));
                                    iiobjimg[0].src = g_preloaderhover.imageshover[ii].src;
                                }
                        }
                    }
                }
            }
    };

//gere mouseout
    this.mouseout = function(e){
        if (!e) var e = window.event;
        tg = (window.event) ? e.srcElement : e.target
            if (tg.nodeName){
                if(tg.nodeName == "AREA"){
                divpar = (tg.parentNode)? tg.parentNode.parentNode : tg.parentElement.parentElement;
                    if (divpar){
                        if(divpar.nodeName == "DIV"){
                            var iiobjimg = divpar.getElementsByTagName('img');
                                if (iiobjimg){
                                    ii = parseInt(divpar.id.substring(divpar.id.length-1,divpar.id.length));
                                    iiobjimg[0].src = g_preloaderhover.images[ii].src;
                                }
                        }
                    }
                }
            }
    };

//ajout evenements entree sortie à la page web lors du chargement de la page
    this.init = function () {

        for(var i=0; i<b_org_elm["w"].length;i++){
            w = document.getElementById("pc_menu"+i).offsetWidth;
            h = document.getElementById("pc_menu"+i).offsetHeight;

            xa = w/parseFloat(b_org_elm["w"][i]);
            ya = h/parseFloat(b_org_elm["h"][i]);

            area = document.getElementById("pc_menu"+i).getElementsByTagName('area')[0];

            b_map2 = area.coords.split(",");
            yswitch = true;
                for(m=0; m<b_map2.length;m++){
                b_map2[m] = Math.round(parseFloat(b_map[i][m]) * ((yswitch)? xa: ya));
                yswitch = (yswitch)? false :  true;
                }
            area.coords = b_map2.join(',');
        }
    }; 


    this.resize = function () {
    clearTimeout(myInstOne.timeoutstop);
    g_stopflo=true;

    globalize.init();
    g_stopflo=false;
    myInstOne.obj = null;
    myInstOne.callDelayed();
    };


    nar = document.getElementsByTagName('area').length;

        for(var i=0; i<nar;i++){
            var elem = document.getElementsByTagName('area')[i];
            if (elem.addEventListener){
                    elem.addEventListener("onmouseover",this.mouseover,true);
                elem.addEventListener("onmouseout",this.mouseout,true);
            }else if (elem.attachEvent) {
                    elem.attachEvent("onmouseover", this.mouseover);
                    elem.attachEvent("onmouseout", this.mouseout);
            }else{
                    elem["onmouseover"] = this.mouseover;
                    elem["onmouseout"] = this.mouseout;
            }
        }

            window.onresize = this.resize;
        window.onmouseover = this.mouseover;
        window.onmouseout = this.mouseout;
}


//permet de temporiser et éviter les erreurs de chargement des objets
function temporise_Init(Lastdiv){
if(document.getElementById){
    if(document.getElementById(Lastdiv)){

    eleban_createallarea();

    myInstOne = new myObjfloater('b_menumap11', 'pc_menu1', 1, 0);

    globalize = new image_resizer(document.getElementById('pc_redim'));
    globalize.init();
        globalize.resize();



    }else{
    setTimeout(temporise_Init(Lastdiv), 30);
    }
}
}


window.onload = function () {
temporise_Init("pc_bandeau");
}

3
bu ne yapar?
user8408080
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.