好的,我找了幾分鐘。下面,我介紹了四種解決方案,並提出了最糟糕的解決方案(中間兩項,涉及O(n)數據轉換)對您來說非常簡單。
讓我們確認阿呆解決方案
這是合理的,先從明顯。你可以使用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
。
你可以建立數組你想要
使用traverse
你其實可以轉換JP-惹巴風格的數組爲DIM2
陣列,元組的元素:
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
我們可以補丁惹巴
這是真的只有一個問題,因爲惹巴沒有什麼,我認爲一個正常traverse
功能。 Repa的遍歷更像是一個數組構造,它恰好爲另一個數組提供索引函數。我們希望以下形式進行遍歷:
newTraverse :: Array r sh e -> a -> (a -> sh -> e -> a) -> a
但粗糙的這其實只是一個畸形的摺疊。所以讓我們將其重命名和重新排列參數:
foldAllIdxS :: (sh -> a - > e -> a) -> a -> Array r sh e -> a
它與(預先存在的)foldAllS
操作很好的對比:
foldAllS :: (a -> a -> a) -> a -> Array r sh a -> a
通知我們的新折怎麼有兩個重要的特點。結果類型不需要匹配元素類型,所以我們可以從一個直方圖元組開始。其次,我們的摺疊版本通過索引,它允許您選擇要更新的元組中的哪個直方圖(如果有的話)。
您可以懶洋洋地使用最新的JuicyPixels-惹巴
爲了獲得您的首選惹巴陣列格式,或獲取未裝箱載體,你可以使用新上載JuicyPixels-惹巴-0.6。
someImg <- readImage path :: IO (Either String (Img RGBA))
let img = either (error "Blah") id someImg
uvec = toUnboxed img
tupleArr = collapseColorChannel img
現在您可以直接摺疊向量或使用元組數組了,就像您最初所期望的那樣。
我也參加了一個醜陋的刺在充實第一,可怕的天真,解決方法:
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] ]
我太警惕這種代碼的性能(每指數3個遍歷......我必須是累了)把它扔進JP-Repa,但如果你發現它運作良好,然後讓我知道。
你有什麼試過? (如果數組的類型是'Array U DIM2(Word8,Word8,Word8)',你可以這樣做嗎?如果是,你可以寫一個轉換函數Array U DIM3 Word8 - > Array U DIM2(Word8,Word8,Word8) ?) – huon
明天我會試着看看這個。與此同時,如果圖像表示之間存在基本轉換,您認爲這對JP-repa有用,則可隨時發送補丁。 –
@FalcoHirschenberger你有沒有得到大津閾值完成?我喜歡它,但我想避免任何重複的工作。 –