2012-01-14 13 views
10

प्राप्त करने के लिए मैटलैब में ओपनजीएल का उपयोग करके Ive ने एक समान प्रश्न पूछा और सीधे answer खोजने का प्रबंधन नहीं किया।गहराई बफर

कोई व्यक्ति किसी वस्तु के प्रतिपादन के गहराई बफर निकालने के लिए नमूना कोड प्रदान कर सकता है जो मैटलैब में एक आकृति में है?

तो मान लें कि मैं एक ओबीजे फ़ाइल लोड करता हूं या यहां तक ​​कि केवल एक साधारण सर्फ कॉल लोड करता हूं, इसे प्रस्तुत करता हूं और अब इसकी गहराई बफर प्राप्त करना चाहता हूं तो मैटलैब और ओपनजीएल दोनों का उपयोग करके मेरे लिए कौन सा कोड होगा। अर्थात। मैं इसे कैसे सेट अप करूं और फिर वास्तविक डेटा तक कैसे पहुंचूं?

मैं अनिवार्य रूप से मैटलैब्स शक्तिशाली साजिश कार्यों का उपयोग करने में सक्षम होना चाहता हूं और फिर गहराई से बफर प्राप्त करने के लिए अंतर्निहित ग्राफिक्स संदर्भ तक पहुंचने में सक्षम होना चाहता हूं।

नोट: बकाया JOGL निर्दिष्ट करता है लेकिन यह जरूरी नहीं है। किसी भी कोड है जो ऊपर के रूप में कार्य करता है और Matlab में इसे चलाने के बाद गहराई बफर के साथ मुझे प्रदान कर सकते हैं के लिए पर्याप्त है)

+1

आप हमेशा एक प्रश्न प्राप्त करने के लिए एक उपहार देने की कोशिश कर सकते हैं। – PeterT

+0

मेरा इरादा है, लेकिन केवल तब ही पता चला जब मैंने सवाल पोस्ट किया कि मुझे दो दिनों तक इंतजार करना होगा जब तक कि यह वर्तमान प्रश्न योग्य नहीं हो जाता। – twerdster

+0

क्या आप ऐसे उत्तरों को स्वीकार करते हैं जिनमें केवल मैटलैब शामिल है? मुझे जॉग के बारे में कोई जानकारी नहीं है। –

उत्तर

13

depthmap thing

आज, मैं अपने सहयोगियों के साथ पीने चला गया, और पाँच बियर और कुछ tequillas के बाद मैं इस पाया सवाल और विचार, "हाँ में है!" तो मैं थोड़ी देर के लिए संघर्ष कर रहा था लेकिन फिर मुझे मेक्स का उपयोग करके एक सरल समाधान मिला। मैंने सिद्धांत दिया कि अंतिम विंडो द्वारा बनाए गए ओपनजीएल संदर्भ को सक्रिय छोड़ा जा सकता है और इसलिए "सी" से पहुंच योग्य हो सकता है, यदि स्क्रिप्ट एक ही थ्रेड में चलती है।

मैंने एक साधारण "सी" प्रोग्राम बनाया जो एक मैटलैब फ़ंक्शन को कॉल करता है, जिसे "टेस्टोफिमीफिल्टर" कहा जाता है, जो फ़िल्टर की आवृत्ति प्रतिक्रिया को प्लॉट करता है (जो कि मेरे पास एकमात्र स्क्रिप्ट थी)। इसे ओपनजीएल का उपयोग करके प्रस्तुत किया जाता है। फिर ओपनजीएल बफर पर जाने के लिए प्रोग्राम glGetViewport() और glReadPixels() का उपयोग करता है। फिर यह एक मैट्रिक्स बनाता है, इसे गहराई के मानों से भरता है, और इसे दूसरे फ़ंक्शन पर पास करता है, जिसे "trytodisplaydepthmap" कहा जाता है। यह imshow फ़ंक्शन का उपयोग करके गहराई से प्रदर्शित करता है। ध्यान दें कि एमईएक्स फ़ंक्शन को मूल्यों को वापस करने की अनुमति है, इसलिए हो सकता है कि पोस्टप्रोसेसिंग को कोई अन्य कार्य न हो, लेकिन मैं यह समझने में सक्षम नहीं हूं कि यह कैसे किया जाता है। हालांकि, तुच्छ होना चाहिए। मैं आज पहली बार एमएक्स के साथ काम कर रहा हूं।

अधिक देर बिना

, वहाँ स्रोत कोड हैं मैं प्रयोग किया है:

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 

वें बचाओ एक ही निर्देशिका में ese, साथ test.c संकलन (टाइप कि मैटलैब कंसोल के लिए):

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

कहाँ "क्यू: \ MATLAB \ R2008a \ sys \ एल सी सी \ lib \ opengl32.lib" पथ है करने के लिए "opengl32 .lib "फ़ाइल।

और अंततः मैटलैब कंसोल में "परीक्षण" टाइप करके इसे निष्पादित करें। इसे फ़िल्टर आवृत्ति प्रतिक्रिया के साथ एक खिड़की लाना चाहिए, और गहराई बफर के साथ एक और खिड़की। नोट करें कि "सी" कोड गहराई बफर पढ़ता है, इस समय फ्रंट और बैक बफर को स्वैप किया जाता है, इसलिए किसी भी परिणाम प्राप्त करने के लिए स्क्रिप्ट को दो बार चलाने की आवश्यकता हो सकती है (इसलिए फ्रंट बफर जिसमें अब बैक बफर के साथ परिणाम स्वैप होते हैं, और गहराई को पढ़ा जा सकता है)।यह स्वचालित रूप से "सी" द्वारा किया जा सकता है, या आप getframe (gcf) सहित कोशिश कर सकते हैं; आपकी स्क्रिप्ट के अंत में (जो ओपनजीएल से भी वापस पढ़ता है, इसलिए यह आपके लिए बफर को स्वैप करता है, या कुछ)।

यह मैटलैब 7.6.0.324 (आर 2008 ए) में मेरे लिए काम करता है। स्क्रिप्ट चलता है और निम्न को थकाता है:

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

और निश्चित रूप से यह छवियों को प्रदर्शित करता है। ध्यान दें कि गहराई बफर रेंज Matlab पर निर्भर करती है, और काफी अधिक हो सकती है, इसलिए जेनरेट की गई छवियों का कोई भी अर्थ सरल नहीं हो सकता है।

+0

ओह, मैं आवश्यकताओं को याद किया। बेशक यह सर्फ() के साथ भी काम करता है। बस कोड को आजमाया: http://www.mathworks.com/help/techdoc/ref/surf.html और मिला: http://www.luki.webzdarma.cz/up/depthmap.png स्पष्ट –

+3

आप लायक हैं एक पदक, एक और बियर और 300 प्रतिनिधि। – twerdster

+1

क्या मैं आपको यह सब एक साथ रख सकता हूं और इसे एक अच्छा गणित सबमिशन में बना सकता हूं? मैं अकेला नहीं हूं जो इसे उपयोगी पाता है। – twerdster

2

स्वाइन का उत्तर सही है। यहां थोड़ा प्रारूपित और सरल संस्करण है जो क्रॉस-प्लेटफार्म है।

फिर एक फ़ाइल 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; 
} 

बनाएं जिसका नाम यदि आप खिड़कियों पर

mex mexGetDepth.c "path to OpenGL32.lib" 

का उपयोग कर संकलित करें या यदि आप एक nix प्रणाली

mex mexGetDepth.c "path to opengl32.a" 

तो निम्नलिखित चलाने पर नए फ़ंक्शन का परीक्षण करने के लिए छोटी स्क्रिप्ट

peaks; 
figure(1); 
depthData=mexGetDepth; 
figure 
imshow(depthData); 
+0

क्या हमें glGetIntegerv और glReadPixels fucntions को कहीं और घोषित करने की आवश्यकता है? मूल कोड में, यह बाहरी WINAPI शून्य का उपयोग करके किया जाता है ..., लेकिन मुझे यकीन नहीं है कि हम इसे लिनक्स में कैसे करेंगे –