좋아, 몇 분을 찾았습니다. 아래에서는 4 가지 솔루션을 다루고 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
을 구현하도록 선택했기 때문에 가능합니다.
당신은 당신은
는 당신이 실제로 요소 튜플로 DIM2
배열로 JP-바디 수리 스타일의 배열을 변환 할 수 있습니다 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-바디 수리가 언 박싱 배열을 제공하지 않음을 한탄. 다행히, 변환은 간단하다 :
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
하지만 실제로는 형식이 잘못되었습니다. 그래서 인수를 이름을 변경하고 다시 정렬 할 수 있습니다 다음 (기존) foldAllS
작업과 잘 대조
foldAllIdxS :: (sh -> a - > e -> a) -> a -> Array r sh e -> a
: 우리의 새로운 배는 두 가지 중요한 특징을 가지고 어떻게
foldAllS :: (a -> a -> a) -> a -> Array r sh a -> a
공지 사항. 결과 유형은 요소 유형과 일치 할 필요가 없으므로 히스토그램의 튜플로 시작할 수 있습니다. 두 번째로, 우리 버전의 fold는 인덱스를 전달합니다.이 튜플은 업데이트 할 튜플 (있는 경우)을 선택할 수있게 해줍니다.
당신은 게으르게 원하는 바디 수리 배열 형식을 획득하려면 최신 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 오츠 (Otsu) thresholding을 완성 했습니까? 나는 그것을 원하지만 어떤 중복 작업도 피하고 싶다. –