6

私が取り組んでいるアプリケーションでは、256x256のマトリックスをソケット経由で送信する必要があります。クラスター上で実行されるオフショアシステムシミュレーター用の視覚化クライアントを開発しています。このマトリックスは、海面の現在の状態を表す高さマップです。

これはリアルタイムアプリケーションであるため、速度は必須です。また、フロートの256 x 256マトリックスを使用して、256キロバイト/秒の帯域幅要件のために、毎秒256キロバイトのデータを送信する必要があります。

少なくとも私のアプリケーションでは、それはたくさんあります。

だから、私の質問は、ソケットを介して送信する前にこのマトリックスを圧縮するためのいくつかの良い方法がありますか?そして、そのような方法があれば、どれだけのOS削減が期待できますか?

私の行列は連続表面を表しているので、非可逆圧縮法は私にとって問題ではありません。私は主に、圧縮率、圧縮が行われるのにかかる時間、そして最後に、C++用のこのメソッドの実装がすでにあるかどうかに関心があります。

4

8 に答える 8

5

あなたが十分に沖合にいる場合、および/または穏やかな海の状態にある場合、砕波は大きな問題にはなりそうにありません。この場合、表面はきれいに連続しており、XとYの複数の正弦波/余弦波の重ね合わせのように見える可能性があります。

表面の2-DFFTは、いくつかの洞察を与える可能性があります。表面を帯域幅が制限された2-DFFTとして表現し、より高い空間周波数のデータを破棄できる場合があります。

于 2010-08-20T17:00:46.850 に答える
2

最初に:数値表現

あなたの説明を正しく理解すれば、海の高さの物理的範囲は限られていると思います(たとえば、-50.0〜50メートルの波)ので、典型的なIEEE 754-2008 32ビット浮動小数点(つまりfloatC / C ++)は8を使用します指数(-126〜127の範囲)の場合はビット、小数部の場合は23ビット、符号の場合は1ビット。これがベース2であることに注意してください。

最小の測定(または計算)分散が1mm、0.001メートルの場合、必要な浮動小数点サイズを少なくとも16ビットに減らすことができます。IEEE 754は、交換フォーマットとして使用するために、16ビット浮動小数点値を定義します。これは、指数の場合は5ビット、小数部の場合は10ビット、符号の場合は1ビットです。それが適切だと思います。すぐに要件を128KB/秒(1024Kbps)に減らしてください。

私が最初にこれを書いた後、表現にごくわずかな誤差(<= 2mm)がある均一な表現が必要な場合は、unit物理的な高さ2mmを表す16ビットの符号付き整数に変換することに気付きました。そのため、-32768(== -65536 mmまたは約-65メートル、-200フィート)から32767(== 65534 mmまたは約65.5メートル)の範囲の値で、2mmの解像度で均一な表現が得られます。

これは、a)有効な値の範囲が+/- 65.5メートルであり、2mmの解像度が伝送に許容できるという単純な仮定に基づく、非常に単純な代替表現です。

2番目:データの変更(フィルタリング)

JPEG圧縮で使用されるものと同様の離散コサイン変換(DCT)が、不可逆圧縮技術として役立つかどうかはわかりません。基本的に、これはデータを量子化することで、ほぼ等しい隣接値が平滑化され、ロスレス圧縮方式でより適切に圧縮できるようになります。

3番目:従来のロスレス圧縮

それ以外の場合は、Lempel-Zivベースの方法(LZ、LZH、LZWなど)やおそらく高速LZO法など、適度に高速なロスレス圧縮技術です。

于 2010-08-20T18:03:29.643 に答える
1

さて、行列は単なる2D信号です。したがって、さまざまな圧縮方法があります。私は最初に簡単な解決策を試します:コンテナなしで膨張/収縮します(基本的にはZip、Zipなし)。http://en.wikipedia.org/wiki/DEFLATE 圧縮レベルはデータに依存するため、自分で試してみる必要があるとは言えません。

そうでなければ、それを行うためのより賢い方法は、変更のみを送信することです。サーバー側のコードにアクセスできる場合は、毎秒変更される高さマップの数バイトを送信するだけです。これが理想的なソリューションであり、必要に応じて、変更されたバイトをデフレーターで圧縮することもできます。

于 2010-08-20T16:59:56.483 に答える
1

まず、基本的なエンコーディングを32ビット浮動小数点からある種の固定小数点に変更できるかどうかを考えます。すべての値がかなり特定の範囲内にあると仮定すると(おそらくそう思われます)、これで帯域幅を半分に減らすことができます。必要な範囲(および精度)によっては、指数値を表すこともできます。そのため、さまざまな大きさのかなり適切なアイデアをキャプチャしますが、小さな違いはほとんど無視されます。

あるサンプルから次のサンプルへの大きな高さの変化は(おそらく)予想されていないと思います。(おそらく)多くのサンプルにまたがる傾斜がかなり頻繁に見られます。

その場合、予測デルタ圧縮がおそらくうまく機能します。基本的な考え方は、すべての(エッジではない)ポイントについて、周囲のポイントに基づいてそのポイントの値を予測し、予測したものとポイントの実際の値との差のみをエンコードすることです。失う可能性のある精度によっては、そのデルタを1バイト(または1バイトあたり2バイト)にエンコードできる場合があります。

それが済んだら、ハフマン圧縮または算術圧縮の使用を検討できますが、どちらの場合も圧縮がかなり遅くなります。

于 2010-08-20T17:08:45.430 に答える
1

まず、データを確認します。それらのフロートの何ビットの情報を本当に送信する必要がありますか?最下位ビットを切り取って、それが十分に正確であるかどうかを確認してみてください。次に、基本的なロスレスアルゴリズムから始めます。LZ、ロスレス方式(LZ78、LZW、...)を介して圧縮します。高速の解凍速度でベースラインのロスレス比を取得します。次に、BZipなどを試して、おそらくより良い圧縮方法とより遅い解凍を試してください。これで、ロスレス制限があります。次に、損失の多いアルゴリズムを試してください。JPEGなどの損失率は調整可能であり、それでも非常に高速に解凍されます。最後に、いくつかのフィルターを追加します。X軸またはY軸に沿った単純な差動パスを使用すると、データはおそらく非常によく圧縮されます(または、両方を試して結果を1ビットとして保存します)。これにより、データがさらに圧縮可能になります。

結局のところ、現在の帯域幅を少なくともx3ロスレスで、x10を少し損失で得ることができると思います。

于 2010-08-20T17:17:46.310 に答える
1

私があなたを正しく理解しているなら、表面は毎秒測定されます。したがって、1秒以内の変化がそれほど大きくない場合は、データをビデオとして扱い、ビデオ圧縮アルゴリズムを試してみてください。ビデオ圧縮では、動き補償も考慮されます。動き補償は、アルゴリズムの他の部分の中でも、高いビデオ圧縮率にとって重要です。

于 2010-08-20T20:57:35.997 に答える
0

私は次のことを試みます:

高さの変化は毎秒非常に小さいと予想されるため、2回の連続した転送間の高さの差を送信してみてください。これらの数値に10^nを掛けて、浮動小数点数として送信する必要はなく、代わりに整数として送信する必要があります。次に、ゼロ圧縮エンコーディング(plz google for it)を使用します。これにより、送信されるバイト数を大幅に減らすことができます。その後、圧縮アルゴリズムを使用してこれらのバイトをパックします。

私はそれを約50%減らすことができると思います(それぞれに3〜4バイトを使用するのに十分な差がない限り)。

于 2010-08-20T17:22:16.923 に答える
-1

まず最初に、何レベルの高さが必要ですか?波の山から谷までの高さの最大差はどれくらいですか?256または65536の可能な高さの値で表すことができると思います。これにより、データ構造を変更しなくても、データがすぐに1/2または1/4にカットされます。更新のたびに最小値/最大値を浮動小数点数として送信できるため、256レベルが常に完全に使用され、可能な限り最高の精度が得られます...海が荒れると精度が低下します。

標準の画像アルゴリズムを使用して、256x256の画像を保存することもできます。標準形式のビットマップカットを使用していない場合は、グレースケールとして扱うことができます。各頂点Vが0〜255の値にスケーリングされている場合は、色(V、V、V)を作成し、JPGライブラリを無料で使用できます。それはすでに存在します。または、8/16/32ビットデータの単一チャネルを持つDDSファイル形式も見つかる可能性があります。

この最初の部分は、過去に成功しました。第2部では、独自のアルゴリズムを作成することは避けたいと思いますが、たとえばD3DXなどの既存のライブラリを使用できる形式でデータを取得します。

于 2010-08-23T16:57:32.097 に答える