การสร้างเครื่องมือค้นหารูปภาพตามสีใน Ruby

เผยแพร่แล้ว: 2022-03-11

ว่ากันว่าภาพหนึ่งภาพมีค่าพันคำ และในหลาย ๆ ด้านคำในภาพเป็นสี สีเป็นส่วนสำคัญในชีวิตของเรา และเราไม่สามารถปฏิเสธความสำคัญของสีเหล่านั้นได้

ขณะดูรูปภาพ เรามักจะพยายามระบุสีในส่วนของรูปภาพ เราทุกคนได้ลองทำแล้ว แต่ไม่เคยทำในรายละเอียดเลย เมื่อระบบขอให้ระบุสีจากรูปภาพ เรามักจะติดป้ายกำกับโดยใช้ชื่อสีเฉพาะ เช่น แดง น้ำเงิน และเขียว อย่างไรก็ตาม หากเราขอให้เราแยกสีที่โดดเด่นที่สุด 30 สีออกจากภาพ ดวงตาของเราไม่สามารถตรวจจับหรือระบุสีเหล่านั้นได้ค่อนข้างง่าย Camalian เกี่ยวกับเรื่องนี้ ช่วยให้คุณแยกสีออกจากภาพแล้วเล่นกับมัน

Camalian: เครื่องมือเลือกสี Ultiamte สำหรับ Ruby

ในบทความนี้ เราจะมาดูกันว่าช่องว่างของสีคืออะไร อัญมณีทับทิม Camalian นำเสนออย่างไร และสามารถใช้เพื่อสร้างเครื่องมือค้นหารูปภาพอย่างง่ายที่ใช้สีเพื่อระบุและแยกแยะได้อย่างไร

พื้นที่สี

ก่อนที่เราจะเริ่มต้น เรามาทำความเข้าใจแนวคิดพื้นฐานเกี่ยวกับสีกันก่อน รูปภาพที่แสดงบนหน้าจอของเราแสดงโดยใช้อาร์เรย์พิกเซลสองมิติ แม้ว่าไฟล์รูปภาพอาจถูกเข้ารหัสด้วยวิธีต่างๆ กัน แต่การแสดงแบบคร่าวๆ หลังจากคลายการบีบอัดและถอดรหัสข้อมูลจะเหมือนกัน ในการแสดงตามอาร์เรย์ 2 มิตินี้ แต่ละพิกเซลในภาพสีมีสามองค์ประกอบ ได้แก่ สีแดง สีเขียว และสีน้ำเงิน แม้ว่าภาพที่พิมพ์บนกระดาษจะเป็นพื้นผิวจุดสองมิติ แต่ตัวจุดเองก็มักจะเป็นส่วนผสมของหมึกสี่องค์ประกอบ ได้แก่ สีฟ้า สีม่วงแดง สีเหลือง และสีดำ เทคนิคเหล่านี้ใช้เพื่อแสดงสีที่เรียกว่าช่องว่างสี ช่องว่างสีที่นิยมใช้กันมากที่สุด ได้แก่ RGB, CMYK, HSL และ HSV CMYK ส่วนใหญ่จะใช้ในอุตสาหกรรมการพิมพ์ในขณะที่ส่วนอื่น ๆ ทั้งหมดใช้ในสื่อดิจิทัล

RGB Color Space

สื่ออิเล็กทรอนิกส์ทางกายภาพใดๆ เช่น หน้าจอ 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 เป็นเรื่องง่าย การติดตั้งด้วยสี Camalian จะง่ายยิ่งขึ้น คุณสามารถติดตั้ง Ruby gem ได้โดยดำเนินการ:

 gem install camalian

และหากต้องการใช้อัญมณีนี้ คุณจะต้องใส่ลงในสคริปต์ 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% หรืออีกนัยหนึ่งมีค่าความสว่าง (ในปริภูมิสี HSL) ระหว่าง 0 ถึง 40 สิ่งที่เราต้องทำคือ:

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

การทำ Image Search Engine

ตอนนี้เรารู้แล้วว่าการจัดการสีโดยใช้ 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 และดูซอร์สโค้ดได้ คุณสามารถรายงานจุดบกพร่องได้โดยการสร้างปัญหาหรือมีส่วนร่วมโดยส่งคำขอดึง