
色1.私の視覚私は何を見ているのでしょう。明るさ、輝き、色、形でしょうか。 2.視覚の記憶私は色を記憶できないように思います。記憶しているのは、形状と心象です。 3.色形を認識するために明るさの差を捉えているので、赤い車もべったり同じ色に見えているわけではありません。 4.デジタルカメラの視覚CCDがデジタルカメラの受光素子に使われていることは知っていますが、色はどうなっているのでしょう。 データを処理する観点で考えると出来るだけ素なデータが良いように思います。しかし、デジタルカメラも目標は、視覚に近づけること、 5.色の数値表現デジタルカメラのことを考えると、フィルタで分光される3つの周波数領域の強さしかないので、RGBで色を表すことは必然です。 6.色の認識と数値表現色の認識を考えると、周囲の色や方向で同じものがいろいろに見えることから、数値化した値と1対1の関係にないことは確かです。 7.色の数値表現の種類RGB以外に、HSBなど複数の表現方法があることは気が付いていました。しかし、測定されているのが、RGBの3領域の強さであることからRGBだけを使っていました。 下図は、雑誌のナンクロの問題を撮影したものです。
フラッシュの影響で、グレースケール化、2値化をすると、4隅では、白が黒になってしまいます。 RGBのそれぞれの平均値は、(140,138,141)と(181,172,166)で、グレースケール化した値の平均は、141と169です。 adbeのサイトには、1976 CIE u',v'色度図がありました。L*a*b*は図がないのでl*u*v*を見てみます。
色度図ではu'が0から0.7,v'が0から0.6の空間に、(0,06),(0.25,0),(0.62,0.52)を頂点とする三角形に近い形をしています。 下図は、colorspaceパッケージのLUVでL,U,Vの[0,100]、[-100,100]、[-100,100]の色を作り、RGBに変換して、C#で描画したものです。1pixelに色をを設定し、ストレッチで拡大表示しています。
L*a*b*も感じを掴むために図示してみます。下図は、L*が 25、39、53、67、81、95 の6枚です。各図とも、-100から100を50分割し、a,bの値とし、(b,a)の位置にLAB()の返す値をプロットしました。他の方向から見た図が、「colorspaceパッケージのLab」にあります。
8.R言語の色の表現 R言語で色を使うのは、plot()などの col= のオプションです。 col="red" のように、色名でも指定できます。 col=には、rgb(),hsv(),hcl(),gray(),rainbow(),heat.colors(),topo.colors(),terrain.colors()を記述でき、 9.ビットマップ表示するには
どうもドット単位にカラーを指定して描画する直接的な方法はないようです。 > colors<-rainbow(9)
ビットマップを読み込むエクステンションを書いて読み込んでみました。 # Bitmapの読み込み これを使って、 > img <- bm_read("DSCF0670.JPG") 10.グレースケール
前の例の img を、以下のようにして、グレースケールで表示してみた。 > y <- (img$rgb * c(306,601,116)) 表示装置(モニタ)はウインドウごとに異なる条件で表示しているわけではなく、一律の解像度、色数で表示しているのですから、グレースケールもカラー表示だと言うことにやっと気が付きました。カラー画像をグレースケール化するときに、各色に乗じる定数は決まっているようです。
11.RGBで色の分布を見る
左図は、雑誌のナンクロをデジタルカメラで撮影したものの一部で、全体は780x767ドットです。 度数に対応した色は、rainbow(使われている色数)で作りました。
12.colorspaceパッケージのRGBここでは、2値化するのに色の要素が使えないのかと言うことを考えています。colorspaceパッケージをデフォルトで使って出来ることで十分と思っていましたが少し深入りしてしまいました。 RGB(R/255,G/255,B/255) パソコンで普通のRGBは、他のRGBと区別が必要な場合はsRGBと表記されているようです。 通常、sRGB->リニアRGBには、指数に2.4が使われるようですが、colorspaceパッケージのRGBは、2.2が使われていることもわかりました。
> # R の基本の色の扱い -----------------------------------------------
> # γ補正されたRGBから16進文字列を作り色指定に使う > sRGBhex <- rgb(64, 128, 192, maxColor=255) > sRGBhex [1] "#4080C0" > # デフォルトは0-1の値になっているが、γ補正されたRGBに変わりない > sRGBhex <- rgb(64/255, 128/255, 192/255) > sRGBhex [1] "#4080C0" > # ColorSpaceパッケージのRGB --------------------------------------- > # 16進文字列の色(Rの基本的な色表現)からColorSpaceのRGBに変換 > cs_RGB <- hex2RGB("#4080C0") > cs_RGB # リニアRGB R G B [1,] 0.06567053 0.2452781 0.5560067 > # 16進文字列に復元を確認 > hex(cs_RGB) # 復元を確認 [1] "#4080C0" > # 0-1のR,G,Bを指定して、ColorSpaceのRGBを作る > cs_RGB2 <- RGB(cs_RGB@coords[1],cs_RGB@coords[2],cs_RGB@coords[3]) > cs_RGB2 R G B [1,] 0.06567053 0.2452781 0.5560067 > # ColorSpaceのRGBで指定する、R,G,Bはγ補正されたRGBではない > sRGB2 <- RGB(64/255, 128/255, 192/255) > sRGB2 # γ補正されたRGBの0-1表現 R G B [1,] 0.2509804 0.5019608 0.7529412 > # γ補正の逆演算をしてからColorSpaceのRGBに(2.4だと合わない) > lR <- (( 64/255+0.055)/1.055)^2.4 > lG <- ((128/255+0.055)/1.055)^2.4 > lB <- ((192/255+0.055)/1.055)^2.4 > sRGB3 <- RGB(lR, lG, lB) > sRGB3 R G B [1,] 0.05126946 0.2158605 0.5271151 > hex(sRGB3) # 復元しない [1] "#3878BB" > # γ補正の逆演算をしてからColorSpaceのRGBに(2.2で一致) > lR2 <- (( 64/255+0.055)/1.055)^2.2 > lG2 <- ((128/255+0.055)/1.055)^2.2 > lB2 <- ((192/255+0.055)/1.055)^2.2 > sRGB4 <- RGB(lR2, lG2, lB2) > sRGB4 R G B [1,] 0.06567053 0.2452781 0.5560067 > hex(sRGB4) # 復元を確認 [1] "#4080C0" >
13.L*a*b*で色の分布を見るおなじ物をRGBからL*a*b*に変換して、分布を見てみました。
全データのでは境目は分かりませんが、度数が60超をプロットすると、下図になります。
各面を見るとなんとなく左右に分割されているように見えます。この左右はどんなことを表すのか、左右を分離して見ました。
L*を2値化してみました。
(100,0,0)からの 色差を計算し、この差に離隔抽出フィルタを適用して見ます。注目点と左、左上、上の4点で行います。負の値が白への変化なので、色差が-3以下の点を白の候補にします。この候補の度数分布を見て閾値を決めます。
##############################################################
# 特徴的な部分を分割してファイルにしておいてから source("Bitmap_R.R") img <- bm_read("11.bmp") cols <- rgb(img$rgb[1,],img$rgb[2,],img$rgb[3,],maxColor=255) rgbc <- hex2RGB(cols) labc <- as(rgbc,"LAB") # 各ピクセルの白(1,0,0)からの距離を計算 labd <- array(0,c(img$width, img$height)) i <- 1 for( y in 1:img$height) for( x in 1:img$width) { labd[x,y] <- sqrt((labc@coords[i,1]-100)^2 + labc@coords[i,2]^2 + labc@coords[i,3]^2) i <- i + 1 } range(labd) windows(4,4) hist(labd,breaks=50,main="白からの色差の度数") # 左上近傍 ラプラシアンフィルタで輪郭を見つける edge <- array(0,c(img$width, img$height)) for( y in 2:img$height) for( x in 2:img$width) { edge[x,y] <- labd[x,y]*(-3) + labd[x-1,y] + labd[x,y-1] + labd[x-1,y-1] } range(edge) # この値が負であればその位置は白と判断する。色差3で区別して、白を集める white <- labd[edge< -3] range(white) windows(4,4) hist(white,breaks=50,main="白への変化点の色差の度数") length(white) length(edge) # e <- as.vector(edge) windows(4,4) b <- matrix(0,nrow=3,ncol=length(img$rgb[1,])) b[1,] <- ifelse(labd<=43,255,img$rgb[1,]) b[2,] <- ifelse(labd<=43,255,img$rgb[2,]) b[3,] <- ifelse(labd<=43,255,img$rgb[3,]) bm_image(b,img$width,img$height,main="閾値:白からの色差43")
|
|||||||||||||||||||||||||||||||||||||||||||||||||||

