1. ホーム
  2. arrays

[解決済み] 数百万のピクセルを持つ2Dの非ボックス化ピクセル配列にはどのようなHaskell表現が推奨されますか?

2022-09-14 19:55:29

質問

Haskellで画像処理の問題に取り組みたいと考えています。 私は何百万ものピクセルを持つビットナル(ビットマップ)画像とカラー画像の両方を扱っています。 私はいくつかの質問があります。

  1. どのような基準で Vector.UnboxedUArray ? これらは両方とも箱詰めされていない配列ですが Vector の抽象化は、特にループ融合の周りでは、大きく宣伝されているようです。 これは Vector は常に良いのでしょうか? もしそうでなければ はどのような場合に使うべきですか?

  2. カラー画像の場合、私は16ビット整数のトリプル、または単精度浮動小数点数のトリプルを保存したいと思います。 この目的のために、どちらか Vector または UArray は使いやすいですか? より高性能?

  3. ビット画像について、私はピクセルあたり1ビットだけを保存する必要があります。 複数のピクセルを 1 つの単語にパックすることによって、私を助けることができる定義済みのデータ型はありますか、それとも私自身でしょうか?

  4. 最後に、私の配列は 2 次元です。 私は、quot;array of array" (または vector of vectors) として表現することによって課される余分な間接性を扱うことができると思いますが、私はインデックス マッピング サポートのある抽象化を希望します。 誰か標準ライブラリまたはHackageから何かを推薦することができますか?

私は関数型プログラマで、突然変異は必要ありません:-)

どのように解決するのですか?

多次元配列について、私の見解では、Haskellにおける現在の最良の選択肢は repa .

Repaは、高性能で規則的な多次元・形状多相性の並列配列を提供します。すべての数値データは箱詰めされずに格納される。Repaコンビネータで書かれた関数は、プログラム実行時にコマンドラインで+RTS -Nwhateverを指定すれば、自動的に並列化されます。

最近では、画像処理の問題にも使われている。

私が書き始めたのは の使い方のチュートリアルを書き始めました。 Haskellの配列やvectorライブラリを既に知っている人が始めるには良い場所です。重要な足がかりは、多次元インデックス(およびステンシルも)に対処するために、単純なインデックス型の代わりに形状型を使用することです。

その repa-io パッケージは .bmp 画像ファイルの読み書きのサポートを含んでいますが、 もっと多くの形式のサポートが必要です。

あなたの具体的な質問に対応するため、ここにグラフィックとディスカッションを掲載します。



Vector.UnboxedとUArrayのどちらを選ぶべきか、どのような基準で選べばよいでしょうか。

両者はほぼ同じ表現を持っていますが、主な違いはベクトルを扱うためのAPIの広さです:両者には通常リストと関連付けられるほぼすべての操作(融合駆動型の最適化フレームワークを持つ)がある一方 UArray にはほとんど API がありません。

カラー画像では、16 ビット整数のトリプルまたは単精度浮動小数点数のトリプルを保存したいと思います。

UArray は多次元データのサポートに優れており、インデックス付けに任意のデータ型を使用することができます。これは Vector (のインスタンスを書くことで)可能です。 UA のインスタンスを書くことによって)、 それは Vector -- の主要な目的ではありません。 Repa のおかげで、効率的な方法で保存されたカスタムデータ型を非常に簡単に使用することができます。 形状 のおかげで、効率的な方法で保存されたカスタムデータ型を非常に簡単に使用できます。

Repa では、ショートパンツのトリプルはこのタイプになります。

Array DIM3 Word16

つまり、Word16の3次元配列です。

ビット画像では、私はピクセルごとに 1 ビットだけを保存する必要があります。

UArraysはBoolをビットとしてパッキングし、VectorはビットパッキングをしないBoolのインスタンスを使用します。 Word8 . しかし,ベクトルに対するビットパッキング実装は簡単に書けます. これがその一つです uvector ライブラリ(廃止されました)からです。フードの下には RepaVectors を使用しているので、そのライブラリの表現の選択を継承しているのだと思います。

複数のピクセルを 1 つの単語にパックすることで、私を助けることができる定義済みのデータ型はありますか。

どのライブラリでも、異なる単語タイプに対して既存のインスタンスを使用できますが、パックされたデータをロールしたりアンロールするためにData.Bitsを使用していくつかのヘルパーを記述する必要があるかもしれません。

最後に、私の配列は 2 次元

UArrayとRepaは効率的な多次元配列をサポートしています。Repaはまた、そうするための豊富なインターフェースを持っています。Vector単体ではそうではありません。


注目すべきは、その言及です。

  • hmatrix 線形代数パッケージへの広範なバインディングを持つカスタム配列タイプです。を使用するようにバインドされるべきです。 vector または repa のようなタイプがあります。
  • ix-shapeable(イクス・シェイパブル 通常の配列から、より柔軟なインデックスを作成することができます。
  • 黒板 アンディ・ギルによる、2D画像を操作するためのライブラリです。
  • コーデック-イメージ-デビル UArrayに様々な画像形式を読み書きできる。