Ruby'de Renk Tabanlı Görsel Arama Motoru Oluşturma
Yayınlanan: 2022-03-11Bir resmin bin kelimeye bedel olduğu söylenir. Ve birçok yönden resimlerdeki kelimeler renklerdir. Renkler hayatımızın ayrılmaz bir parçasıdır ve önemlerini inkar edemeyiz.
Bir resme bakarken, çoğu zaman onun bir kısmındaki rengi belirlemeye çalıştık. Hepimiz yapmayı denedik ama asla ayrıntılı olarak yapmadık. Bir görüntüden renkleri tanımlamamız istendiğinde, onları kırmızı, mavi ve yeşil gibi belirli renk adlarını kullanarak etiketleme eğilimindeyiz. Bununla birlikte, bir görüntüdeki en belirgin 30 rengi çıkarmamız istenirse, gözümüz bunları kolayca algılayamaz veya tanımlayamaz. Camalian tamamen bununla ilgili. Görüntülerden renkleri çıkarmanıza ve onlarla oynamanıza yardımcı olur.
Bu makalede, renk uzaylarının neyle ilgili olduğuna, Camalian Ruby mücevherinin neler sunduğuna ve renkleri tanımlamak ve ayırt etmek için kullanan basit bir görsel arama motoru yapmak için nasıl kullanılabileceğine bir göz atacağız.
Renkler Uzay
Başlamadan önce, renklerle ilgili bazı temel kavramları anlayalım. Ekranlarımızda sunulan görüntüler, iki boyutlu bir piksel dizisi kullanılarak temsil edilir. Görüntü dosyaları farklı şekillerde kodlanabilse de, verilerin sıkıştırılması ve kodunun çözülmesinden sonraki kaba temsil aynıdır. Bu 2B dizi tabanlı gösterimde, renkli bir görüntüdeki her pikselin üç bileşeni vardır: kırmızı, yeşil ve mavi. Bir kağıda basılan resimler de noktaların iki boyutlu bir yüzeyi olsa da, noktaların kendileri genellikle dört bileşenli mürekkebin karışımıdır: camgöbeği, macenta, sarı ve siyah. Renkleri temsil etmek için kullanılan diğer bazı teknikler arasında bunlara renk uzayları denir. En popüler olarak kullanılan renk uzaylarından bazıları RGB, CMYK, HSL ve HSV'dir. CMYK çoğunlukla baskı endüstrisinde kullanılırken, diğerleri dijital medyada kullanılmaktadır.
RGB Renk Alanı
CRT ekranlar, LCD'ler veya ışığı ileten telefonlar gibi herhangi bir fiziksel elektronik ortam, üç bileşen kullanarak renk üretir: kırmızı, yeşil, mavi. İnsan gözü, gözdeki üç tip renk reseptörünü uyararak milyonlarca rengi algılayabilir. Bu reseptörleri R, G ve B ile ilişkilendirebilirsiniz.
İdeal olarak, her bir renk bileşeni, değerleri 0 ile 255 arasında değişebilen bir bayt içinde depolanır.
HSL ve HSV Renk Alanı
Bir küp üzerinde RGB renk uzayını düzenlemek oldukça zordur. Onu bir küp ve/veya renk tekerleği üzerinde temsil etmeye çalışmanın sonuçları zayıftır. Milyonlarca veya renkle çalışırken, her bir renk tonu RGB renk uzayında düzgün şekilde hizalanamaz.
Bu sorunun üstesinden gelmek için 1970'lerde araştırmacılar HSV (Ton, Doygunluk, Değer) ve HSL (Ton, Doygunluk, Açıklık) renk uzaylarını tanıttı. Bu renk uzaylarının her ikisi de bir renk tekerleğinde düzgün bir şekilde hizalanabilir ve üzerindeki çeşitli renk tonlarını tanımlamayı kolaylaştırır.
Renkler için Yakut Mücevher
Camalian tamamen renklerle ilgilidir. Camalian ile yapabileceğiniz en basit şeylerden biri, bir görüntüde kullanılan her bir renk tonunu belirlemektir.
Diyelim ki 15 farklı renge sahip bir görüntümüz var.
Renk örneğinden renkleri belirlemek, onları görüntünün kendisinden tanımlamaktan kesinlikle daha kolaydır. Ayrıca, bu basit bir görüntüdür ve çekilen gerçek fotoğraflar, renk paletleri söz konusu olduğunda genellikle çok daha çeşitlidir. Görüntüden renk değerlerini çıkarmak oldukça zor kod parçaları gerektirir ve Camalian burada devreye girer. Bu zor şeyleri sizin için yapar, böylece bir görüntüden renkle ilgili bilgileri kolaylıkla ayıklayabilirsiniz.
Başlarken
Camalian ile renkleri ayıklamak kolaysa, yüklemek daha da kolaydır. Ruby gem'i aşağıdakileri yürüterek kurabilirsiniz:
gem install camalian
Ve bu gem'i kullanmak için onu doğrudan Ruby betiğinize ekleyebilirsiniz:
require 'camalian'
Renkleri Çıkarma
Bir görüntüden renkleri çıkarmak için önce onu belleğe yüklememiz ve görüntü nesnesi üzerindeki yöntemleri kullanmamız gerekir:
image = Camalian::load( File.join( File.dirname(__FILE__), 'colormap.png') ) colors = image.prominent_colors(15) puts colors.map(&:to_hex)
Bu kod parçacığı, komut dosyasının bulunduğu dizinden "colormap.png" adlı bir resim yükler ve ondan en belirgin 15 rengi çıkarır.
Çalıştırmak için dosyayı “color_test1.rb” olarak kaydedin ve ruby color_test1.rb
ile kabukta çalıştırın. Aşağıdakine benzer bir çıktı üretmelidir:
["#318578", "#41b53f", "#2560a3", "#359169", "#2154b1", "#4dda15", "#1d48bf", "#1530dc", "#296d94", "#193dcd", "#3da94d", "#45c131", "#3da84e", "#2d7986", "#193cce"]
Ve bu kadar kolay! Yukarıdaki resimde kullanılan 15 rengi az önce çıkardık. Döngüsel kod kullanarak veya daha kötüsünü gözlerinizle yapmaya çalıştığınızı hayal edebiliyor musunuz? İşleri bir çentikle çevirelim. Bu sefer Camalian'ı daha detaylı bir resim üzerinde kullanmaya çalışacağız:
Bu görüntüde aynı betiği çalıştırarak aşağıdakileri elde ederiz:
[“#210b03”, “#723209”, “#974d09”, “#ae5d08”, “#c77414”, “#d77f15”, “#ffea54”, “#94651f”, “#b66a15”, “#c25f06”, “#fdd94d”, “#d39a39”, “#efa540”, “#fffffe”, “#fff655”]
Yukarıda üretilen renk değerleri dizisini görselleştirmeye çalışmak bize şöyle bir şey verir:
Palet iyi, ancak çıkarılan renklerde belirli bir desen yok. Renk değerlerini benzerliğe göre sıralayalım ve bunun işe yarayıp yaramadığını görelim. Tek yapmamız gereken, diziyi konsola yazdırmadan önce bir işlev daha çağırmaktır:

colors = image.prominent_colors(15).sort_similar_colors
Peki ya nispeten daha açık renkler elde etmek istersek? Sadece %40 koyu veya başka bir deyişle açıklık (HSL renk uzayında) değeri 0 ile 40 arasında olan renkler istiyor olabiliriz. Tek yapmamız gereken:
colors = image.prominent_colors(15).light_colors(0, 40)
Görsel Arama Motorunu Yapmak
Artık Camalian kullanarak renklerle başa çıkmanın ne kadar kolay olduğunu bildiğimize göre, görüntüleri yüklemenize ve renklerine göre indekslenmesini sağlayan basit bir web uygulaması oluşturalım. Kısaca, bir Ruby uygulaması oluşturmayla ilgili çeşitli ayrıntıları atlayacağız. Bunun yerine, renkler ve Camalian kullanımıyla ilgili ayrıntılara odaklanacağız.
Bu Ruby uygulamasının kapsamına gelince, onu resim yüklemelerini işlemekle, bunları kaydetmeden önce resimden renkleri çıkarmakla ve seçilen renk ve eşiğe göre yüklenen resmi aramakla sınırlayacağız.
Aşağıda, uygulamamızın yapısını açıklamak için bir model diyagramı verilmiştir:
Yüklenen her resim, bir PortfolioItem nesnesi kullanılarak temsil edilir. Her Color nesnesi, yüklenen görüntüler aracılığıyla keşfedilen benzersiz renkleri temsil eder ve son olarak PortfolioColor, her görüntü ile içinde bulunan renkler arasındaki ilişkiyi temsil eder.
Uygulamanın çoğu parçası oldukça standarttır, özellikle konu görüntü yüklemelerini işlemek, model varlıkları oluşturmak ve bunları veritabanında kalıcı kılmak vb. olduğunda. Bir Ruby geliştiricisi olmanız durumunda, bunlar hiç de akıllıca olmamalıdır. Yüklenen görüntüden rengi çıkarmak için kullanılan yöntem aşağıdadır:
after_save :extract_colors private def extract_colors image = Camalian::load(self.image.path) colors = image.prominent_colors(self.color_count.to_i).sort_similar_colors colors.each do |color| unless c = Color.where(r: color.r, g: color.g, b: color.b).first c = Color.create(r: color.r, g: color.g, b: color.b, h: color.h, s: color.s, l: color.l) end self.colors << c end end
Bu, renk paletini çıkararak ve veritabanına kaydederek yardımcı olur. Yalnızca belirli sayıda belirgin rengi nasıl çıkardığımıza dikkat edin (kullanıcının görüntüyü yüklerken tanımlayabileceği bir şey).
Bir kullanıcı web kullanıcı arayüzündeki form aracılığıyla bir resim gönderdiğinde, resim bir gönderi işleyicisi aracılığıyla alınır ve bunun için yeni bir PortfolioItem oluşturulur. Bu yöntem, Extract_colors , bir portföy öğesi veritabanında kalıcı olduğunda çağrılır.
Renk paletini sayfalarda oluşturabilmek için basit bir yardımcı kullanıyoruz:
module PortfolioItemsHelper def print_color_palette(colors) color_string = '' colors.each do |c| color_string += content_tag :span, ' ', style: "display: block; float: left; width: 35px; height: 35px; background: #{c.to_hex}" end content_tag :div, color_string.html_safe, style: "display: inline-block;" end end
Esasen, her biri arka plan rengi ayıklanan belirgin renklerden birine ayarlanmış olan küçük kare açıklıklara sahip bir div oluşturur.
Son olarak, aramayı uygulamak için biraz matematik ve mantık kullanmalıyız:
class PortfolioSearchForm include ActiveModel::Model attr_accessor :color, :similarity validates_presence_of :color, :similarity def color_object @color_object ||= Camalian::Color.new(self.color) end def color_range(color, level) (color_object.send(color) - level)..(color_object.send(color) + level) end def colors_by_rgb level = self.similarity.to_i * 255 / 100.0 Color.where(r: color_range(:r, level), g: color_range(:g, level), b: color_range(:b, level)) end def colors_by_hsl level = self.similarity.to_i Color.where(h: color_range(:h, (self.similarity.to_i * 30 / 100.0) ), s: color_range(:s, level), l: color_range(:l, level)) end end
Colours_by_hsl metodu ile sorgumuzla eşleşen tüm Color varlıklarını getirebiliriz. Ve bunlarla yüklenen tüm resimleri tanımlayabilir ve arama sonucu sayfamızı oluşturabiliriz. Sorgunun kendisi oldukça basittir. Belirli bir renk ve bir benzerlik değeri verildiğinde, her renk bileşeni için bir değerler aralığı hesaplanır.
Ve bu hemen hemen tüm zor kısımlar.
Denemek
Kodun tamamını GitHub'da bulabilirsiniz. Bu uygulamanın bir örneğini Heroku'ya dağıtabilir veya yerel olarak deneyebilirsiniz:
git clone https://github.com/nazarhussain/camalian-sample-app.git cd camalian-sample-app bundle install rake db:migrate rails s
Son uygulama şuna benzer:
Uygulama çalıştığında, web tarayıcınızı http://localhost:3000'e yönlendirin. Ekrandaki formu kullanarak, çeşitli renk paletlerinden birkaç resim yükleyin. Ardından, görselleri renge göre aramak için sağ üst köşedeki arama alanını kullanın. Eşik açılır menüsü, görüntülerin renklerini eşleştirmek için farklılık toleransını belirtmenize olanak tanır.
Sıradaki ne?
Bu makalede oluşturduğumuz demo uygulaması oldukça basittir, ancak olasılıklar sonsuzdur! Bu kitaplığın diğer bazı pratik kullanımları şunları içerebilir:
- Kullanıcıların karanlık profil resimleri yüklemesini kısıtlama
- Sitenin renk temasını kullanıcı tarafından yüklenen bazı resimlere uyarlayın
- Tasarım yarışmaları için, gönderimleri renk paleti gereksinimlerine göre otomatik olarak doğrulayın
Kütüphaneyi GitHub'da daha fazla keşfedebilir ve kaynak kodunu kontrol edebilirsiniz. Sorun oluşturarak hataları bildirmekten veya çekme istekleri göndererek katkıda bulunmaktan çekinmeyin.