質問

私は以前に同様の質問をしましたが、直接を見つけることができませんでした 答え.

誰かが、オブジェクトのレンダリングの深さバッファーをMATLABの図に抽出するためのサンプルコードを提供できますか?

したがって、OBJファイルや単純なサーフコールをロードして、レンダリングして、その深さバッファーに到達したいとしましょう。MATLABとOpenGLの両方を使用してどのコードを実行しますか。 IEこれをセットアップしてから実際のデータにアクセスするにはどうすればよいですか?

基本的に、Matlabsの強力なプロット関数を使用して、深さバッファを出すために基礎となるグラフィックスコンテキストにアクセスできるようにしたいと考えています。

注:バウンティはJoglを指定しますが、それは必須ではありません。上記のように機能し、MATLABで実行した後に深さバッファを提供できるコードで十分です)

役に立ちましたか?

解決

depthmap thing

今日、私は同僚と一緒に飲みに行きました、そして、5杯のビールといくつかのテキーラの後、私はこの質問を見つけて、「yaに持ってください!」と考えました。だから私はしばらく苦労していましたが、その後、MEXを使用した簡単なソリューションを見つけました。最後のウィンドウによって作成されたOpenGLコンテキストは、アクティブなままになる可能性があるため、スクリプトが同じスレッドで実行された場合、「C」からアクセスできると理論付けました。

フィルターの周波数応答をプロットする「testofMyFilter」と呼ばれる1つのMATLAB関数を呼び出す単純な「C」プログラムを作成しました(これは手元にある唯一のスクリプトでした)。これは、OpenGLを使用してレンダリングされます。次に、プログラムはGlgetViewPort()とGlreadPixels()を使用してOpenGLバッファーに到達します。次に、マトリックスを作成し、深度値で埋め、「tryTodisplayDepthmap」と呼ばれる2番目の関数に渡します。 imshow関数を使用して深度マップを表示するだけです。 MEX関数も値を返すことが許可されているため、ポストプロセスが別の関数である必要はないかもしれませんが、それがどのように行われるかを理解することができない状態ではありません。ただし、些細なはずです。私は今日初めてMexと仕事をしています。

それ以上遅滞なく、私が使用したソースコードがあります:

testofmyfilter.m

imp = zeros(10000,1);
imp(5000) = 1;
% impulse

[bwb,bwa] = butter(3, 0.1, 'high');
b = filter(bwb, bwa, imp);
% filter impulse by the filter

fs = 44100; % sampling frequency (all frequencies are relative to fs)
frequency_response=fft(b); % calculate response (complex numbers)
amplitude_response=20*log10(abs(frequency_response)); % calculate module of the response, convert to dB
frequency_axis=(0:length(b)-1)*fs/length(b); % generate frequency values for each response value
min_f=2;
max_f=fix(length(b)/2)+1; % min, max frequency

figure(1);
lighting gouraud
set(gcf,'Renderer','OpenGL')

semilogx(frequency_axis(min_f:max_f),amplitude_response(min_f:max_f),'r-') % plot with logarithmic axis using red line
axis([frequency_axis(min_f) frequency_axis(max_f) -90 10])  % set axis limits

xlabel('frequency [Hz]');
ylabel('amplitude [dB]'); % legend

grid on % draw grid

test.c

//You can include any C libraries that you normally use
#include "windows.h"
#include "stdio.h"
#include "math.h"
#include "mex.h"   //--This one is required

extern WINAPI void glGetIntegerv(int n_enum, int *p_value);

extern WINAPI void glReadPixels(int     x, 
    int     y, 
    int     width, 
    int     height, 
    int     format, 
    int     type, 
    void *      data);

#define GL_VIEWPORT                       0x0BA2
#define GL_DEPTH_COMPONENT                0x1902
#define GL_FLOAT                          0x1406

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    int viewport[4], i, x, y;
    int colLen;
    float *data;
    double *matrix;
    mxArray *arg[1];

    mexCallMATLAB(0, NULL, 0, NULL, "testofmyfilter");
    // call an .m file which creates OpenGL window and draws a plot inside

    glGetIntegerv(GL_VIEWPORT, viewport);
    printf("GL_VIEWPORT = [%d, %d, %d, %d]\n", viewport[0], viewport[1], viewport[2], viewport[3]);
    // print viewport dimensions, should be [0, 0, m, n]
    // where m and n are size of the GL window

    data = (float*)malloc(viewport[2] * viewport[3] * sizeof(float));
    glReadPixels(0, 0, viewport[2], viewport[3], GL_DEPTH_COMPONENT, GL_FLOAT, data);
    // alloc data and read the depth buffer

    /*for(i = 0; i < 10; ++ i)
        printf("%f\n", data[i]);*/
    // debug

    arg[0] = mxCreateNumericMatrix(viewport[3], viewport[2], mxDOUBLE_CLASS, mxREAL);
    matrix = mxGetPr(arg[0]);
    colLen = mxGetM(arg[0]);
    printf("0x%08x 0x%08x 0x%08x %d\n", data, arg[0], matrix, colLen); // debug
    for(x = 0; x < viewport[2]; ++ x) {
        for(y = 0; y < viewport[3]; ++ y)
            matrix[x * colLen + y] = data[x + (viewport[3] - 1 - y) * viewport[2]];
    }
    // create matrix, copy data (this is stupid, but matlab switches
    // rows/cols, also convert float to double - but OpenGL could have done that)

    free(data);
    // don't need this anymore

    mexCallMATLAB(0, NULL, 1, arg, "trytodisplaydepthmap");
    // pass the array to a function (returnig something from here
    // is beyond my understanding of mex, but should be doable)

    mxDestroyArray(arg[0]);
    // cleanup

    return;
}

trytodisplaydepthmap.m:

function [] = trytodisplaydepthmap(depthMap)

figure(2);
imshow(depthMap, []);
% see what's inside

これらすべてを同じディレクトリに保存し、test.cをコンパイルします(MATLABコンソールに入力します):

mex test.c Q:\MATLAB\R2008a\sys\lcc\lib\opengl32.lib

ここで、「Q: matlab r2008a sys lcc lib opengl32.lib」は「opengl32.lib」ファイルへのパスです。

最後に、Matlabコンソールで「テスト」を入力するだけですべてを実行します。フィルター周波数応答を備えたウィンドウと、深さバッファー付きの別のウィンドウを表示する必要があります。注フロントバッファとバックバッファーは、「C」コードが深さバッファーを読み取る瞬間に交換されるため、結果を取得するためにスクリプトを2回実行する必要がある場合があります(したがって、バックバッファーと再び結果を含むフロントバッファーが再びバッファーを含むようになります。そして、深さを読み取ることができます)。これは、「C」で自動的に実行できます。または、getFrame(GCF)を含めて試してみることができます。スクリプトの最後に(OpenGLからも読み戻されるため、バッファーを交換します。

これは、MATLAB 7.6.0.324(R2008A)で私にとって機能します。スクリプトが実行され、次のように吐き出します。

>>test
GL_VIEWPORT = [0, 0, 560, 419]
0x11150020 0x0bd39620 0x12b20030 419

そしてもちろん、それは画像を表示します。深度バッファー範囲はMATLABに依存し、非常に高くなる可能性があるため、生成された画像を理解することは簡単ではない場合があります。

他のヒント

の答えは正しいものです。以下は、クロスプラットフォームであるわずかにフォーマットされたよりシンプルなバージョンです。

mexgetDepth.cというファイルを作成します

#include "mex.h"   

#define GL_VIEWPORT                       0x0BA2
#define GL_DEPTH_COMPONENT                0x1902
#define GL_FLOAT                          0x1406

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    int viewport[4], i, x, y;
    int colLen;
    float *data;
    double *matrix;

    glGetIntegerv(GL_VIEWPORT, viewport);
    data = (float*)malloc(viewport[2] * viewport[3] * sizeof(float));
    glReadPixels(0, 0, viewport[2], viewport[3], GL_DEPTH_COMPONENT, GL_FLOAT, data);

    plhs[0] = mxCreateNumericMatrix(viewport[3], viewport[2], mxDOUBLE_CLASS, mxREAL);
    matrix = mxGetPr(plhs[0]);
    colLen = mxGetM(plhs[0]);

    for(x = 0; x < viewport[2]; ++ x) {
        for(y = 0; y < viewport[3]; ++ y)
            matrix[x * colLen + y] = data[x + (viewport[3] - 1 - y) * viewport[2]];
    }

    free(data);
    return;
}

次に、Windowsでコンパイルしている場合

mex mexGetDepth.c "path to OpenGL32.lib"

または、nixシステムの場合

mex mexGetDepth.c "path to opengl32.a"

次に、次の小さなスクリプトを実行して、新しい機能をテストします

peaks;
figure(1);
depthData=mexGetDepth;
figure
imshow(depthData);
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top