imhistRは,簡易的に画像処理を行うためのツールとして開発されました。WindowsとMacで動作し,扱うことのできる画像ファイルの種類はbmp, jpg(jpeg), pngです。作成者のGitHubページにあるコードをRのコンソールに打ち込むことでインストールできます。できる限りは,Rを最新バージョンにしてからインストールを行ってください1。
画像処理をするツールと言っても,その機能は,画像に含まれる個々のピクセルの輝度値等に関するヒストグラムおよびその記述統計量の算出のみに特化されています。例えば,「画像の輝度ヒストグラムの歪度は,対象の質感に大きく影響する」という研究(Motoyoshi et al., 2007)2で示されているように,ピクセルのヒストグラムについての情報は,画像を人が認知する際に重要な役割を果たしていると考えられます。Rで画像処理を行うパッケージは,EBImageやripaなど秀逸・多機能なものがすでに複数存在しています。EBImageは数年来使用されていて特に有名ですが,Rcppとparalellを使って高速演算の実装を施したripaが現在のスタンダードであると考えられます。しかし,ヒストグラムを手軽に算出するパッケージとしてはimhistRが最適です(だと思っています)。
パッケージ内の関数は3つあり,それぞれが以下の名前:機能を持っています:
lrgbhist:Luminance(輝度)およびRGB(赤緑青)の各変数におけるヒストグラムの算出labhist:Lab色空間(L:黒-白,a:緑-マゼンダ,b:青-黄の三次元で記述される空間)の各次元におけるヒストグラムの算出hsbhist:HSB色空間(H:色彩,S:彩度,B:明度の三次元で記述される空間)の各次元におけるヒストグラムの算出3つの関数は算出する指標が異なるのみであり,引数(ユーザーが指定する変数)の入力方法はすべて同じです。戻り値(計算結果として出力される値)の形式も3つの関数で類似しています。したがって,1つの関数で使い方を覚えてしまえば,残りの関数もすぐに使えるようになります。以下では,lrgbhistについて7つある引数のそれぞれさらに戻り値を解説し,そのあと残り2つの関数の機能について解説して行きます。
lrgbhistに設定されている引数(Arguments)は,input,mode,output,hist,resize,endoff,textsizeの7つです。Rのコンソールに?lrgbhistと打ち込んでマニュアルのUsageを見てもらうとわかりますが,初期設定ではlrgbhist(input, mode = "file", output = input, hist = TRUE, resize = FALSE, endoff = FALSE, textsize = 16)となっています。どのような出力が得られるのかを示すために,まずパッケージを読み込んでからRのロゴを解析するコードの実行結果を示しておきます。また,マニュアルのExamplesに記されているコードをコンソールに打ち込むと分析が行われますので,とりあえずそれらを打ち込んでみて感じを掴みながら以下の説明を読むと理解が深まると思います。あるいは,それで問題なく使えそうであれば以下は詳細な設定が必要なときのみ見ていただければと思います。
require(imhistR)
## Loading required package: imhistR
lrgbhist("Rlogo.png", textsize = 12, endoff = TRUE)
## Mean_Luminance SD_Luminance Skew_Luminance Kurt_Luminance
## Rlogo.png 0.5307022 0.1816393 0.1654525 -1.697913
## Mean_Red SD_Red Skew_Red Kurt_Red Mean_Green SD_Green
## Rlogo.png 0.42456 0.2849509 0.01362389 -1.875264 0.552168 0.1613232
## Skew_Green Kurt_Green Mean_Blue SD_Blue Skew_Blue Kurt_Blue
## Rlogo.png 0.2315529 -1.657691 0.7183205 0.05884395 -1.220589 2.128444
最初に最も重要な modeについて説明します。この引数は,file,url,folder,scrapingの4つのバリエーションを持っており,どれかを指定して分析を行います:
file: 初期設定ではfileが設定されていますが,これは単一の画像ファイルを分析するモードです。url: 次にurlですが,これは指定したurlの画像ファイルを分析するモードです。webを見ていて,「この画像のヒストグラムをちょっと分析してみたい」と思ったときにどうぞ。そういう人がどのくらい存在するのか知りませんが。folder: folderは,指定したフォルダ(ディレクトリ)のなかにある画像ファイルを分析するモードです。例えばiPhoneの写真が入っているフォルダに1000枚のjpg画像が入っているとき,このモードでlrgbhistを実行することでワンコマンドで一括処理を行うことができます。scraping: 最後にscrapingについてですが,まずweb scrapingという用語があり,これはwebページを解析してデータを取得してくることを指します。本パッケージでは,googleの画像検索のみについてこのweb scrapingを提供しており,検索トップ20枚の画像を自動ダウンロードしてきて一括解析を行います。この20枚というのはパッケージ作成者が決めているわけではなく,googleの画像検索結果のページを解析したとき,2015年7月現在では20枚分の画像データの情報のみが解析可能なためです。個人のグーグルアカウントにログインしているとき,もしくは会社や大学の保持しているネットワーク内においてのみscrapingを行うことができます。scrapingは情報解析が目的である以上は著作権などは特に気にする必要はないらしいですが(参考),scrapingし過ぎるとgoogleからペナルティを受けるらしいので,そうなってしまった場合は自己責任でお願いします(参考)。もし何らかの問題が生じるときは,この機能は停止します。inputには,分析する対象となる画像ファイルを指定します。ファイル指定の方法はmodeに依存して変わります:
fileモードのときには,分析したい画像のファイル名をxxx.jpgという形で末尾に拡張子をつけて指定します。この際,Rのディレクトリが指定したファイルのあるディレクトリであるかに気をつけてください。現在のディレクトリがどこであるかは,getwd()で確認できます。画像のあるディレクトリと現在のディレクトリが異なっている場合は,setwd(xxx)のxxx部分に画像のあるディレクトリを指定してから分析を行ってください。urlモードのときにはurlを指定しますが,ここで指定できるurlはweb上の画像を右クリックして「画像URLをコピー」によって取得したurlの末尾が.bmp,.jpg,.jpeg,.pngのいずれかであるものに限ります。末尾にこれらが付いていないurlに関しては解析の対象になりませんのでご注意ください。folderモードに関しては,例えばC:/Users/xxxといった形でフォルダ名を指定してください。このモードのときに特定のファイル名を指定しても解析は行われません。デジカメやスマホで取った写真の画像ファイルに対してこのモードで分析を行うと,処理時間がかかりすぎて困りますがその場合は以下で示すresizeやhistを上手く活用すると大きく時間短縮できます。iPhone5以降のカメラが800万画素で,画像を数値として読み込むときはRGBの3次元あるので1枚2400万程度のデータ数になります。3600万画素などの高機能デジカメだと1枚でデータ数1億を超えます。そりゃ処理時間かかるって話ですよね。scrapingでは, 特定の事象に対してgoogle検索を行ったときのurlを指定します。例えば,”R”で画像検索を行ったときのurl3などを入力します。現在のディレクトリのなかにスクレ―ピングした画像を保存するscrapingフォルダが自動生成され,1秒間隔で画像がダウンロードされた後,解析処理が行われます。outputは,戻り値(画像のヒストグラムおよび記述統計量データ)の名前を決めるのに使われます。戻り値の名前は,初期設定ではinputの値が使われるようになっています。fileモードでは初期設定のままで問題ないと考えられますが,他の3モードでは適宜名前を変更するのが望ましいと考えられます。urlとscrapingモードでは,長いurlを避けるために初期設定はwebfileとなっています。output="xxx"として“xxx”の部分に好きな名前を入れることで,出力の名前を変更できます。ただし,画像の拡張子が自動的に末尾につくようになっているため,戻り値のフルネームはxxx.jpgなどになります。
この引数はヒストグラムのグラフを描画するか否かを決めるのに使われます。初期設定ではグラフを描画するようになっています。urlとscrapingモードで扱うweb上の画像は容量が小さいため,初期設定のままで問題ありません。一方で,fileとfolderモードにおいて扱うと考えられるデジカメやスマホの写真は容量が大きいため,処理に時間がかかる場合はグラフを描画しないという選択肢があります。例えば,2500(横) x 3200(縦)の800万画素を持った画像を分析した場合をhist=TRUE(初期設定)とhist=FALSEで比較します。
system.time(x <- lrgbhist("Mypicture.jpg", textsize = 12))
## user system elapsed
## 48.36 6.91 55.28
system.time(x <- lrgbhist("Mypicture.jpg", hist = FALSE))
## user system elapsed
## 10.00 1.52 11.52
このように,ヒストグラムのあり・なしで処理時間に大きな差が生まれるのは,本パッケージで用いているggplot2が,データ数が多くなるとグラフのレンダリングに要する時間が長くなるためです。ヒストグラムの記述統計量の値のみを得るのが目的の場合は,hist=FALSEとしてグラフを消すと待ち時間のストレスなく解析が遂行されます。どのくらいの人が記述統計量のみに興味があるのかはわかりませんが。
解析時間が長い場合のもう一つの対処法として,resizeがあります。この引数によって画像を圧縮してから処理することが可能になります。上記と同じ画像を圧縮によって横縦1/4のサイズにすることで,625(横) x 800(縦)の5万画素の画像にしてから解析を行った結果が以下になります。
system.time(x <- lrgbhist("Mypicture.jpg", resize = 1/4, textsize = 12))
## user system elapsed
## 6.76 0.53 7.30
ヒストグラムありのままで素早い解析を行うことができました。勿論,算出されるヒストグラムおよびその記述統計量について圧縮前の画像と比べると誤差が生じるのですが,0-1の範囲において00.1か00.2程度の範囲の誤差です。厳密な計算が必要なときにはこの誤差を消すべきですが,大まかな結果をみたいときにはresizeを使って待ち時間なく記述統計量の近似値とヒストグラムを得るのが楽でしょう。画像圧縮のアルゴリズムにはmmandパッケージのmnkernelを使用しています。ちなみに,お気づきかと思いますがhist=FALSEにしてresizeするのが以下に示すように最速です。
system.time(x <- lrgbhist("Mypicture.jpg", hist = FALSE, resize = 1/4))
## user system elapsed
## 3.57 0.43 4.00
ただし,この場合はヒストグラムも得られず,記述統計量も近似値なのであまりお勧めはできません。
この引数は,分析対象となる画像が白や黒の枠もしくは背景を持っている場合に使用してください。そのような画像の場合,輝度の最高値もしくは最低値にヒストグラムの分布が大きく偏ってしまうために,それらの値に戻り値が大きな影響を受けてしまい,画像の本体が持つ情報を抽出できなくなるためです。ただし,枠や背景以外の白と黒の値も削られてしまうことになるので,それらを除外した正確な分析を行うにはImageMagickなどを使った処理が必要になります。
名前の通り文字の大きさを設定する引数です。デフォルトではヒストグラムのキャプションの大きさが16ptに設定されており,それとの比率で他の文字の大きさが決められていますので,キャプションの大きさを変えることで全体の文字の大きさが変わります。ご自分の使用環境に合わせて値を変えて下さい。
lrgbhistの戻り値(return value)は2つあり,記述統計値とグラフです。コンソールに算出される記述統計値は,輝度(= 0.298912*R + 0.586611*G + 0.114478*B)とRGBの4つのヒストグラムのそれぞれに関する平均値(M),標準偏差(SD),歪度(Skew),尖度(Kurt)の値であり,合計で16個の値になります。グラフは,fileおよびurlモードでは最初に示したようなヒストグラムのグラフがR上にプロットされます。一方,folderとscrapingモードではグラフが複数になるので,R上ではグラフが表示されず現在のディレクトリ下に分析対象のすべての画像のヒストグラムをまとめたpdfファイルが生成されます。
labhistは,入力した画像のRGB値を人の認知様式に基づいて構成されたLab色空間の値に変換した後,各色空間のヒストグラムを算出します。ヒストグラムはlrgbhistとは若干仕様の異なる以下に示すようなグラフが算出されます。記述統計量は,3空間のそれぞれに4つの記述統計量で合計12個となります。冒頭でも述べた通り,引数の使い方はlrgbhistと同様です。画像は,かの有名なLennaさんです4。
labhist("Lenna.jpg", textsize = 12)
## Mean_L*dim. SD_L*dim. Skew_L*dim. Kurt_L*dim. Mean_a*dim.
## Lenna.jpg 51.13606 18.06221 -0.1621125 -0.8141867 33.33402
## SD_a*dim. Skew_a*dim. Kurt_a*dim. Mean_b*dim. SD_b*dim.
## Lenna.jpg 10.32476 -0.8512583 0.2061033 11.41938 13.37176
## Skew_b*dim. Kurt_b*dim.
## Lenna.jpg -0.6934147 -0.2502477
Lab色空間の算出の仕方はいくつかありますが,本パッケージではITU-R BT 709の規格に基づいて基準白色点をD65として,RGBからCIE 1976 Labへの標準的な変換を行っています。なお,LabのLは明度(Lightness)を示しているものの5,aとbはそれぞれが示す色(a:緑-マゼンダ,b:青-黄)と無関係な名前なので,おそらく恣意的にアルファベットの頭2つで命名したのではなかろうかと。
最後のhsbhistは,画像のRGB値の最大値および最小値を基にしてHSB色空間6の値に変換したものです。HSBは,Hが色相(Hue)をSが彩度(Saturation)をBが明度(Brightness)を指します。色相は360°の円で示され0°の赤から60°ずつ黄,緑,シアン,青,マゼンダと切り替わり,最後に赤に戻ってくる色の表現です。彩度は色の鮮やかさの指標であり,灰色様の無彩色から値が大きくなるにつれて鮮明な色になっていきます。明度は文字通り色の明るさを示します。この色空間は例えばコンピュータグラフィックスなどで用いられているとともに,色相が直感的に色を理解するのに適していることから様々な場面で目にする機会があります。ヒストグラムのグラフおよび記述統計量は,labhistと同様のものが算出されます。彩度と明度は色相の色のそれぞれが持っていますが,本パッケージでは色相において最もヒストグラムの値が大きい色について,彩度と明度の値をグラフ化しています。
hsbhist("Mandrill.jpg", textsize = 12)
## Mean_Hue SD_Hue Skew_Hue Kurt_Hue Mean_Saturation
## Mandrill.jpg 0.3160952 0.2371427 0.873348 0.2590106 0.3494969
## SD_Saturation Skew_Saturation Kurt_Saturation Mean_Brightness
## Mandrill.jpg 0.2052667 0.8111574 -0.004059034 0.6117051
## SD_Brightness Skew_Brightness Kurt_Brightness
## Mandrill.jpg 0.2066086 0.0349603 -0.9268101
発展的な話題として,並列計算について述べます。近年のパソコンではマルチコアが主流ですが,Rで計算を行うときには1つのコアしか使用していません。しかし,parallelなどのパッケージによってマルチコアをフルに活用することで,処理を格段に速くすることが可能になります。本パッケージでは,R言語をC++言語で書き換えて処理を速くするRcppを随所に使っているもののparallelに関する処理は行っていません。ただし,folderモードで一括で画像解析しているときに処理を早くするために,以下の例のような方法で並列計算を行うと時間が大幅に節約されて快適です。例えば,単一のフォルダ内にスマホで取った40枚の写真があって,resizeなどを使ってもまだ処理時間がかかり過ぎるという事態が生じたとします。そんなときは,フォルダ内の写真を10枚ずつ4つのフォルダに小分けして並列計算を行うことで時間を短縮して処理を行うことが出来るのです。以下で示すように,処理時間は並列計算するとき(上)としないとき(下)で大きく異なります。
fol <- c("C:/Users/Public/Documents/dir")
system.time(x <- lrgbhist(input = fol, mode = "folder", resize = 1/4))
## dir.pdf in C:/Users/honda/Downloads
## user system elapsed
## 218.25 16.36 234.61
#install.packages(c("foreach", "doParallel")) # まだインストールしていない場合
require(foreach); require(doParallel)
## Loading required package: foreach
## Loading required package: doParallel
## Loading required package: iterators
## Loading required package: parallel
fol <- c("C:/Users/Public/Documents/dir1", "C:/Users/Public/Documents/dir2",
"C:/Users/Public/Documents/dir3", "C:/Users/Public/Documents/dir4")
cl <- makeCluster(4)
registerDoParallel(cl)
system.time(x <- foreach(i=1:4) %dopar% {
imhistR::lrgbhist(input = fol[i], mode = "folder", resize = 1/4, output = paste0("dir", i))
})
## user system elapsed
## 0.03 0.00 69.21
stopCluster(cl)
makeClusterによって処理に用いるコア数を4つに増やしたことで,分析に要する時間が30%以下まで減っているのがわかりますね。戻り値は,pdfがフォルダごとに複数生成されるのに対して,記述統計量はこの例で言えばxにlist形式で格納されます。並列計算後でもまだ処理時間がかかり過ぎているとも言えますが,この並列計算の機能を有効活用することによって,デジカメやスマホで取った大量の写真を現実的な時間単位で解析することが可能になります。
個人が限られた時間のなかで作成するパッケージにできることは,局地戦ではないかと思うわけです。すなわち,多機能な市販ソフトには全体として全く及ばないけれど,一点の機能においては負けないようなソフトを作るというのが個人に可能な範囲ではないかと。画像の輝度と色のヒストグラム解析を手軽に行って見やすい結果を得るという一点において,imhistRは他のソフトよりも有効であると考えます。
Rcppが先に入っていると上手くいかないことがあるようですが,Rcppを一回入れ直してから本パッケージを入れ直してもらえると行けます↩
Motoyoshi, I., Nishida, S., Sharan, L., & Adelson, E. H. (2007). Image statistics and the perception of surface qualities. Nature, 447(7141), 206-209.↩
https://www.google.co.jp/search?hl=ja&site=imghp&tbm=isch&source=hp&biw=960&bih=879&q=R&oq=R&gs_l=img.3↩
こちらから拝借しました。以下のMandrillについても同ページから拝借しました。web上でのご提供ありがとうございます。↩
lrgbhistのLuminance,labhistのLightness,hsbhistのBrightnessは,明るさという意味では同じ指標であると言えますが,算出式がそれぞれ異なるため厳密には別の事柄を示しています↩
HSV色空間という呼び名の方が有名かと思いますが,VのValueが何を指しているのか不明瞭に感じたのでHSBを採用しました↩