Menü
Bedava
kayıt
ev  /  ÜZERİNDE/ Vücut konturunun gerçek zamanlı olarak tanınması. openCV'de bilgisayarla görü

Gerçek zamanlı vücut kontur tanıma. openCV'de bilgisayarla görü

Yevgeniy Borisov Pazartesi, 24 Temmuz 2017

Bu makale, bir görüntüdeki bir nesneyi bulma yöntemlerine genel bir bakış sağlar.

1. Giriş

Üretimde kontrolün otomasyonundan robotik araçların tasarımına kadar birçok pratik görev, görüntüdeki nesneleri bulma görevi ile doğrudan ilgilidir. Bunu çözmek için çekim koşullarına bağlı olarak iki farklı strateji kullanabilirsiniz - arka plan modelleme ve nesne modelleme.
  1. Arka Plan Simülasyonu - Bu yaklaşım, kamera sabitse, yani. çok az değişen bir geçmişimiz var ve böylece onun bir modelini oluşturabiliriz. Arka plan modelinden önemli ölçüde sapan tüm görüntü noktaları, ön plan nesneleri olarak kabul edilir. Böylece nesne algılama ve izleme problemlerini çözmek mümkündür.
  2. Nesne modelleme - bu yaklaşım daha geneldir, arka planın sürekli ve önemli ölçüde değiştiği durumlarda kullanılır. Önceki durumdan farklı olarak, burada tam olarak neyi bulmak istediğimizi bilmemiz gerekiyor, yani. nesnenin bir modelini oluşturmak ve ardından resmin noktalarını bu modele uygunluk açısından kontrol etmek gerekir.
Bazen sorunun koşulları, her iki yaklaşımı da birleştirmenize izin verir, bu, sonuçları önemli ölçüde iyileştirebilir. Sabit bir kameranın arka planını modelleme sorununun çözümü şurada bulunabilir. Daha sonra, ikinci stratejinin uygulamasını ele alacağız, yani. arama nesnesinin modellenmesi.

2. Yöntemlere genel bakış

Bu bölümde, artan karmaşıklık sırasına göre bir görüntüde nesne bulma problemini başarılı bir şekilde çözmek için kullanılabilecek yaklaşımların bir listesini sunuyoruz.
  1. Renk filtreleri - nesne renkli olarak arka plandan önemli ölçüde öne çıkıyorsa, uygun filtreyi seçebilirsiniz.
  2. Konturların seçimi ve analizi - nesnenin örneğin bir daire şeklinde olduğunu biliyorsak, görüntüdeki daireleri arayabiliriz.
  3. Desen eşleştirme - bir nesnenin görüntüsüne sahibiz, başka bir görüntüde bir nesnenin bu görüntüsüyle eşleşen alanları arıyoruz.
  4. Özel noktalarla çalışmak - nesneli resimde, başka bir görüntüde bu tür özelliklerle karşılaştırmaya çalıştığımız özellikler (örneğin açılar) arıyoruz.
  5. Makine öğrenimi yöntemleri - sınıflandırıcıyı bir nesneye sahip resimler üzerinde eğitiriz, bir şekilde görüntüyü parçalara böleriz, her parçayı bir nesnenin varlığı için sınıflandırıcı ile kontrol ederiz.
Bu yöntemlere aşağıda daha ayrıntılı olarak bakacağız.

3. Renk filtreleri

Renk filtreleri yöntemi, nesnenin arka plan renginden önemli ölçüde farklı olduğu ve aydınlatmanın tekdüze olduğu ve değişmediği durumlarda kullanılabilir. Renk filtresi yöntemi hakkında daha fazla bilgiyi şuradan okuyabilirsiniz.

4. Konturların çıkarılması ve analizi

Nesne arka planda renkli olarak belirgin bir şekilde öne çıkmıyorsa ve / veya karmaşık bir renklendirmeye sahipse, renk filtresi yönteminin kullanılması iyi sonuçlar vermeyecektir. Bu durumda, konturların seçim ve analizi yöntemini uygulamayı deneyebilirsiniz. Bunu yapmak için resimdeki sınırları seçiyoruz. Kenarlıklar, parlaklık gradyanının aniden değiştiği ve Canny yöntemi kullanılarak bulunabilen yerlerdir. Ardından, seçilen sınır çizgilerinin nesnenin geometrik konturlarına uygunluğu kontrol edilebilir, bu Hough Transform yöntemi kullanılarak yapılabilir, örneğin bir dairenin sınırları içinde arama yapabiliriz.





4: daire bulma

Bu yöntem, renk filtreleriyle birlikte de kullanılabilir. Konturların seçimi ve analizi hakkında daha fazla bilgiyi burada bulabilirsiniz. Daire arama örneğinin kaynak kodu indirilebilir.

5. Desen eşleştirme

Görüntüde çok fazla küçük ayrıntı varsa, kenar analizi zor olabilir. Bu durumda şablon eşleştirme yöntemini kullanabilirsiniz. Aşağıdakilerden oluşur - bir nesneyle bir resim çekeriz (Şek. 5) ve büyük görüntüde nesne görüntüsüyle çakışan alanları ararız (Şek. 6,7).


Şekil 5: aranacak nesne

Desen eşleştirme yöntemi ile ilgili anlatımı daha detaylı dinleyebilirsiniz. Örnek için kaynak kodu indirilebilir.

6. Özel noktalarla çalışma

Önceki bölümde açıklanan desen eşleştirme yöntemi, desen noktaları ve görüntü noktaları arasındaki tam eşleşmeleri arar. Görüntü şablon parametrelerine göre döndürülür veya ölçeklenirse, bu yöntem iyi çalışmaz. Bu sınırlamaların üstesinden gelmek için, sözde dayalı yöntemler kullanılır. tekil noktalar, onları aşağıda ele alacağız. Önemli bir nokta, görüntüde önemli ölçüde öne çıkan küçük bir alandır. Bu tür noktaları belirlemek için birkaç yöntem vardır, bunlar köşeler (Harris köşe dedektörü) veya lekeler (blob, damla) olabilir, yani. genel arka plana karşı öne çıkan oldukça net bir kenarlıkla aynı parlaklığa sahip küçük alanlar. Özel bir nokta için, sözde. tanımlayıcı - belirli bir noktanın özelliği. Tanımlayıcı, tekil noktanın belirli bir komşuluğundan, bu komşuluğun farklı bölümlerinin parlaklık gradyanlarının yönleri olarak hesaplanır. Özel noktalar için tanımlayıcıları hesaplamak için birkaç yöntem vardır: SIFT, SURF, ORB, vb. Tanımlayıcıları hesaplamak için bazı yöntemlerin patentli olduğu (örneğin, SIFT) ve ticari kullanımlarının sınırlı olduğu unutulmamalıdır. Görsellerdeki özel noktalar ve bunlarla çalışma yöntemleri hakkında dersi daha detaylı dinleyebilirsiniz. Bir görüntüdeki bir nesneyi bulmak için özel noktalar kullanılabilir. Bunu yapmak için, istenen nesnenin bir görüntüsüne sahip olmamız ve ardından aşağıdaki işlemleri yapmamız gerekiyor.
  1. Nesnenin bulunduğu resimde, nesnenin özel noktalarını arar ve tanımlayıcılarını hesaplarız.
  2. Analiz edilen görüntüde ayrıca tekil noktalar arar ve onlar için tanımlayıcıları hesaplarız.
  3. Nesnenin özel noktalarının tanımlayıcılarını ve görüntüde bulunan özel noktaların tanımlayıcılarını karşılaştırırız.
  4. Yeterli sayıda eşleşme bulunursa, alanı ilgili noktalarla işaretleriz.
Aşağıdaki Şekil 8, bir nesneyi tekil noktalara göre arama yönteminin sonuçlarını göstermektedir.


Şekil 8:özel noktalarla nesne dedektörü

Örnek için kaynak kodu indirilebilir.

7. Makine öğrenimi yöntemleri

Özel nokta kümelerini karşılaştırarak nesneleri arama yönteminin dezavantajları vardır, bunlardan biri zayıf genelleme yeteneğidir. Örneğin bir fotoğraftaki insanların yüzlerini seçmek gibi bir görevimiz varsa, yöntemimiz belirli bir fotoğrafı özel noktalara göre arayacaktır. Özel noktaların seçildiği fotoğraf, yüzlerin geri kalanı daha da kötüleşecek, çünkü büyük olasılıkla diğer özel noktalara karşılık geliyorlar. Kamera açısını değiştirirseniz sonuçlar daha da kötü olabilir. Bu sorunları çözmek için zaten makine öğrenme yöntemlerine ihtiyacımız var ve bir nesneli tek bir resme değil, farklı koşullarda bir nesnenin görüntüsüne sahip yüzlerce (ve bazı durumlarda yüz binlerce) farklı resimden oluşan tüm eğitim setlerine ihtiyacımız var. Bu makalenin ikinci bölümünde bir görüntüdeki nesneleri bulmak için makine öğrenme yöntemlerinin uygulanmasına bakacağız.

Edebiyat

  1. ES Borisov Sabit kameralar için nesne dedektörü.
    - http: //site/cv-backgr.html
  2. ES Borisov Video işleme: renk filtrelerine dayalı nesne dedektörü.
    - http: //site/cv-detektör-renk.html
  3. ES Borisov Temel görüntü işleme yöntemleri.
    - http: //site/cv-base.html
  4. Anton Konushin Bilgisayar vizyonu (2011). Anlatım 3. Basit görüntü analizi yöntemleri. Eşleşen desenler.
    - http://www.youtube.com/watch?v=TE99wDbRrUI
  5. OpenCV belgeleri: Harris Köşe Algılama
    - http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_feature2d/py_features_harris/py_features_harris.html
  6. Vikipedi: Blob_detection
    - http://en.wikipedia.org/wiki/Blob_detection
  7. Anton Konushin Bilgisayar vizyonu (2011). Ders 5. Yerel özellikler
    - http://www.youtube.com/watch?v=vFseUICis-s

Açık kaynaklı bir bilgisayar vizyonu ve makine öğrenimi kitaplığı. Bilgisayarla görme ve makine öğrenimi için hem klasik hem de modern algoritmaları içeren 2.500'den fazla algoritma içerir. Bu kütüphane, Python (bu makalede kullanıyoruz), Java, C ++ ve Matlab gibi çeşitli dillerde arayüzlere sahiptir.

Kurulum

Windows için kurulum talimatları görüntülenebilir ve Linux için -.

Bir görüntüyü içe aktarma ve görüntüleme

import cv2 image = cv2.imread ("./ path / to / image.extension") cv2.imshow ("Resim", resim) cv2.waitKey (0) cv2.destroyAllWindows ()

Not Yukarıdaki yöntemi okurken, görüntü RGB (herkesin alıştığı gibi) değil, BGR renk alanındadır. Başlangıçta o kadar önemli olmayabilir, ancak renkle çalışmaya başladığınızda bu özelliği bilmeye değer. 2 çözüm var:

  1. 1. kanalı (R - kırmızı) 3. kanal (B - mavi) ile değiştirin ve ardından kırmızı renk (255,0,0) değil (0,0,255) olacaktır.
  2. Renk alanını RGB olarak değiştirin: rgb_image = cv2.cvtColor (image, cv2.COLOR_BGR2RGB)

    Ve sonra kodda artık görüntü ile değil, rgb_image ile çalışacak.

Not Görüntünün görüntülendiği pencereyi kapatmak için herhangi bir tuşa basın. Pencereyi kapat düğmesini kullanırsanız, donmalarla karşılaşabilirsiniz.

Makale boyunca, görüntüleri görüntülemek için aşağıdaki kod kullanılacaktır:

cv2 def viewImage'ı içe aktar (görüntü, pencere adı_adı): cv2.namedWindow (adı_penceresi, cv2.WINDOW_NORMAL) cv2.imshow (pencerenin adı_adı, görüntü) cv2.waitKey (0) cv2.destroyAllWindows ()

Kırpma

Kırpma sonrası köpek

İçe aktar cv2 kırpılmış = image viewImage (kırpılmış, "Kırpıldıktan sonra köpek")

Görüntünün görüntü olduğu yer.

Boyut değişikliği

%20 oranında yeniden boyutlandırıldıktan sonra

Import cv2 scale_percent = 20 # Orijinal boyutun yüzdesi genişlik = int (img.shape * scale_percent / 100) height = int (img.shape * scale_percent / 100) dim = (genişlik, yükseklik) resize = cv2.resize (img, loş) , enterpolasyon = cv2.INTER_AREA) viewImage (yeniden boyutlandırıldı, "%20 oranında yeniden boyutlandırıldıktan sonra")

Bu işlev, orijinal görüntünün en boy oranını hesaba katar. Diğer görüntü yeniden boyutlandırma işlevleri görülebilir.

Dönüş

180 derece döndükten sonra köpek

cv2'yi içe aktar (h, w, d) = image.shape center = (w // 2, h // 2) M = cv2.getRotationMatrix2D (merkez, 180, 1.0) döndürülmüş = cv2.warpAffine (resim, M, (w) , h)) viewImage (döndürülmüş, "180 derecelik dönüşten sonra köpek")

image.shape yükseklik, genişlik ve kanalları döndürür. M - Döndürme Matrisi - görüntüyü merkez çevresinde 180 derece döndürür. -ve, görüntünün saat yönünde dönüşüdür ve + ve sırasıyla saat yönünün tersinedir.

Gri tonlamalı ve siyah beyaz eşikleme

gri tonlamalı köpek

siyah beyaz köpek

İçe aktar cv2 gray_image = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) ret, eşik_image = cv2.threshold (im, 127, 255, 0) viewImage (gray_image, "Grayscale köpek") viewImage (threshold_image, "Siyah beyaz köpek ")

gray_image, görüntünün tek kanallı sürümüdür.

Eşik işlevi, 127'den daha koyu (daha küçük) olan tüm piksellerin 0 ile değiştirildiği ve 127'den daha parlak (daha büyük) olan tüm piksellerin 255 ile değiştirildiği bir görüntü döndürür.

Netlik için, başka bir örnek:

Ret, eşik = cv2.threshold (im, 150, 200, 10)

Burada 150'den daha koyu olan her şey 10 ile değiştirilir ve daha parlak olan her şey 200 ile değiştirilir.

Eşik fonksiyonlarının geri kalanı açıklanmıştır.

Bulanıklaştırma / kenar yumuşatma

Bulanık köpek

cv2 blurred'ı içe aktar = cv2.GaussianBlur (image, (51, 51), 0) viewImage (bulanık, "Bulanık köpek")

GaussianBlur işlevi 3 parametre alır:

  1. Orijinal görüntü.
  2. 2 pozitif tek sayıdan oluşan bir demet. Rakamlar ne kadar yüksek olursa, yumuşatma gücü o kadar büyük olur.
  3. sigmaX ve sigmaY... Bu parametreler 0'a eşit bırakılırsa değerleri otomatik olarak hesaplanacaktır.

Dikdörtgen çizme

Köpeğin yüzünün etrafına bir dikdörtgen çizin

İçe aktar cv2 çıktısı = image.copy () cv2.rectangle (çıkış, (2600, 800), (4100, 2400), (0, 255, 255), 10) viewImage (çıktı, "Köpeğin yüzünü bir dikdörtgenle çerçeveleyin" )

Bu fonksiyon 5 parametre alır:

  1. Görüntünün kendisi.
  2. Sol üst köşenin koordinatı (x1, y1).
  3. Sağ alt köşe koordinatı (x2, y2).
  4. Dikdörtgen rengi (seçilen renk modeline bağlı olarak GBR / RGB).
  5. Dikdörtgenin çizgi genişliği.

Çizgi çizmek

Bir çizgi ile ayrılmış 2 köpek

cv2 çıktısını içe aktar = image.copy () cv2.line (çıktı, (60, 20), (400, 200), (0, 0, 255), 5) viewImage (çıktı, "bir çizgiyle ayrılmış 2 köpek")

Line işlevi 5 parametre alır:

  1. Çizginin çizildiği gerçek görüntü.
  2. İlk noktanın koordinatı (x1, y1).
  3. İkinci noktanın koordinatı (x2, y2).
  4. Çizgi rengi (seçilen renk modeline bağlı olarak GBR / RGB).
  5. Hat genişliği.

Resimdeki metin

Metin içeren resim

cv2 çıktısını içe aktar = image.copy () cv2.putText (çıktı, "Biz<3 Dogs", (1500, 3600),cv2.FONT_HERSHEY_SIMPLEX, 15, (30, 105, 210), 40) viewImage(output, "Изображение с текстом")

putText işlevi 7 parametre alır:

  1. Doğrudan görüntü.
  2. Resim için metin.
  3. Metnin başlangıcının sol alt köşesinin koordinatı (x, y).
  4. Algılanan yüzler: 2

    cv2'yi içe aktar image_path = "./path/to/photo.extension" face_cascade = cv2.CascadeClassifier ("haarcascade_frontalface_default.xml") image = cv2.imread (image_path) gray = cv2.cvtColor (image, cv2.COLOR_BGR_BGR .detectM) , scaleFactor = 1.1, minNeighbors = 5, minSize = (10, 10)) face_detected = "Yüzler algılandı:" + format (len (yüzler)) print (faces_detected) # (x, y , w, h için yüzlerin etrafına kareler çizin) ) yüzlerde: cv2.rectangle (resim, (x, y), (x + w, y + h), (255, 255, 0), 2) viewImage (resim, yüzler_algılandı)

    algılamaMultiScale, hem yüzleri hem de nesneleri tanımak için genel bir işlevdir. İşlevin özel olarak yüzleri araması için ona uygun kademeyi iletiyoruz.

    DetectMultiScale işlevi 4 parametre alır:

    1. Gri tonlamalı işlenmiş görüntü.
    2. Ölçek Faktörü parametresi. Bazı yüzler diğerlerinden daha yakın olduğu için diğerlerinden daha büyük olabilir. Bu parametre perspektifi telafi eder.
    3. Tanıma algoritması, nesne tanıma sırasında kayan bir pencere kullanır. minNeighbors parametresi, yüz çevresindeki nesnelerin sayısını belirler. Yani, bu parametrenin değeri ne kadar büyükse, algoritmanın mevcut nesneyi bir yüz olarak tanımlaması için o kadar çok benzer nesneye ihtiyaç duyar. Çok küçük bir değer yanlış pozitiflerin sayısını artıracak ve çok büyük olması algoritmayı daha zorlu hale getirecektir.
    4. minSize, bu alanların gerçek boyutudur.

    Konturlar - nesne tanıma

    Nesne tanıma, görüntünün renk segmentasyonu kullanılarak gerçekleştirilir. Bunun için iki fonksiyon vardır: cv2.findContours ve cv2.drawContours.

    Bu makale, renk segmentasyonu kullanarak nesne algılamayı ayrıntılarıyla anlatmaktadır. Onun için ihtiyacın olan her şey orada.

    Bir görüntüyü kaydetme

    import cv2 image = cv2.imread ("./ import / path.extension") cv2.imwrite ("./ export / path.extension", image)

    Çözüm

    OpenCV, 3D oluşturma, gelişmiş görüntü ve video düzenleme, videolardaki nesneleri ve insanları izleme ve tanımlama, bir kümeden aynı görüntüleri bulma ve çok daha fazlası için kullanılabilen hafif algoritmalara sahip mükemmel bir kitaplıktır.

    Bu kütüphane, görüntü alanında makine öğrenimi ile ilgili projeler geliştiren herkes için çok önemlidir.

Bu makale, OpenCV kullanarak bir görüntüdeki kitap sayısını saymak için bir Python betiğinin nasıl oluşturulacağını gösterecektir.

Biz ne yapacağız?

Kitapları arayacağımız görsele bir göz atalım:

Görselde dört kitabın yanı sıra kahve kupası, Starbucks fincanı, birkaç mıknatıs ve bir parça şeker gibi dikkati dağıtan eşyaların olduğunu görebiliyoruz.

Amacımız kitap olarak başka bir konu belirlemeden görseldeki dört kitabı bulmaktır.

Hangi kütüphanelere ihtiyacımız var?

Görüntüler üzerinde kitap aramak ve keşfetmek için bir sistem yazmak için bilgisayarla görme ve görüntü işleme için OpenCV kullanacağız. OpenCV'nin düzgün çalışması için NumPy'yi de kurmamız gerekiyor. Bu kütüphanelerin kurulu olduğundan emin olun!

Python ve OpenCV ile resimlerle ilgili kitap arama

Yaklaşık. tercüme Makalemizdeki kaynak kodun orijinalindeki koddan farklı olduğunu fark edebilirsiniz. Yazar muhtemelen gerekli kütüphanelerin kurulumunu depolar aracılığıyla kullanmıştır. Çok daha kolay olan pip kullanmanızı öneririz. Hatalardan kaçınmak için makalemizde verilen kodun sürümünü kullanmanızı öneririz.

Favori kod düzenleyicinizi açın, find_books.py adında yeni bir dosya oluşturun ve başlayın:

# - * - kodlama: utf-8 - * - # gerekli paketleri içe aktar numpy as np içe aktar cv2 # görüntüyü yükleyin, rengi gri tonlamalı olarak değiştirin ve görüntünün keskinliğini azaltın = cv2.imread ("example.jpg") gri = cv2.cvtColor (resim, cv2.COLOR_BGR2GRAY) gri = cv2.GaussianBlur (gri, (3, 3), 0) cv2.imwrite ("gri.jpg", gri)

OpenCV kitaplığını içe aktararak başlayalım. Diskten bir görüntü yüklemek, cv2.imread işlevi tarafından gerçekleştirilir. Burada sadece diskten yüklüyoruz ve ardından renk gamını RGB'den gri tonlamaya dönüştürüyoruz.

Ayrıca yüksek frekanslı gürültüyü azaltmak ve uygulamamızın doğruluğunu artırmak için görüntüyü biraz bulanıklaştırıyoruz. Kodu çalıştırdıktan sonra görüntü şöyle görünmelidir:

Diskten bir görüntü yükledik, onu gri tonlamaya dönüştürdük ve biraz bulanıklaştırdık.

Şimdi görüntüdeki nesnelerin kenarlarını (yani ana hatlarını) tanımlayalım:

# kenar algılama kenarlı = cv2.Canny (gri, 10, 250) cv2.imwrite ("kenarlı.jpg", kenarlı)

Artık imajımız şuna benziyor:

Görüntülerde nesnelerin ana hatlarını bulduk. Ancak, gördüğünüz gibi, bazı yollar kapalı değil - yollar arasında boşluklar var. Resmin beyaz pikselleri arasındaki boşlukları gidermek için "kapat" işlemini kullanacağız:

# bir kapatma çekirdeği oluştur ve uygula = cv2.getStructuringElement (cv2.MORPH_RECT, (7, 7)) kapalı = cv2.morphologyEx (kenarlı, cv2.MORPH_CLOSE, çekirdek) cv2.imwrite ("kapalı.jpg", kapalı)

Şimdi ana hatlardaki boşluklar kapandı:

Bir sonraki adım, görüntüdeki nesnelerin ana hatlarını gerçekten tespit etmektir. Bunun için cv2.findContours işlevini kullanacağız:

# görüntüdeki konturları bulun ve kitap sayısını sayın cnts = cv2.findContours (kapalı.kopya (), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) toplam = 0

Kitabın geometrisini düşünün.

Kitap bir dikdörtgen. Dikdörtgenin dört köşesi vardır. Bu nedenle, taslağa bakarsak ve dört köşesi olduğunu bulursak, bunun bir kitap olduğunu ve görüntüdeki başka bir nesne olmadığını varsayabiliriz.

Bir yolun kitap olup olmadığını kontrol etmek için her bir yol boyunca döngü yapmamız gerekir:

# cnts'de c için konturlar boyunca döngü: # kontur yaklaşık (pürüzsüz) peri = cv2.arcLength (c, True) yaklaşık = cv2.aboutPolyDP (c, 0.02 * peri, True) # konturun 4 köşesi varsa, biz len (yaklaşık) == 4 ise kitap olduğunu varsayalım: cv2.drawContours (image,, -1, (0, 255, 0), 4) toplam + = 1

Yolların her biri için cv2.arcLength kullanarak çevreyi hesaplıyoruz ve ardından cv2.aboutPolyDP kullanarak yolu yaklaşıklaştırıyoruz (düzgün).

Yolu tahmin etmemizin nedeni, mükemmel bir dikdörtgen olmayabilmesidir. Fotoğraftaki gürültü ve gölgeler nedeniyle kitabın tam olarak 4 köşesi olması pek olası değil. Konturu yaklaştırarak bu sorunu çözüyoruz.

Son olarak, yaklaşılacak konturun gerçekten dört köşesi olup olmadığını kontrol ederiz. Eğer öyleyse, kitabın etrafına bir taslak çizeriz ve ardından toplam kitap sayısı için sayacı arttırırız.

Ortaya çıkan resmi ve bulunan kitap sayısını göstererek bu örneği tamamlayalım:

# ortaya çıkan resim baskısını göster ("Bu resimde (0) kitap buldum" .format (toplam) cv2.imwrite ("output.jpg", resim))

Bu aşamada görselimiz aşağıdaki gibi olacaktır.

özetleyelim

Bu makalede, Python ve OpenCV ile basit görüntü işleme ve bilgisayarla görme tekniklerini kullanarak görüntülerdeki kitapları nasıl bulacağınızı öğrendiniz.

Yaklaşımımız şuydu:

  1. Diskten bir görüntü yükleyin ve onu gri tonlamaya dönüştürün.
  2. Görüntüyü biraz bulanıklaştırın.
  3. Görüntüdeki nesneleri algılamak için Canny kenar detektörü uygulayın.
  4. Yollardaki boşlukları kapatın.
  5. Görüntüdeki nesnelerin ana hatlarını bulun.
  6. Konturun bir dikdörtgen ve dolayısıyla bir kitap olup olmadığını belirlemek için kontur yaklaşımı uygulayın.

Bu yazıda kullanılan script ve görselin kaynak kodunu indirebilirsiniz.

Ana fikir, yüzün antropometrik noktalarının konumu arasındaki istatistiksel ilişkileri hesaba katmaktır. Her yüz görüntüsünde noktalar aynı sırada numaralandırılmıştır. Yüzlerin karşılaştırılması, göreceli konumlarına göre yapılır.

Yüzleri karşılaştırmak için kameraya göre aynı yüz konumunu kullanabilirsiniz. Bunun için daha çok tercih edilir.

Bir kameradan video akışı yakalama ve bir yüzü vurgulama

#Dahil etmek ad alanı cv kullanarak; int main () (// Face cascade yükle (.xml dosyası) CascadeClassifier face_cascade; face_cascade.load ("haarcascade_frontalface_alt2.xml"); Mat img; VideoCapture cap (0); while (true) (cap >> img; // cvtColor (img, img, CV_BGR2GRAY); // Yüzleri algıla std :: vektör yüzler; face_cascade.detectMultiScale (img, yüzler, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Boyut (30, 30)); // (int i = 0; i) için algılanan yüzlere daireler çizin< faces.size(); i++) { Point center(faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5); ellipse(img, center, Size(faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar(255, 0, 255), 4, 8, 0); } imshow("Detected Face", img); waitKey(1); } return 0; }

Kademeli dosyalar c: \ opencv \ build \ etc \ dizininde bulunur ... Gerekli kademeyi proje dizininde, main.cpp kaynak dosyasıyla aynı yere yerleştirin.

Yüz noktalarını vurgulama

Uygulama, OpenCV Facemark için C ++ koduna dayanmaktadır.

#Dahil etmek #Dahil etmek #Dahil etmek #Dahil etmek #Dahil etmek #Dahil etmek #include "drawLandmarks.hpp" ad alanı std kullanarak; ad alanı cv kullanarak; ad alanı cv kullanarak :: yüz; int main (int argc, char ** argv) (// Yüz Dedektörünü Yükle CascadeClassifier faceDetector ("haarcascade_frontalface_alt2.xml"); // Bir Facemark Ptr örneği oluşturun facemark = FacemarkLBF :: create(); // Yer işareti algılayıcı yüz işaretini yükle-> loadModel ("lbfmodel.yaml"); // Video yakalama için web kamerasını ayarla VideoCapture cam (0); // Bir video karesini ve gri tonlamalı Mat karesini saklamak için değişken, gri; // Bir kare oku while (cam.read (frame)) (// Yüz vektörünü bul yüzler; // FaceDetector gri tonlamalı görüntü gerektirdiği için çerçeveyi gri tonlamaya dönüştürün. cvtColor (çerçeve, gri, COLOR_BGR2GRAY); // Yüzleri algıla faceDetector.detectMultiScale (gri, yüzler); // Yer işaretleri için değişken. // Bir yüz için yer işaretleri bir nokta vektörüdür // Görüntüde birden fazla yüz olabilir. Bu nedenle, // bir nokta vektörü kullanıyoruz. vektör< vector> önemli noktalar; // Dönüm noktası dedektörünü çalıştırın bool başarısı = yüz işareti->< faces.size(); i++) { cv::rectangle(frame, faces[i], Scalar(0, 255, 0), 3); } for (int i = 0; i < landmarks.size(); i++) { drawLandmarks(frame, landmarks[i]); /*for (size_t j = 0; j < landmarks[i].size(); j++) circle(frame, Point(landmarks[i][j].x, landmarks[i][j].y), 1, Scalar(255, 0, 0), 2);*/ } } // Display results imshow("Facial Landmark Detection", frame); // Exit loop if ESC is pressed if (waitKey(1) == 27) break; } return 0; }

Uygulama projesinde dosya ile aynı yerde ana.cpp, gönderilmiş dosyalar haarcascade_frontalface_alt2.xml, drawLandmarks.hpp ve lbfmodel.yaml kodda atıfta bulunulanlardır. Kademeli dosyalar c: \ opencv \ build \ etc \ ... dizininde bulunur. drawLandmarks.hpp ve lbfmodel.yaml Facemark_LBF.rar arşivinde mevcuttur.

Kodu yapıştırdıktan sonra, OpenCV 3.4.3-vc14-vc15'in uygulamayı çalıştırmak için gereken bir dizi kitaplıktan yoksun olması nedeniyle hatalar ortaya çıktı. Kitaplığımı bağladım (opencv_new.zip dosyasını indirin) ve onu C sürücüsünün (C: \ opencv-new) kök dizinine kurdum.

Şimdi, opencv-new için yapılan tüm ayarların yapılması gerekiyor:

Windows'ta ayarların yapılması... "Ortam değişkenini değiştir" penceresine gidiyorum (Windows düğmeleri -> Sistem Araçları -> Denetim Masası -> Sistem ve Güvenlik -> Sistem -> Gelişmiş Sistem Ayarları -> Ortam Değişkenleri -> Yol -> Değiştir). Bu pencerede C: \ değişkenini oluşturuyorum opencv-yeni\ x64 \ vc14 \ bin. Windows'u yeniden başlatın.

Proje özelliklerinde ayrıca opencv_new kitaplığına da bakın (opencv yerine). "Özellik Sayfaları" penceresinde aşağıdakileri yapıyorum:

  • C / C ++ -> Genel -> Ek Dahil Etme Dizinleri -> C: \ opencv-yeni\ Dahil etmek
  • Bağlayıcı -> Genel -> Ek Kitaplık Dizinleri -> C: \ opencv-yeni\ x64 \ vc14 \ lib
  • Bağlayıcı -> Giriş -> Ek Bağımlılıklar -> opencv_core400.lib; opencv_face400.lib; opencv_videoio400.lib; opencv_objdetect400.lib; opencv_imgproc400.lib; opencv_highgui400.lib

Hata Ayıklama, başlangıçta, program bir hata üretir. Sürüm için başlatma başarılı.


Görüntü filtreleme ve yüz tanıma için özelliklerin seçilmesi

Yüzün noktalı çerçevesi, nesnel ve öznel faktörlere bağlı olarak farklı şekillerde görüntülenir.

Objektif faktörler, yüzün kameraya göre konumudur.

Öznel faktörler - düzensiz veya zayıf aydınlatma, duygulara bağlı yüz bozulması, şaşı gözler vb. Bu durumlarda, tel kafes doğru olmayabilir, hatta noktalar yüzünden yırtılabilir:

Bazen bu tür görüntüler video çekimi sırasında atlanır. Hem eğitim hem de tanıma sırasında filtrelenmeleri gerekir.

Bazı noktalar en kararlı ve bilgilendiricidir. Kameraya göre konumundan bağımsız olarak yüze sıkı bir şekilde takılırlar. Ek olarak, yüzün özelliklerini iyi karakterize ederler. Bu noktalar, bir özellik sistemini modellemek için bir temel olarak kullanılabilir.

Yüzleri karşılaştırmak için aynı yüz konumunda 2B nokta tel kafes kullanabilirsiniz. Yüzünüzün kameraya göre en bilgilendirici konumu nedir? Açıkçası önden. Adli bilimin tam bir yüz ve profil fotoğrafı çekmesi boşuna değil. Şimdilik kendimizi tam yüzle sınırlayacağız.

Tüm işaretler (mesafeler) boyutsuz (normalize edilmiş), yani bir boyut (mesafe) ile ilişkili olmalıdır. Bunun için en uygun ölçü sanırım gözlerin köşe noktalarının orta noktaları arasındaki mesafedir. Örneğin, yer işaretleri dizisinde gerçekte tanımlanan gözlerin dış köşe noktaları neden olmasın? Gerçek şu ki, bir renk değişikliğine, şaşkınlık ifadesine, göz kırpmaya vb. yanıt verirken gözlerin köşe noktaları birbirinden ayrılır (yaklaşır). Gözlerin merkezleri arasındaki mesafe bu dalgalanmaları nötralize eder ve bu nedenle daha çok tercih edilir.

İlk yaklaşımda hangi işareti temel alacağız? Burun köprüsünün tepesinden çenenin altına kadar olan mesafeyi varsayıyorum. Fotoğrafa bakılırsa, bu işaret farklı kişiler için önemli ölçüde farklılık gösterebilir.

Bu nedenle, eğitim ve karşılaştırma için öznitelikler oluşturmadan önce, öznel veya nesnel nedenlerle yüzün (tam yüz) doğru ön görüntüsü olmayan, video yakalama ile elde edilen yüzlerin nokta çerçevelerini filtrelemek gerekir.

Yalnızca aşağıdaki kriterlere uyan noktasal tel kafesleri bırakıyoruz:

  • Gözlerin uç noktalarından geçen düz çizgi (göz çizgisi), burnun uç noktalarından geçen çizgiye (burun çizgisi) diktir.
  • Gözlerin çizgisi, ağzın köşelerinden geçen düz çizgiye (ağız çizgisi) paraleldir.
  • Burun çizgisine göre yukarıdaki noktaların simetrisi gözlenir.
  • Gözlerin köşe noktaları (dış ve iç) aynı düz çizgi üzerindedir.

Tüm işaretleri takip eden önden görüntülere bir örnek:

Filtrelenen resimlere bir örnek:

Hangi işaretlerin görüntüyü geçmediğini kendiniz belirlemeye çalışın.

Filtreleme ve yüz tanıma sağlayan özellikler nasıl resmileştirilir? Temel olarak, noktalar arasındaki mesafeleri belirleme koşullarına, paralellik ve diklik koşullarına dayanırlar. Bu tür işaretleri resmileştirme görevi konuda ele alınmaktadır.

Noktaların 2D tel çerçevesi ile yüz tanıma algoritması

Yüz tel kafes noktalarının koordinatları, başlangıçta, pencerenin sol üst noktasına sabitlenen koordinat sisteminde ayarlanır. Bu durumda Y ekseni aşağı doğru yönlendirilir.

Özellikleri tanımlama kolaylığı için, X ekseni gözlerin orta noktaları arasındaki segmentten geçen ve Y ekseni orta noktasından yukarı yönde bu segmente dik olan özel bir koordinat sistemi (UCS) kullanıyoruz. UCS koordinatları (-1'den +1'e kadar) normalize edilir - gözlerin orta noktaları arasındaki mesafe ile ilişkilidir.

UCS, özellikleri tanımlamada kolaylık ve basitlik sağlar. Örneğin, yüzün önden görünümdeki konumu, gözlerin karşılık gelen noktalarının burun çizgisine göre simetri işareti ile belirlenir. Bu özellik, burun çizgisinin Y ekseni ile çakışmasıyla, yani X1 = X2 = 0, burada X1 ve X2, UCS'de burnun uç noktalarının (27 ve 30) koordinatlarıdır.

SC penceresine göre belirleme

Sol ve sağ gözün orta noktalarının koordinatları (Sol ve Sağ):

XL = (X45 + X42) / 2; YL = (Y45 + Y42) / 2; XR = (X39 + X 36) / 2; YR = (Y39 + Y 36) / 2;

UCS'nin başlangıcı:

X0 = (XL + XR) / 2; Y0 = (YL + YR) / 2;

X ve Y eksenleri boyunca gözlerin orta noktaları arasındaki mesafeler:

DX = XR - XL; DY = YR - YL;

Gözlerin orta noktaları arasındaki gerçek mesafe L (Pisagor teoremine göre):

L = kare (DX ** 2 + DY ** 2)

UCS dönüş açısının trigonometrik fonksiyonları:

Pencereli CS'deki koordinatlardan UCS'deki koordinatlara gidin X0, Y0, L, sin AL, cos AL parametrelerini kullanarak:

X_User_0 = 2 (X_Window - X0) / L;

Y_User_0 = - 2 (Y_Window - Y0) / L;

X_Kullanıcı= X_User_0 * cos_AL - Y_User_0 * sin_AL;

Y_Kullanıcı= X_User_0 * sin_AL + Y_User_0 * cos_AL;

Görüntü filtrelemeyi uygulama işaretleri sürekli kontrol etmek:

1.Burun ve göz çizgilerinin dikliğinin yanı sıra gözlerin köşe noktalarının simetrisinin bir işareti... Burun çizgisi 27 ve 30 noktaları ile tanımlanır (bkz. şekil c). UCS'deki bu noktaların koordinatları X1 = X2 = 0 ise (yani, burun çizgisi Y ekseni ile çakışıyorsa) her iki işaret de yerine getirilir.

2.Göz çizgisi ile ağız çizgisinin paralellik belirtisi... Ağız çizgisi 48 ve 54 noktaları ile tanımlanır (bkz. şekil c). UCS Y1-Y2 = 0 ise karakteristik karşılanır.

3. Ağzın köşe noktalarının simetri belirtisi... Ağız çizgisi 48 ve 54 noktaları ile tanımlanır (bkz. şekil c). UCS X1 + X2 = 0 ise özellik yerine getirilir

4. "Gözlerin köşe noktaları aynı düz çizgi üzerinde" işareti... Çizgiler nokta çiftleriyle tanımlanır: (36 ve 45) ve (39 ve 42). Nitelik 1 testi zaten geçilmiş olduğundan, UCS'de yalnızca Y2-Y1 = 0 niteliğini yalnızca 36 ve 39 noktaları için tanımlamak yeterlidir.

Sıfıra mutlak bir eşitlik olamaz, bu nedenle özellikler kabul edilebilir küçük bir değerle karşılaştırılır.

Yüzleri tek bir özelliğe göre karşılaştırma programı

Burun köprüsü noktaları ile çene arasındaki mesafe bir işaret olarak alınır (Yer işaretleri 27 ve 8, bkz. şekil c). Normalleştirilmiş özellik, UCS'de şu oran ile tanımlanır: (Y1 - Y2) / L, burada L, gözlerin merkezleri arasındaki mesafedir. Programı eğitirken, belirli bir kişi için bir işaret, izlenen kişinin yanında görüntülenen bir sayı ile belirlenir (kodun bu kısmı programda yorumlanır). Tanıma sırasında, bir özelliğin değeri, her kişi için programa girilen belirli bir özellik ile karşılaştırılır. Karşılaştırma olumluysa, tanımlayıcısı yüzün yanında görünür.

Program ayrıca 15 yaş daha genç olduğum ve hatta bıyıklı olduğum fotoğrafı da tanıyor. Fotoğraftaki fark önemli, herkes yakalayamayacak. Ancak bir bilgisayar programı kandırılamaz.

Kontrol görevleri:

  1. Programa aşina olun.
  2. Yüzünüz ve birkaç iş arkadaşınız için özelliğin anlamını belirleyin.
  3. Kişilerin (kendiniz ve meslektaşlarınız) tanımlanması için programı test edin.

#Dahil etmek #Dahil etmek #Dahil etmek #Dahil etmek #Dahil etmek #Dahil etmek #include "drawLandmarks.hpp" ad alanı std kullanarak; ad alanı cv kullanarak; ad alanı cv kullanarak :: yüz; int main (int argc, char ** argv) (// Yüz Dedektörünü Yükle CascadeClassifier faceDetector ("haarcascade_frontalface_alt2.xml"); // Bir Facemark Ptr örneği oluşturun facemark = FacemarkLBF :: create(); // Yer işareti algılayıcı yüz işaretini yükle-> loadModel ("lbfmodel.yaml"); // Video yakalama için web kamerasını ayarla VideoCapture cam (0); // Bir video karesini ve gri tonlamalı Mat karesini saklamak için değişken, gri; // Bir kare oku while (cam.read (frame)) (// Yüz vektörünü bul yüzler; // FaceDetector gri tonlamalı görüntü gerektirdiği için çerçeveyi gri tonlamaya dönüştürün. cvtColor (çerçeve, gri, COLOR_BGR2GRAY); // Yüzleri algıla faceDetector.detectMultiScale (gri, yüzler); // Yer işaretleri için değişken. // Bir yüz için yer işaretleri bir nokta vektörüdür // Görüntüde birden fazla yüz olabilir. Bu nedenle, // bir nokta vektörü kullanıyoruz. vektör< vector> önemli noktalar; // Yer işareti dedektörünü çalıştır bool başarısı = yüz işareti-> sığdır (çerçeve, yüzler, yer işaretleri); if (success) (// Başarılı olursa, (size_t i = 0; i) için yer işaretlerini yüzde işleyin< faces.size(); i++) { cv::rectangle(frame, faces[i], Scalar(0, 255, 0), 3); } for (int i = 0; i < landmarks.size(); i++) { //if((i >= 30) && (i<= 35)) drawLandmarks(frame, landmarks[i]); for (size_t j = 0; j < landmarks[i].size(); j++) { circle(frame, Point(landmarks[i][j].x, landmarks[i][j].y), 1, Scalar(255, 0, 0), 2); } line(frame, Point(landmarks[i].x, landmarks[i].y), Point(landmarks[i].x, landmarks[i].y), Scalar(0, 0, 255), 2); float XL = (landmarks[i].x + landmarks[i].x) / 2; float YL = (landmarks[i].y + landmarks[i].y) / 2; float XR = (landmarks[i].x + landmarks[i].x) / 2; float YR = (landmarks[i].y + landmarks[i].y) / 2; line(frame, Point(XL, YL), Point(XR, YR), Scalar(0, 0, 255), 2); float DX = XR - XL; float DY = YR - YL; float L = sqrt(DX * DX + DY * DY); float X1 = (landmarks[i].x); float Y1 = (landmarks[i].y); float X2 = (landmarks[i].x); float Y2 = (landmarks[i].y); float DX1 = abs(X1 - X2); float DY1 = abs(Y1 - Y2); float L1 = sqrt(DX1 * DX1 + DY1 * DY1); float X0 = (XL + XR) / 2; float Y0 = (YL + YR) / 2; float sin_AL = DY / L; float cos_AL = DX / L; float X_User_0 = (landmarks[i].x - X0) / L; float Y_User_0 = -(landmarks[i].y - Y0) / L; float X_User27 = X_User_0 * cos_AL - Y_User_0 * sin_AL; float Y_User27 = X_User_0 * sin_AL + Y_User_0 * cos_AL; X_User_0 = (landmarks[i].x - X0) / L; Y_User_0 = -(landmarks[i].y - Y0) / L; float X_User30 = X_User_0 * cos_AL - Y_User_0 * sin_AL; float Y_User30 = X_User_0 * sin_AL + Y_User_0 * cos_AL; if (abs(X_User27 - X_User30) <= 0.1) { //putText(frame, std::to_string(abs(L1 / L)), Point(landmarks[i].x, landmarks[i].y), 1, 2, Scalar(0, 0, 255), 2); if (abs((L1 / L) - 1.6) < 0.1) { putText(frame, "Roman", Point(landmarks[i].x, landmarks[i].y), 1, 2, Scalar(0, 0, 255), 2); } if (abs((L1 / L) - 1.9) < 0.1) { putText(frame, "Pasha", Point(landmarks[i].x, landmarks[i].y), 1, 2, Scalar(0, 0, 255), 2); } if (abs((L1 / L) - 2.1) < 0.1) { putText(frame, "Svirnesvkiy", Point(landmarks[i].x, landmarks[i].y), 1, 2, Scalar(0, 0, 255), 2); } } putText(frame, "Incorrect", Point(landmarks[i].x, landmarks[i].y), 1, 2, Scalar(0, 0, 255), 2); } } // Display results imshow("Facial Landmark Detection", frame); // Exit loop if ESC is pressed if (waitKey(1) == 27) break; } return 0; }

Bir robot için dış dünya hakkında en önemli bilgi kaynakları onun optik sensörleri ve kameralarıdır. Görüntüyü aldıktan sonra durumu analiz etmek ya da karar vermek için onu işlemek gerekir. Önceden söylediğim gibi, Bilgisayar görüşü görüntülerle çalışmanın birçok yöntemini birleştirir. Robotun çalışması sırasında kameralardan gelen video bilgilerinin kontrolör üzerinde çalışan bir program tarafından işlendiği varsayılmaktadır. Sıfırdan kod yazmamak için hazır yazılım çözümlerini kullanabilirsiniz. Şu anda birçok hazır bilgisayarlı görü kitaplığı var:

  • Matrox Görüntüleme Kitaplığı
  • kamelya kitaplığı
  • eVision'ı aç
  • halkon
  • libCVD
  • Opencv
  • vesaire…
SDK verileri, işlevsellik, lisans koşulları ve kullanılan programlama dilleri bakımından büyük farklılıklar gösterebilir. üzerinde duracağız Opencv... Hem eğitim amaçlı hem de ticari kullanım için ücretsizdir. Optimize edilmiş C/C++ ile yazılmıştır, C, C++, Python, Java arayüzlerini destekler ve 2500'ün üzerinde algoritma içerir. Standart görüntü işleme işlevlerine (filtreleme, bulanıklaştırma, geometrik dönüşümler vb.) ek olarak bu SDK, fotoğraftaki bir nesneyi algılamayı ve onun "tanımasını" içeren daha karmaşık görevleri çözmenize olanak tanır. Tespit ve tanıma görevlerinin tamamen farklı olabileceği anlaşılmalıdır:
  • belirli bir nesnenin aranması ve tanınması,
  • aynı kategorideki nesneleri arayın (tanınmadan),
  • sadece nesne tanıma (onunla birlikte hazır bir görüntü).
Bir görüntüdeki özellikleri tespit etmek ve bir eşleşme olup olmadığını kontrol etmek için OpenCV aşağıdaki yöntemlere sahiptir:
  • Yönlendirilmiş Gradyanların Histogramı (HOG) - yayaları tespit etmek için kullanılabilir
  • Viola-Jones algoritması - yüzleri bulmak için kullanılır
  • SIFT (Scale Invariant Feature Transform) özellik algılama algoritması
  • SURF (Hızlandırılmış Sağlam Özellikler) özelliği algılama algoritması
Örneğin, SIFT, bir nesneyi tanımlamak için kullanılabilecek nokta kümelerini algılar. Yukarıdaki yöntemlere ek olarak, OpenCV, algılama ve tanıma için başka algoritmaların yanı sıra k-en yakın komşular, sinir ağları, destek vektör makineleri vb. gibi makine öğrenimi ile ilgili bir dizi algoritmaya sahiptir. Genel olarak, OpenCV bir bilgisayarla görme sorunlarının büyük çoğunluğunu çözmek için yeterli araç seti. Algoritma SDK'ya dahil değilse, kural olarak sorunsuz programlanabilir. Ayrıca, OpenCV'ye dayalı olarak kullanıcılar tarafından yazılan algoritmaların birçok yazar versiyonu vardır. Ayrıca, OpenCV'nin son yıllarda çok genişlediği ve biraz "ağır" hale geldiği de belirtilmelidir. Bu bağlamda, farklı meraklı grupları OpenCV'ye dayalı "hafif" kütüphaneler yaratıyor. Örnekler: SimpleCV, liuliu ccv, tinycv ... Faydalı siteler
  1. http://opencv.org/ - Projenin ana sitesi
  2. http://opencv.willowgarage.com/wiki/ - Eski sürümler için belgeler içeren eski proje sitesi