Ruby에서 색상 기반 이미지 검색 엔진 구축

게시 됨: 2022-03-11

그림은 천 마디 말의 가치가 있다고 합니다. 그리고 여러 면에서 그림의 단어는 색상입니다. 색상은 우리 삶의 필수적인 부분이며 그 중요성을 부인할 수 없습니다.

이미지를 볼 때 우리는 종종 이미지의 일부에서 색상을 식별하려고 시도했습니다. 우리는 모두 시도했지만 세부적으로는 한 적이 없습니다. 이미지에서 색상을 식별하라는 요청을 받으면 빨강, 파랑 및 녹색과 같은 특정 색상 이름을 사용하여 레이블을 지정하는 경향이 있습니다. 그러나 이미지에서 가장 눈에 띄는 30가지 색상을 추출하도록 요청하면 우리의 눈은 이를 쉽게 감지하거나 식별할 수 없습니다. Camalian은 이것에 관한 것입니다. 이미지에서 색상을 추출한 다음 가지고 노는 데 도움이 됩니다.

Camalian: Ruby용 Ultiamte 색상 선택기

이 기사에서는 색상 공간이 무엇인지, Ruby gem Camalian이 제공해야 하는 것이 무엇인지, 색상을 사용하여 색상을 식별하고 구별하는 간단한 이미지 검색 엔진을 만드는 데 사용할 수 있는 방법을 살펴보겠습니다.

색상 공간

시작하기 전에 먼저 색상에 대한 몇 가지 기본 개념을 이해하겠습니다. 화면에 표시되는 이미지는 2차원 픽셀 배열을 사용하여 표현됩니다. 이미지 파일은 다른 방식으로 인코딩될 수 있지만 데이터 압축을 풀고 디코딩한 후의 조잡한 표현은 동일합니다. 이 2d 배열 기반 표현에서 컬러 이미지의 각 픽셀에는 빨강, 녹색 및 파랑의 세 가지 구성 요소가 있습니다. 종이에 인쇄된 그림은 점의 2차원 표면이기도 하지만 점 자체는 일반적으로 시안, 마젠타, 노랑 및 검정의 4가지 구성 요소 잉크의 혼합물입니다. 색상을 나타내는 데 사용되는 다른 기술 중에서 이러한 것을 색상 공간이라고 합니다. 가장 널리 사용되는 색상 공간 중 일부는 RGB, CMYK, HSL 및 HSV입니다. CMYK는 대부분 인쇄 산업에서 사용되는 반면 나머지는 모두 디지털 미디어에서 사용됩니다.

RGB 색 공간

빛을 전송하는 CRT 화면, LCD 또는 전화와 같은 물리적 전자 매체는 빨강, 녹색, 파랑의 세 가지 구성 요소를 사용하여 색상을 생성합니다. 인간의 눈은 눈에 있는 세 가지 유형의 색상 수용체를 자극하여 수백만 가지 색상을 감지할 수 있습니다. 이러한 수용체를 R, G 및 B와 연관시킬 수 있습니다.

이상적으로는 각 색상 구성 요소는 0에서 255 사이의 값을 가질 수 있는 바이트에 저장됩니다.

HSL 및 HSV 색 공간

큐브에 RGB 색상 공간을 배열하는 것은 다소 어렵습니다. 큐브 및/또는 색상환으로 표현하려고 하면 결과가 좋지 않습니다. 백만 개 이상의 색상으로 작업하는 동안 각 색상 색조는 RGB 색상 공간에서 적절하게 정렬될 수 없습니다.

루비 이미지 검색 엔진

이러한 문제를 극복하기 위해 1970년대에 연구자들은 HSV(Hue, Saturation, Value) 및 HSL(Hue, Saturation, Lightness) 색 공간을 도입했습니다. 이 두 색상 공간은 모두 색상환에 적절하게 정렬될 수 있으며 색상환의 다양한 색조를 더 쉽게 식별할 수 있습니다.

색상에 대한 루비 보석

Camalian은 색상에 관한 것입니다. Camalian으로 할 수 있는 가장 간단한 작업 중 하나는 이미지에 사용된 색상의 각 색조를 식별하는 것입니다.

15가지 다른 색상을 가진 이미지가 있다고 가정해 보겠습니다.

견본에서 색상을 식별하는 것이 이미지 자체에서 식별하는 것보다 확실히 쉽습니다. 더욱이 이것은 단순한 이미지이며 캡처한 실제 사진은 색상 팔레트와 관련하여 훨씬 더 다양한 경우가 많습니다. 이미지에서 색상 값을 추출하려면 꽤 까다로운 코드가 필요하며 이것이 Camalian이 필요한 부분입니다. 이러한 까다로운 작업을 수행하므로 이미지에서 색상 관련 정보를 쉽게 추출할 수 있습니다.

시작하기

Camalian으로 색상 추출이 쉽다면 설치가 훨씬 쉽습니다. 다음을 실행하여 Ruby gem을 설치할 수 있습니다.

 gem install camalian

그리고 이 gem을 사용하려면 Ruby 스크립트에 직접 요구할 수 있습니다.

 require 'camalian'

색상 추출

이미지에서 색상을 추출하려면 먼저 메모리에 로드하고 이미지 객체에 메서드를 사용해야 합니다.

 image = Camalian::load( File.join( File.dirname(__FILE__), 'colormap.png') ) colors = image.prominent_colors(15) puts colors.map(&:to_hex)

이 코드 조각은 스크립트가 있는 디렉토리에서 "colormap.png"라는 이미지를 로드하고 여기에서 가장 눈에 띄는 15가지 색상을 추출합니다.

실행하려면 파일을 "color_test1.rb"로 저장하고 ruby color_test1.rb 로 쉘에서 실행하십시오. 다음과 유사한 출력을 생성해야 합니다.

 ["#318578", "#41b53f", "#2560a3", "#359169", "#2154b1", "#4dda15", "#1d48bf", "#1530dc", "#296d94", "#193dcd", "#3da94d", "#45c131", "#3da84e", "#2d7986", "#193cce"]

그리고 그것은 쉽습니다! 위 이미지에 사용된 15가지 색상만 추출했습니다. 눈으로 루피 코드를 사용하거나 더 나쁜 방법으로 시도하는 것을 상상할 수 있습니까? 한 단계 높여보자. 이번에는 더 자세한 내용이 포함된 이미지에 Camalian을 사용하려고 합니다.

이 이미지에서 동일한 스크립트를 실행하여 다음을 얻습니다.

 [“#210b03”, “#723209”, “#974d09”, “#ae5d08”, “#c77414”, “#d77f15”, “#ffea54”, “#94651f”, “#b66a15”, “#c25f06”, “#fdd94d”, “#d39a39”, “#efa540”, “#fffffe”, “#fff655”]

위에서 생성된 색상 값 배열을 시각화하려고 하면 다음과 같은 결과가 나타납니다.

팔레트는 좋은데 추출된 색상에 특정한 패턴이 없습니다. 색상 값을 유사도별로 정렬하고 도움이 되는지 살펴보겠습니다. 실제로 배열을 콘솔에 인쇄하기 전에 함수를 하나 더 호출하기만 하면 됩니다.

 colors = image.prominent_colors(15).sort_similar_colors 

하지만 상대적으로 밝은 색상을 추출하려면 어떻게 해야 할까요? 40%만 어두운 색상, 즉 0에서 40 사이의 밝기(HSL 색상 공간에서) 값을 원할 수 있습니다. 우리가 해야 할 일은 다음과 같습니다.

 colors = image.prominent_colors(15).light_colors(0, 40) 

이미지 검색 엔진 만들기

이제 Camalian을 사용하여 색상을 처리하는 것이 얼마나 쉬운지 알았으므로 이미지를 업로드하고 색상별로 색인을 생성할 수 있는 간단한 웹 애플리케이션을 빌드해 보겠습니다. 간결함을 위해 Ruby 애플리케이션 구축과 관련된 다양한 세부 사항은 건너뛰겠습니다. 대신 색상 및 Camalian 사용법을 다루는 세부 사항에 중점을 둘 것입니다.

이 Ruby 애플리케이션의 범위는 이미지 업로드를 처리하고, 이미지에서 색상을 추출한 후 저장하고, 선택한 색상과 임계값을 기반으로 업로드된 이미지를 검색하는 것으로 제한합니다.

다음은 애플리케이션의 구조를 설명하는 모델 다이어그램입니다.

업로드된 모든 이미지는 PortfolioItem 개체를 사용하여 표현됩니다. 각 Color 개체는 업로드된 이미지를 통해 발견된 고유한 색상을 나타내며, 마지막으로 PortfolioColor는 각 이미지와 해당 이미지에서 찾은 색상 간의 관계를 나타냅니다.

응용 프로그램의 대부분은 특히 이미지 업로드 처리, 모델 엔터티 생성 및 데이터베이스에 유지 등과 관련하여 매우 표준적입니다. Ruby 개발자인 경우 이러한 작업은 간단합니다. 다음은 업로드된 이미지에서 색상을 추출하는 데 사용되는 방법입니다.

 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

이것은 색상 팔레트를 추출하고 데이터베이스에 저장함으로써 도움이 됩니다. 특정 수의 두드러진 색상(사용자가 이미지를 업로드할 때 정의할 수 있는 색상)만 추출하는 방법에 주목하세요.

사용자가 웹 UI의 양식을 통해 이미지를 제출하면 포스트 핸들러를 통해 이미지를 수신하고 이에 대한 새 PortfolioItem 이 생성됩니다. 이 메서드, extract_colors 는 포트폴리오 항목이 데이터베이스에 유지될 때마다 호출됩니다.

페이지에 색상 팔레트를 렌더링할 수 있도록 간단한 도우미를 사용합니다.

 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

기본적으로 배경색이 추출된 두드러진 색상 중 하나로 설정된 작은 정사각형 범위 가 있는 div 를 만듭니다.

마지막으로 검색을 구현하려면 몇 가지 수학과 논리를 사용해야 합니다.

 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

colors_by_hsl 메서드를 사용하여 쿼리와 일치하는 모든 Color 엔터티를 가져올 수 있습니다. 그리고 이를 통해 업로드된 모든 이미지를 식별하고 검색 결과 페이지를 렌더링할 수 있습니다. 쿼리 자체는 다소 간단합니다. 특정 색상과 유사도 값이 주어지면 각 색상 구성 요소에 대해 값 범위가 계산됩니다.

그리고 그것은 거의 모든 어려운 부분입니다.

그것을 밖으로 시도

GitHub에서 전체 코드를 찾을 수 있습니다. 이 앱의 인스턴스를 Heroku에 배포하거나 로컬에서 사용해 볼 수 있습니다.

 git clone https://github.com/nazarhussain/camalian-sample-app.git cd camalian-sample-app bundle install rake db:migrate rails s

최종 애플리케이션은 다음과 같습니다.

응용 프로그램이 실행되면 웹 브라우저에서 http://localhost:3000을 가리킵니다. 화면의 양식을 사용하여 다양한 색상 팔레트의 이미지 몇 개를 업로드합니다. 그런 다음 색상별로 이미지를 검색하려면 오른쪽 상단의 검색 필드를 사용하십시오. 임계값 드롭다운을 사용하면 이미지 색상 일치를 위한 비유사성 허용 오차를 지정할 수 있습니다.

무엇 향후 계획?

이 기사에서 만든 데모 애플리케이션은 다소 간단하지만 가능성은 무한합니다! 이 라이브러리의 다른 실용적인 용도는 다음과 같습니다.

  • 사용자가 어두운 프로필 사진을 업로드하지 못하도록 제한
  • 사이트의 색상 테마를 사용자가 업로드한 일부 사진에 적용
  • 디자인 대회의 경우 색상 팔레트 요구 사항에 따라 제출물을 자동으로 검증합니다.

GitHub에서 라이브러리를 추가로 탐색하고 소스 코드를 확인할 수 있습니다. 문제를 생성하여 버그를 보고하거나 pull 요청을 보내 기여하십시오.