2011-06-02 72 views
-1

您好我在matlab中使用imread函數來讀取圖像。但是現在,如果我想在mex文件中使用這個圖像,我該怎麼辦? 我對圖像使用了im2double函數,然後將它傳遞給mex文件,但我得到的結果是不可接受的。以mex可接受的格式讀取matlab中的圖像

所以是有可用於

+0

什麼結果不可用? MEX文件預期如何處理圖像? – 2011-06-02 13:52:55

+0

圖像數據的格式是什麼? 8位灰度,RGB? – trondd 2011-07-05 09:40:40

回答

0

轉換爲加倍,並通過255劃分在墨西哥文件Matlab的雙陣列被用於表示圖像

+0

我正在嘗試實現圖像分割。問題是,如果我將圖像轉換爲雙精度圖像,首先執行rgb2gray函數,然後對圖像執行im2double函數,然後傳遞給mex文件,分割不合適。如果我用matlab編寫mex代碼(它相當慢),但它會給出正確的結果。 – Madhu 2011-06-04 05:06:29

+0

@Madhu,你應該提供一個更有建設性的OP,Daniel給出的答案對於OP中提供的少量信息是非常充足的。請添加一個最簡單的工作示例,其中包括遇到特定問題的* actual *代碼。我們都知道你可能有一個數據解釋/分割問題,但是如果你只提供一些你正在做的事情的文本解釋,**不能確定確切的原因。 – Herbert 2014-05-13 15:36:02

1

Matlab具有不同的數據類型的任何其它功能,例如uint8,in32,最常見的是雙倍。您可以在工作區或使用whos命令查看這些工作區。

Matlab workspace

這些數據類型是非常相似的那些在C(++)。因此,例如,我們可以寫這篇文章的C++/MEX代碼printint.cpp

#include <matrix.h> 
#include <mex.h> 


void mexFunction(int nargout, mxArray *argout[], int nargin, const mxArray *argin[]) { 
    int nCols = mxGetDimensions(argin[0])[1]; 
    int nRows = mxGetDimensions(argin[0])[0]; 

    int *data = (int *)mxGetData(argin[0]); 

    for(int row=0; row<nRows; ++row) { 
     for(int col=0; col<nCols-1; ++col) { 
      mexPrintf("%3d, ", data[nRows*col + row]); 
     } 
     mexPrintf("%3d\n", data[nRows*(nCols-1) + row]); 
    } 
} 

這段代碼簡單地打印所有數值矩陣,但它假設,在矩陣的元素整數。也就是說,mxGetData返回一個void指針,它可以指向任何類型的數據,也可以加倍。我把void指針指向一個整數指針,這是一個棘手的問題,但在C(++)中是允許的。

但這卻允許我對雙打運行printint,或任何類型的矩陣爲此事:

>> doubles=randi(10,[2,5]) 
doubles = 
     8  3  1  7 10 
     1  1  9  4  1 
>> whos('doubles') 
    Name   Size   Bytes Class  Attributes 
    doubles  2x5    80 double    
>> printint(doubles) 
    0, 0, 0, 0, 0 
1075838976, 1072693248, 1074266112, 1072693248, 1072693248 

可以看到,輸出是垃圾,我已經解釋雙打,好像他們是整數。這也可能導致分段錯誤,即如果一個輸入的數據的實際大小小於int的大小;像uint8。如果輸入一個整數,該方法不工作:

>> integers = int32(doubles) 
integers = 
        8   3   1   7   10 
        1   1   9   4   1 
>> whos('integers') 
    Name   Size   Bytes Class Attributes 
    integers  2x5    40 int32    
>> printint(integers) 
    8, 3, 1, 7, 10 
    1, 1, 9, 4, 1 

我通常承擔一定的數據類型爲輸入,因爲我用MEX加快代碼的某些部分,不想花時間創建靈活和愚蠢的API的。這是以輸入數據類型和假設數據類型不匹配時出現意外行爲爲代價的。因此,可以考慮以編程方式測試輸入的數據類型,以便正確處理它。

你的問題:如果你使用I = imread(文件名),MATLAB返回一個列x欄x通道類型UINT8,其等於一個無符號字符在3-d矩陣C(++)。爲了處理這些數據,可以編寫一個簡單的類來包裝圖像。這是在這裏完成:

#include <matrix.h> 
#include <mex.h> 

class MatlabImage { 
public: 
    MatlabImage(const mxArray *data) { 
     this->data = (unsigned char*)mxGetData(data); 
     this->rows = mxGetDimensions(data)[0]; 
     this->cols = mxGetDimensions(data)[1]; 
     this->channels = mxGetDimensions(data)[2]; 
    } 
    unsigned char *data; 
    int rows, cols, channels; 
    int get(int row, int col, int channel) { 
     return this->data[row + rows*(col + cols*channel)]; 
    } 
}; 

void mexFunction(int nargout, mxArray *argout[], int nargin, const mxArray *argin[]) { 
    MatlabImage image(argin[0]); 
    int row=316; int col=253; 
    mexPrintf("I(%d, %d) = (%3d, %3d, %3d)\n", row, col, image.get(row,col,0), image.get(row,col,1), image.get(row,col,2)); 
} 

這可以然後在Matlab中使用這樣的:

>> I = imread('workspace.png'); 
>> whos('I') 
    Name  Size    Bytes Class Attributes 
    I   328x344x3   338496 uint8    
>> getpixel(I) 
I(316, 253) = (197, 214, 233) 
>> I(317,254,:) 
ans(:,:,1) = 
    197 
ans(:,:,2) = 
    214 
ans(:,:,3) = 
    233 

人們也可以用雙打以類似的方式工作。 double(I)會將圖像轉換爲雙打,並且im2double(I)也是這樣,但是將所有值除以255,使得它們位於0和1之間。在這兩種情況下,一個需要投mxGetData(...)的結果(雙*)的代替(無符號字符*)。最後注意,C(++),從0開始和Matlab索引從1開始,所以將索引從一個傳遞到另一個總是需要在某處增加或減少索引。