オプトテクノロジーズでは半期に1、2度社内ハッカソンを開催してます。
テーマも自由にみんなで業務・趣味とわず開発を行います。そして何かしら成果物を作ります。一日で。
動機
問題提起
弊社では隔週金曜日に社食がカレーになります。
ここではワンコインでどれだけ大盛りにするかが競われています。
しかし、盛りすぎて溢してしまうことも多く、問題になっています。
我々が美しくカレーを盛れるようになるために
- カレーを盛る
- 写真に撮る
- 採点する
継続&採点基準を順守するためアプリを用意します。
準備
カレー検出器
openCV
$ brew install opencv
学習
いくらカレー好きな僕でも数万枚のカレー画像を持ってるわけもなく期間1日(8時間)の中でそこまでするのは無理だったのでプリセットの顔認証で代用します。
※opencvについてきたcascadeファイルがなんかバージョン合ってなくて個別で探しに行った記憶があります
採点
ちょっとロジック考えるの大変なので、カレー部分を二値化してカレー(と思われる)部分とご飯(と思われる)部分の割合を求めます。
ここでは
- 技術点:検出部分のカレーとご飯の割合
- 芸術点:検出部分のカレーを特殊な計算で算出
とします(いいのかな)。
require 'opencv'
include OpenCV
if ARGV.length < 1
puts "Usage: ruby #{__FILE__} source dest"
exit
end
data = './cascade/haarcascade_frontalface_alt.xml' #カレー検出器が間に合わないので顔認識で代用
detector = CvHaarClassifierCascade::load(data)
image = IplImage.load(ARGV[0])
detector.detect_objects(image).each do |region|
color = CvColor::Gray
image.rectangle! region.top_left, region.bottom_right, :color => color #ここで顔に枠をつけるよ
image.set_roi(region) #ここでさらにカレーの部分だけを切り取り
end
i3 = image.BGR2GRAY.add(10) #グレスケ
i2 = i3.threshold(128, 255, CV_THRESH_BINARY) #2値化
# i2.save_image(ARGV[1])
black = i2.count_non_zero
size = i2.width * i2.height
white = size.to_f - black
artistry = (1 - (black * 0.8) / (size / 2.0)) * 100.0
technical = (1 - (white / black)) * 10.0
puts "技術点 = #{technical.round(2)}, 芸術点 = #{artistry.round(2)}"
WEBアプリ化
誰もが自由にカレー画像をアップロードして点数化できるようにWEBアプリにします。
Railsとruby-opencvを使います。
画像アップロードは手っ取り早いのでcarrierwave
を使います。
Gemfile
$ rails new CurrynaSoderberg
source 'https://rubygems.org'
gem "carrierwave"
gem 'rmagick', require: 'RMagick'
gem "ruby-opencv"
gem 'simple_form'
gem 'rails', '~> 5.0.0', '>= 5.0.0.1'
画像認識界隈ではポピュラーでみんな大好きなえっち画像の主レナ・ソーダバーグをもじってアプリ名にしました。
完成
これでいつでもカレーを美しく盛る練習ができるようになりました!
採点方法は要調整