R フラクタル次元 - eiichiromomma/CVMLAB GitHub Wiki

(R) フラクタル次元

画像のフラクタル次元を算出

フラクタル次元関係のライブラリ

fdimがメジャーらしいが、画像を扱うには少々トリッキーな事をせねばならないのでR-help MLを漁っていたら同じく画像のフラクタル次元を求めようと質問している人がいた。

回答は"CRANを検索しろ"なのだが、画像に特化した話はどこにも無い。 質問者のURLがsignatureにあったので見てみると、既に実装してソースを公開してくれていた。 しかも画像形式はrimage準拠。

2の階乗の正方形でなければ求まらないが、半端な分割をしても余った分の処理が曖昧になると思われるのでそのまま使ってみる。 試しに128x128の画像を突っ込んでみたがコケる。

オリジナルのソースを読むと強制的に2^9(=512)まで試したり、真っ白だとコケたり、閾値処理を無意味にしてたりするので色々変更を加える。

bc.RのQuick Hack

色々やって以下のようになった。

    --- org.bc.R    Thu Jun  8 14:50:40 2006
    +++ bc.R        Thu Jun  8 14:59:34 2006
    @@ -20,22 +20,31 @@
       if (attr(img,'dim')[1] != attr(img,'dim')[2]) {
         stop("Currently it only works for square images")
       }
    -  if (round(log2(attr(img,'dim')[1]), digits=1) != log2(attr(img,'dim')[1])) {
    -    stop("Currently dimensions of the image must be a power of 2")
    -  }
    -
    +  ## 64x64だとなぜか!=が成立するので性善説化
    +  ##if (round(log2(attr(img,'dim')[1]), digits=1) != log2(attr(img,'dim')[1])) {
    +  ##stop("Currently dimensions of the image must be a power of 2")
    +  ##}
    +  ##画像サイズを元にmaxpowerを設定
    +  maxpower <- log2(attr(img,'dim')[1])
       bv <- c()
    -  powers <- 1:9
    +  powers <- 1:maxpower
       boxsize <- 2^powers
       imgsize <- attr(img,'dim')[1]
    
       ## we want the contour
    +  ##輪郭抽出にSobelフィルタを使ってthresholdingで2値化する時、
    +  ##デフォルトでは0.5を閾値とするが、動的閾値の設定にしてみる
    +  ##効果はいまのところ不明
       sb <- normalize(sobel(img))
    -  tsb <- thresholding(sb, th=thvalue, mode='fixed')
    -  tsb <- i2m(img)
    -
    +  ##tsb <- thresholding(sb, th=thvalue, mode='fixed')
    +  tsb <- thresholding(sb, mode='da')
    +  ##tsb <- i2m(img)
    +  ##i2m(tsb)のバグっぽい
    +  tsb <- i2m(tsb)
    
    -  print('Box Size   Count   Total Box')
    +  if(verbose==TRUE){
    +    print('Box Size   Count   Total Box')
    +  }
       for (b in boxsize) {
         bcount <- 0
         bstart <- seq(1,imgsize, by=b)
    @@ -56,15 +65,23 @@
             }
           }
         }
    +    ##bcountが0だと最後にlogでコケる。
    +    ##0ってことは全部白か黒の場合だけなのでbcount=totalboxとする
    +    if(bcount==0){
    +      bcount <- totalbox
    +    }
         if (verbose == TRUE) {
           print(paste(b,bcount,totalbox))
         }
         bv <- c(bv, bcount)
       }
    -  plot(log(1/boxsize), log(bv))
    +  ##バッチ処理に投げるためverbose=FALSEの時の出力をシンプルに
       df <- data.frame(x=log(1/boxsize), y=log(bv))
       model <- lm(y ~  x, df)
    -  abline(model)
    -  print(paste('fractal dimension =',model$coeff[2]))
    +  if (verbose == TRUE){
    +    print(paste('fractal dimension =',model$coeff[2]))
    +    plot(log(1/boxsize), log(bv))
    +    abline(model)
    +  }
       list(fdim=model$coeff[2],model=model)
     }