ユニファ開発者ブログ

ユニファ株式会社プロダクトデベロップメント本部メンバーによるブログです。

線形計画とシンプレックス法

こんにちは、システム開発部のちょうです。

最近秋の基本情報技術者試験(FE)を目標にして勉強しています。FEといえば、いろんな分野の問題が出題されます。その中に、OR・IEにおける線形計画問題は個人にとって一番難しかったです。

例えば、平成25年秋、問75

製品X及びYを生産するために2種類の原料A,Bが必要である。製品1個の生産に必要となる原料の量と調達可能量は表に示すとおりである。製品XとYの1個当たりの販売利益が,それぞれ100円,150円であるとき,最大利益は何円か。

原料 製品Xの一個当たりの必要量 製品Yの一個当たりの必要量 調達可能量
A 2 1 100
B 1 2 80

線形計画を分からなくても、問題を読んだら制約条件や目的関数が理解できると思います。

製品Xの生産量を x 、製品Yの生産量を y とする。

制約条件

2x + y <= 100
x + 2y <= 80

最大利益 max の関数

max = 100x + 150y

一見二変数の方程式ですが、不等式のゆえ、そのまま解けてはならないです。でも現実と繋がる生産の問題なので、生産量は0とそれ以上、つまり負数にならないことが分かります。

x, y >= 0

不等式と合わせて、生産量x, yの範囲は計算できそうですが、 xy お互い関連して、それといつ最大利益になるかも分からなくて、範囲を計算しても意味がないかもしれません。

ほかに方法がないでしょうか。

続きを読む

Rails 5.2で追加予定のActiveStorageを使ってみる

こんにちは、Webエンジニアの本間です。 先週、広島で RubyKaigi 2017 が開催されましたね。私は参加できなかったのですが、興味深い発表が多かったので、公開されているスライドは一通りチェックしたいなと思っています。

さて、今回のブログでは、少し乗り遅れた感がありますがRails 5.2で追加予定の ActiveStorage を使って見て、感想や気になる点などを書いていこうかなと思います。

※注意:現在開発中のalphaバージョンのRails 5.2を使用しています。記事公開後の修正によってはサンプルコードが動作しなかったり、記載された内容と動作が異なる可能性があります。

続きを読む

EC2のタグ情報で設定ファイルを切り替える

おはこんばんにちは、インフラのすずきです。

先日iPhone 6s Plusがお風呂にダイブして、新型iPhoneが出る直前で本体交換しないといけないのか!?
とドキドキしていましたが、なんとか無事で今も順調に動いてくれています。
少なくともiPhone X発売まで頑張って頂きたいところです。

本題ですが、AWSのEC2タグ情報を利用して設定ファイルを切り替える方法をご紹介します。

続きを読む

Swift3 で CoreBluetooth 実装するときにあったら良さそうな Data Extension

こんにちは、iOSエンジニアのしだです。
iOSアプリからBLE経由で Characteristics の値を読み込む場合、20バイト程度のデータをデコードする必要があります。 主に Bluetooth SIG で定められているGATTのデータフォーマットで、あったら便利な Data の Extension を共有します。

準備

  • Xcode 8.3.3 (Swift 3.1)
続きを読む

ffmpegで写真や動画を加工してみよう!

こんにちは。エンジニアの田渕です。

東京では、夜になると秋の虫の声が聞こえるようになりました。ついこの間まで、寝苦しい夜に悩んでいたのに、月日の経つのは早いものです。

日本は秋から冬にかけ比較的行事が多く、その分、写真や動画を撮影する機会も増えます。 最近ではスマートフォンの無料アプリで驚くくらいに加工ができるので、利用されている方も多いのではないでしょうか。 今回は、そんな画像や動画の加工を、コマンドでやってみよう、という記事です。

以前、こちらのブログでffmpegを利用してクロマキー合成する、という記事を書かせてもらいましたが、今回も同じくffmpegを利用して、画像の加工をしていきます。 ffmpegって何?という部分については、前回記事を参照ください。 tech.unifa-e.com

加工してみよう!

では、さっそく加工して行きましょう。

元の画像

こちらの写真は、春先に道端で撮影したものです。夜、そしてスマートフォンのカメラ、という悪条件。 特に何か加工をしたりした訳ではなく、なんだか偶然、全般的に桜の色になっております。 ただ、……ちょっと、くらいかな。。。 f:id:unifa_tech:20170904233442j:plain

コマンド紹介

ffmpegには画像加工用のフィルターという概念があるのですが、そのフィルターのオプションを利用することで、画像や動画の加工が出来ます。 今回利用するのは、eqというオプション。

公式ドキュメントは下記になります。

FFmpeg Filters Documentation

なんだか、色々とたくさんありますが、今日はこの中の、brightness、saturation、contrastを使ってみたいと思います。

コマンドは至って簡単、下記のような具合に指定して使います。

ffmpeg -i source.jpg -vf eq=brightness=0.06 -c:a copy output.jpg

赤文字の部分が、今回の主役であるeqオプションの指定部分です。サンプルは、brightnessを指定した例。 他のオプションも、同じような感じで指定します。 組み合わせて使うことも出来ますが、今回はそれぞれの効果を見るために、一つだけ指定したものを順に見ていきます。

brightness

日本語で言う「輝度」です。サンプル画像は、上で紹介したコマンドをそのまま実行した結果です。 元の画像と比較して、全体的に明るくなっているのがわかるでしょうか? f:id:unifa_tech:20170904233603j:plain

saturation

こちらは「彩度」を変更した画像です。saturation=2という値で実行しています。かなり鮮やかになりましたね。 f:id:unifa_tech:20170904235821j:plain

contrast

最後が「コントラスト」。contrast=2で実行した場合です。元の画像と比べると、くっきり物が見えるようになったような? f:id:unifa_tech:20170904233650j:plain

どうしてffmpegか?

ここまで見てきてもらったように、コマンドでオプションを指定することで、画像の加工ができることがわかりました。実はコマンドラインで画像加工出来るソフトは他にももっと色々とあるのですが、(もっと良く使われているImage Magickとか。)なぜ今回ffmpegを使ったのか?といえば、ffmpegは↑に書かれているコマンドと、全く同じコマンドで、動画の加工が出来るからです。 入力と出力のファイル名を、それぞれ動画のファイルにするだけで、暗かった動画を明るく出来たりします。

まとめ

撮影チャンスは突然にやってくるもので、必ずしも撮影に最適な状況にはなっていません。それでも、一か八か!でシャッターを切るわけですが、結果、「真っ暗で何も見えない」とか「ぼんやりしていて……。」なんてことも、ままあります。

そんな時、園の先生方がパソコンのソフトなどを使って苦労して画像を修正するのではなく、サーバー側でなんとか出来ないかなぁ……なんてことを夢見ています。 もちろん、実現には、色々とクリアすべき課題があるのですが……。

ffmpegのフィルターオプションは膨大で、なかなか面白いものも眠っているので、また折を見てご紹介できればと思います。

それでは!

顔認識でハッピー分析

こんにちは、2週連続の田中です。(でも、先週とは別の田中です。。)

前々から気になってたことを少しだけではありますが解析したので今日はそれについて共有します。

気になっていたこと

それは、、

「保護者のみなさまが購入した写真はハッピーな表情が多いのか?」

きっと、そうだろう とは思いつつも調べてなかったので今回調べてみました。

分析ステップ

  1. 保護者の方が購入した写真を抽出する
  2. 顔認識を行い、顔を検出するとともに表情の認識も行う
  3. どんな表情が検出されているか集計、可視化する

ステップ3に関して、本来は写真とその認識結果を対で示しながらというのが分かりやすくベストなのですがプライバシーの問題のため園の実際の写真を出せないのが残念です。

数字とテキストでまとめただけの結果になりますがご容赦ください。。

顔認識

顔認識は Amazon Rekognition を使いました。 Rekognition は 元々、アメリカのベンチャー企業 Orbeus社 が開発したサービスで実は弊社の子どもの顔認識機能のリリース当初、この技術を使っていました。

突然、サービス停止のアナウンスがあり、慌てて代替の顔認識サービスを探して置き換えの開発を余儀なくされた思い出深いサービスです。その時は、

ええ、マジかよ?! ╰(゚x゚​)╯

と戸惑うばかりでしたがそういう事情(Amazonによる買収)だったんですね。。

当時、顔認識をAPIで提供するサービスはいくつかありましたがRekognitionの性能が頭一つは抜けていたので今回改めて使ってみました。

Rekognitionでは顔の認識とともに表情も検出でき、検出できる表情の種類は

  • HAPPY
  • SAD
  • ANGRY
  • CONFUSED
  • DISGUSTED
  • SURPRISED
  • CALM
  • UNKNOWN

の8種類です。

http://docs.aws.amazon.com/rekognition/latest/dg/API_Emotion.html

表情にはそれぞれ0から100までのスコアがつきます。 検出されなかった表情についてはスコアはつきません。

AWSのアカウントを持っている方は Rekognitionのコンソール画面からデモでお試しできます。

Rekognitionの注意点として現時点では使えるリージョンが限定されていて東京リージョンでは使えません。そのため、今回はOregon(us-west-2)を使いました。対象写真を格納しておくS3バケットも同じリージョンになります。

参考までに使用したコードはこちらです。

require 'optparse'
require "aws-sdk"
require 'dotenv'

options = {}
OptionParser.new do |opt|
  opt.on('-b VALUE', '--bucket VALUE', 'bucket name') { |v| options[:bucket] = v }
  opt.on('-p VALUE', '--prefix VALUE', 'key prefix') { |v| options[:prefix] = v }
  opt.on('-o VALUE', '--output VALUE', 'output directory') { |v| options[:output] = v }
  opt.parse!(ARGV)
end

Dotenv.load

Aws.config = {
  access_key_id: ENV.fetch('AWS_ACCESS_KEY_ID'),
  secret_access_key: ENV.fetch('AWS_SECRET_ACCESS_KEY'),
  region: 'us-west-2'
}

bucket = options[:bucket] || 'your_default_bucket'
prefix = options[:prefix] || ''
output_directory = options[:output] || '.'

s3 = Aws::S3::Client.new(region: 'us-west-2')
keys = s3.list_objects(bucket: bucket, prefix: prefix).contents.map do |object|
  object.key
end
puts "#{keys.count} objects"

rekog = Aws::Rekognition::Client.new(region: "us-west-2")
keys.each do |key|
  puts key

  result = rekog.detect_faces({
    image: {
      s3_object: {
        bucket: bucket,
        name: key
      },
    },
    attributes: ["ALL"]
  })

  output_filename = output_directory + "/" + File.basename(key, '.jpg') + ".json"
  File.write(output_filename, result.to_h.to_json)
end

分析

とりあえず、3枚以上購入があった写真を1000枚抽出して顔認識を行い結果を見てみました。1000枚なのは私の体力的な都合によるものです。

結果

まず、検出した顔が1つの写真に絞り集計してみます。(購入者のお子様だと考えられ、結果の解釈がしやすいため)

表情 カウント スコア平均値
HAPPY 95 73.5
SURPRISED 19 52.5
CALM 3 40.4
CONFUSED 9 35.6
DISGUSTED 3 45.8
ANGRY 9 54.0
SAD 23 36.9

実際の写真も確認して、まとめると

  • 当然ながら HAPPY が多くそのスコアも高い
  • 真面目な表情(何かに真剣に取り組んでいたりetc)は SURPRISED, CALM, CONFUSED あたりでそこそこカウントされた
  • ANGRY, SAD が想定よりカウントが多い。。

ANGRY, SAD となった写真を確認してみると実際には怒ったり悲しい表情をしているというより 下向き顔が多く、機械学習をかけるとこの分類になりやすいようです。下向き顔 = うつむき顔 = 悲しい ということで分類としては妥当な気がしました。

園児がデスクワークしている姿を保育士が立った位置から撮影するとどうしても園児の顔向きとしてはうつむき加減になってしまいます。このような子どもが作業に没頭している写真も残しておきたい大事な1枚ということになります。

続いて、集計する顔の数を増やしてみましたが傾向は大きく変わりませんでした。

今後…

購入のなかった写真には HAPPYな顔は少ないのか? と言ったら恐らくそうとは言えず(自分の子ども以外は良い写真であっても基本的には買わないため)今回の分析には課題や突っ込みどころがたくさんあります。(頑張って数値解析したら有意な差が出るかも?)

ただ、自分の子どもが写っている写真がたくさんある中、購入する写真はそのごく一部であり購入された写真には親の感情により響く、言わばハッピーをより感じさせる何か画像特徴としてのエッセンスがあると考えています。

引き続き検討を行い、保護者が感じるハッピーのエッセンスをシステムとして抽出し、それにマッチする写真を優先的に届けられたらなと思います。ƪ(•◡•ƪ)"