2

GStreamer と OpenCV を使用してビデオ処理用のアプリケーションを開発しています。タスクは、OpenCV ソースからイメージをフェッチして GStreamer パイプラインにプッシュ/プルし (変換とデコードを行い、後でビデオ データをストリーミングする必要があります)、Java 言語環境でイメージを処理することです。

そこで、このタスクを管理する C でネイティブ フレームワークを構築します。ここで、JNI を使用して C ライブラリにアクセスし、実行中の GStreamer メイン ループを JVM に接続しました。SDL ライブラリを使用する画像処理に関係のないスレッドがいくつかありますが、Java メソッドを呼び出していません。どうやらこれまでのところ動作します。生の画像を Java に取り込み、ByteBuffer(ネイティブ側で作成された)getメソッドとSystem.err.println.

問題は、これらの画像を何らかの方法で GUI に表示することです。グラフィカル環境には Swing フレームワークを使用しています。

JPanelそこで、通常どおりに を拡張することで、すばやく汚れたイメージ ビューを作成しました。これは通常、Java のみを使用する場合に機能します。

paintメソッドを使用して画像を描画するメソッドをオーバーライドしますGraphics.drawImage。イメージは、ネイティブ コールバックによって配信された生データを整数配列にコピーし、この整数配列を に割り当てることによって生成されますMemoryImageSourcecreateImage(JFrame の) メソッドを使用してImageオブジェクトを取得します。すべてが明らかに有効な参照を返します。例外はスローされません。少なくとも私には見えません。

MemoryImageSourceこれまでに生成されていない画像にバイト配列を使用するだけでなく、いくつかの方法を試しました。しかし、データはそこにあり、私はそれを読むことができます!

データをコピーしてバイト データを表示することはできますが、カスタムJPanelビュー エリアに表示可能な画像を表示できません。画像が完全に黒または透明か何かのようです。

この問題は本当に私を打ち負かします、私はこれがうまくいくように説得する方法がわかりません. ここでのスレッド化にはいくつかの問題があると思います。しかし、この特定のシナリオに関するこれ以上のリソースはありません。

私は何を間違っていますか、または正しい方法でそれを行う方法を改善します。

追加:ウィンドウのサイズを変更すると、アプリケーションがクラッシュしたり、GUIがフリーズしたりすることもあるので、今のところこれを避けています。そのため、ネイティブ スレッドに問題があります。

4

1 に答える 1

1

OpenCV-Library を使用して、システムにインストールされたカメラにアクセスします。取得した各フレームから寸法、色情報、BGR サンプルを取得し、GStreamer AppSrc が、全体の初期化に使用されたフレーム レートに従って画像をビデオ処理パイプラインに取り込みます。最初のパイプラインは次のようになります。

OpenCV-Camera --> AppSrc --> VideoRate --> ffmpegcolorspace --> AppSink

すぐにもっと複雑になるでしょうが、今はこんな感じです。

AppSink は、Gstreamer の「new-buffer」シグナルで関数を呼び出します (特に、私の問題とは関係ありません)。これらのコールバック実装は、画像の色と寸法、およびそのサンプル バッファを提供する Java オブジェクト関数を呼び出します。これは、私が何をしているかについての簡単な情報です。

今私の問題に:

私の問題を解決したようです。私は今、別の方法で画像を作成しましたが、今ではうまくいきます。

次のようにメモリ イメージ ソースを使用する代わりに:

//constructor, callback whatever
imageSource = new MemoryImageSource(data.width,data.height,rawdata,0,data.width);
...
//Paint method of a JFrame or what ever ...
...
image img = createImage(imageSource);
setBounds(100,100,img.getWidth(null),img.getHeight(null));
createBufferStrategy(2);

BufferStrategy strategy = getBufferStrategy();

Graphics gr = strategy.getDrawGraphics();           
gr.drawImage(img, 0, 0, null);
gr.dispose();

strategy.show();

私は今私のために働くこれらのいくつかの行を使用します:

int[] nBits = {8, 8, 8};
ComponentSampleModel sampleModel = new ComponentSampleModel(DataBuffer.TYPE_BYTE, width, height, channels, width * channels, new int[] {2, 1, 0});
ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB);
ColorModel colorModel = new ComponentColorModel(colorSpace, nBits, false, false,Transparency.OPAQUE,DataBuffer.TYPE_BYTE);

DataBufferByte db = new DataBufferByte(new byte[][] {buffer}, buffer.length);

WritableRaster raster = Raster.createWritableRaster(sampleModel, db, new Point(0, 0));
BufferedImage image = new BufferedImage(colorModel, raster, false, null);

ここで、buffer は、ネイティブ側から呼び出されたメソッドを介して取得した raw バイト サンプル配列を表します。

また、UI がフリーズしたり、これらのエラー メッセージがスローされてクラッシュしたりするなど、swing を使用して他のいくつかの問題に遭遇しました。

[xcb] Unknown request in queue while dequeuing
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
java: ../../src/xcb_io.c:178: dequeue_pending_request: assertion »!xcb_xlib_unknown_req_in_deq« failed.

これはUIManager.setLookAndFeel()、ウィンドウの外観をシステムのデフォルトに設定する方法を使用したためです。デフォルト システムの「ルック アンド フィール」を使用する場合、Swing がネイティブ UI フレームワークを使用することを知らなかったので、これを問題と関連付けませんでした。これを削除すると、問題が解決します。私の調査により、これが Linux (Ubuntu) マシン上の Java のみ (ネイティブ部分ではない) で発生することを説明しているフォーラム投稿(ドイツ語) にたどり着きましたが、同じアプリケーションは変更なしで Windows マシン上で動作します。したがって、それを削除すると問題が解決しました。私の「画像が表示されない問題」は何らかの形でこれに関連していると思いますが、今は働いているのでわかりませんし、気にしません。

于 2012-05-28T09:03:55.060 に答える