顔のデータセットを作成したい。だから私は60 fpsのWindows用のkinectの色/深度/赤外線とその他のデータを取得し、それらをハードディスクに保存するグラバープログラム(Visual C++)を書いています。それは私が秒に10フレーム以上を保存することはできませんので、多くの時間がかかり、多くのフレームが落とされます。私はfileStorage(opencv)を使ってyamlのデータを保存しようとしていますが、それも遅いです。私は2つのスレッドを使用することについて考えています.1つはデータを取得するため、もう1つは保存することです。 2つの独立したスレッド間のデータ通信が主な問題です。 フレームを失うことなくデータを保存する最適なソリューションは何ですか?ハードディスクにFast kinectデータを書き込む
答えて
感謝を読み取ることができます。 私は、共有メモリ(キュー)とmutexという2つのスレッドを定義することでこの問題を解決します。
//I have a passenger class that store all data including images in it
#include "passenger.h"
//I define a queue from passenger class
queue<passenger> passengerQueue;
//and a mutex
std::mutex myMutex;
void GrabberThreadFunc()
{
//get the data and store it in a passenger object
if (nearPassenger.valid)
{
std::lock_guard<std::mutex> guard(myMutex);
passengerQueue.push(nearPassenger);
}
}
void SavetThreadFunc()
{
if (!passengerQueue.empty())
{
std::lock_guard<std::mutex> guard(myMutex);
passengerQueue.front().SaveData();
passengerQueue.pop();
}
}
のint _tmain(int型のargc、_TCHAR * ARGV []) {
thread GrabberThread(GrabberThreadFunc);
thread SaverThread(SaverThreadFunc);
if (GrabberThread.joinable())
GrabberThread.join();
if (SaverThread.joinable())
SaverThread.join();
return 0;
}
R.y.z、あなたのソリューションを共有できますか? – Geucimar
mmap()
でメモリに60以上のフレームをキャッシュし、ファイルを保存するためにsendfile
を使用します。もちろん、キャッシュと保存の間には何らかの同期が必要です。
定義済みの要素数が600(60 * number_of_sec_which_are_cached)であるvector<JOB>
を使用しているとします。
struct JOB
{
int second_number; //second related to time
int frame_number; //frame number in second specified by "JOB::second_number"
unsigned char *buf; //frame buffer
unsigned int buf_length; //number of bytes in frame which would be a fixed number.
int valid;
};
グラバーは、フレームをフェッチするときにJOB::valid = 1
になります。
FileSavingThreadは、JOB::valid==1
と保存後にフレームが保存可能かどうかを確認するためにを使用して、JOB::valid=0
となります。
JOB::valid
にAtomic operations libraryを使用すると、簡単に同期のためのmutexを回避できます。
次に、グラバーはベクトル内の要素(すべての要素を調べることによって)を見つけ、JOB::valid==0
とし、その特定の要素にフレームを格納する必要があります。
同様に、FileSavingThreadはベクトル内でJOB::valid==1
の要素を見つけ、その要素で指定されたフレームをファイルに保存する必要があります。
パフォーマンスに応じて、ベクトルの要素の数を増やしたり、FileSavingThreadの数を増やしたり、その両方を増やしたりすることができます。
//-------------------------------------------------------------------------
- 新しい方法2:メモリマップされている既存のファイルを使用して。
- 参考:ここでMemory Mapped File
、我々は我々が手やメモリマップする前に、そのくらいのサイズのファイルを作成することができます保存するフレーム数やどのくらいの時間を秒数に対応したデータを知っていればそのファイル。次に、フレームを保存することは、連続した方法でメモリに書き込むのと同じくらい簡単です。キャッシングとI/Oは、最適な方法でOSによって自動的に管理されます。
これは、計算に含まれるすべてのパラメータw.r.tフレームが固定されているために可能です。
フレームの読み込みは、保存されたファイルをメモリマッピングすることによっても行うことができます。単一のフレームが再び必要とされる場合、特定のフレームのオフセットを計算するのに必要なすべてのパラメータが固定されるので、保存されたファイルの開始からのオフセットの計算は容易に計算できます。
は今の利点は、このような方法で、読み取り/書き込みにあるものをすべてのあなたの助けのためにここにWhat Do Memory-Mapped Files Have to Offer?
残念ながら、 'std :: vector'にmutexが必要です。ベクトルのメンバ上のアトミックライブラリを使用すると助けになりません。 Grabberがベクトルにジョブを追加すると、既存のすべてのジョブとそれらのアトミック変数を**移動する**再割り当てが行われる可能性があります。したがって、FileSavingThreadはベクトルを読み込み中にロックする必要があります。 – MSalters
Visual StudioはWindowsを意味します - Windowsには 'senfile()'はありません。メモリマッピングは 'mmap()'ではなく、別のAPIも使用します。 mmapの使用法について詳しく説明する必要があります(匿名の共有メモリを使用しているようですが、明らかではありません)。同期は些細な問題ではなく、少なくともいくつかの擬似コードを持つ具体的な例や、関連する回答への参照が役立つでしょう。一般的な考え方は悪くありませんが、答えはより詳細になる可能性があります。 –
@MSalters:答えを慎重に読んでいれば、「要素数があらかじめ定義されたベクトル
- 1. アレイの内容をハードディスクに書き込む方法
- 2. 迷惑データをバイナリファイルに書き込む
- 3. ファイルにデータを書き込む
- 4. iPhoneカレンダー(チタン)にデータを書き込む
- 5. ファイルにデータを書き込む
- 6. データをPHPファイルに書き込む
- 7. データをcsvファイルに書き込む
- 8. Javaサーブレット - ファイルにデータを書き込む
- 9. スリルファイルにデータを書き込む
- 10. USBデバイスにデータを書き込む
- 11. Pythonでjsonにデータを書き込む
- 12. Excelファイルにデータを書き込む、MATLAB
- 13. データベースにデータを書き込む
- 14. テキストファイルにデータを書き込む
- 15. JavaFX Tableviewにデータを書き込む
- 16. PHPデータベースにデータを書き込む
- 17. C++のメモリにデータを書き込む
- 18. php mysql;データベースにデータを書き込む
- 19. TCL YAMLファイルにデータを書き込む
- 20. リモートVPSデータベースにデータを書き込む
- 21. Fast Secure Contact FormからMySQLデータベースに入力を書き込む方法は?
- 22. 上書きせずにExcelにデータを書き込む方法
- 23. 値のデータを書き込む
- 24. データでDXTreeListを書き込む
- 25. 書き込みキャッシュポリシーに書き込み/フェッチを書き込む
- 26. StreamReaderストリームからファイルを書き込む
- 27. QTcpSocketにデータを書き込むことができません
- 28. 制限付きサイズのテキストファイルにデータを書き込む
- 29. Googleスプレッドシート(Java付き)にデータを書き込む
- 30. チャネルネットにデータを書き込むことができません
が必要な帯域幅(60fpsの* sizeOfAFrame)を計算し、帯域幅を書き、ハードウェアと比較します。理論的にすべてのフレームを書き込むことができる場合は、キャッシュしてから別のスレッドから書き込んで最適化することができます。いくつかの遅延が数秒後に発生したファイルシステムを見てきましたが、これはマルチスレッドで修正されました。 fileStorageでの書き出しは、おそらくデータサイズが大幅に増加し、フォーマット/変換に時間がかかるため、生データを書き込むよりもはるかに時間がかかります。 – Micka
OP:60FPSは確実ですか? 1920x1080のRGB画像は6075 KiB、16ビットの奥行き、512x424のIRは424 KiBです.30 Hzでフレームあたり6923 KiBを超えると、〜203 MiB/sが得られます。 Mickaの言うとおり、ハードウェアによって異なります。生データを確実に書き込む必要があります。これは、リアルタイムに近い場所で圧縮することはできません(少なくともCPUのみではない)。いくつかのコードを表示し、HWと実際にどれくらい保存したいかを詳細に説明します(1つの連続したフレームシーケンスの時間的長さ)。 –