私は数分を見つけました。以下では、4つのソリューションをカバーし、最悪のソリューション(O(n)データ変換を含む中間2つのソリューション)を簡単に作成しました。
はダムソリューション
それは明らかに開始するように合理的だと認めることができます。あなたは(未テスト/部分のコードは以下の)初期ゼロの配列から、あなたのヒストグラムを構築し、行と列を横断するData.List.foldl
を使用することができます。
foldl (\(histR, histG, histB) (row,col) ->
let r = arr ! (Z:.row:.col:.0)
g = arr ! (Z:.row:.col:.1)
b = arr ! (Z:.row:.col:.2)
in (incElem r histR, incElem g histG, incElem b histB)
(zero,zero,zero)
[ (row,col) | row <- [0..nrRow-1], col <- [0..nrCol-1] ]
...
where (Z:.nrRow:.nrCol:._) = extent arr
私はこれがものになるかどうか効率的にわからないんだけど、それがすることを疑いますあまりにも多くの境界チェックを行います。 unsafeIndexへの切り替えは、遅延配列hist*
を仮定すると、incElem
を実装することを選択するとうまくいくと思われます。
あなたはあなたが実際の要素のタプルでDIM2
配列にJP-REPAのスタイルの配列を変換することができtraverse
を使用
たいアレイ構築することができます:
main = do
let arr = R.fromFunction (Z:.a:.b:.c) (\(Z:.i:.j:.k) -> i+j-k)
a =4 :: Int
b = 4 :: Int
c= 4 :: Int
new = R.traverse arr
(\(Z:.r:.c:._) -> Z:.r:.c) -- the extent
(\l idx -> (l (idx:.0)
,l (idx:.1)
,l (idx :. 2)))
print (R.computeS new :: R.Array R.U DIM2 (Int,Int,Int))
あなたは身体に私を指すでしたがあなたがこのフォーマットを使用していることについて話したコードですか? JP-Repaにこのタイプの関数を含めるようにパッチするのは簡単です。あなたは箱なしのベクターを構築することができます
は、あなたが簡単な解決策は、箱なしのベクトルをオーバー折ることです言及したが、JP-REPAは、非ボックス化配列を提供していないことを嘆い
に言及しました。幸いなことに、変換は単純です:
toUnboxed :: Img a -> VU.Vector Word8
toUnboxed = R.toUnboxed . R.computeUnboxedS . R.delay . imgData
私たちでしたパッチREPA
REPAは、私は通常のtraverse
関数を考え何を持っていないので、これは本当に唯一の問題です。 Repaのトラバースは、他の配列にインデックス関数を提供する配列構造のほうが多いです。
newTraverse :: Array r sh e -> a -> (a -> sh -> e -> a) -> a
しかし、これは実際には不正な形式になります。だから、名前を変更し、引数の順序を変更することができます:私たちの新しい倍は2つの重要な特性を持っているか
foldAllS :: (a -> a -> a) -> a -> Array r sh a -> a
は予告:
foldAllIdxS :: (sh -> a - > e -> a) -> a -> Array r sh e -> a
(既存の)foldAllS
操作とうまく対比されました。結果の型は要素の型と一致する必要はありませんので、ヒストグラムのタプルで始めることができます。次に、我々のバージョンのfoldはインデックスを渡します。これにより、更新するタプルのヒストグラム(もしあれば)を選択することができます。
はあなたが遅延し、ご希望のREPAアレイフォーマットを取得するには、最新のJuicyPixels-REPA
を使用することができ、またはアンボクシングベクトルを取得するために、あなただけの新たにアップロードされたJuicyPixels-REPA-0.6を使用することができます。
someImg <- readImage path :: IO (Either String (Img RGBA))
let img = either (error "Blah") id someImg
uvec = toUnboxed img
tupleArr = collapseColorChannel img
ここで、最初に必要だったようにベクトルを折りたたんだり、タプル配列を直接使用することができます。
私も最初、恐ろしくナイーブ、ソリューション肉付けで醜い刺しを取った:私はこのコードのパフォーマンス指標あたり(3つのトラバーサルのあまり警戒してる
histograms :: Img a -> (Histogram, Histogram, Histogram, Histogram)
histograms (Img arr) =
let (Z:.nrRow:.nrCol:._) = R.extent arr
zero = R.fromFunction (Z:.256) (\_ -> 0 :: Word8)
incElem idx x = RU.unsafeTraverse x id (\l i -> l i + if i==(Z:.fromIntegral idx) then 1 else 0)
in Prelude.foldl (\(hR, hG, hB, hA) (row,col) ->
let r = R.unsafeIndex arr (Z:.row:.col:.0)
g = R.unsafeIndex arr (Z:.row:.col:.1)
b = R.unsafeIndex arr (Z:.row:.col:.2)
a = R.unsafeIndex arr (Z:.row:.col:.3)
in (incElem r hR, incElem g hG, incElem b hB, incElem a hA))
(zero,zero,zero,zero)
[ (row,col) | row <- [0..nrRow-1], col <- [0..nrCol-1] ]
を...私がでなければなりません疲れている)をJP-Repaに投げ込むことができますが、それがうまくいくとわかったら私に知らせてください。
何を試しましたか? (もし配列に 'Array U DIM2(Word8、Word8、Word8) '型があったらそれを実行できますか?もしそうなら、' Array U DIM3 Word8 - > Array U DIM2(Word8、Word8、Word8) ?) – huon
明日これを見てみよう。その間に、JP-repaで役に立つと思われる画像表現の間に基本的な変換がある場合は、自由にパッチを送ってください。 –
@FalcoHirschenberger大津のスレッシュホールドが完了しましたか?私はそれが欲しいですが、重複した作業を避けたいと思います。 –