2015-10-14 38 views
1

下面的屏幕截圖是MATLAB中函數執行的結果。MATLAB執行半色調mex包裝函數時崩潰?

a=imread('C:\CVIPtools\images\car.bmp'); 
ad=im2double(a); 
ht = halftoneCVIP(ad,4,255, 0.5, 0, 0); 

enter image description here

半色調:它是通過創建點圖案或抖動模式表示各種灰度級減小的灰度級的數量的方法,減少了有效空間分辨率也。

有6種半色調方法。 1.弗洛伊德Stienberg 2.抖動3. 閾 4.羣集3 5.羣集4 6.羣集8

*圖像* CVIPhalftone(圖像cvip_Image,INT的半色調,整數 MAXVAL,浮fthreshval,CVIP_BOOLEAN retain_image, CVIP_BOOLEAN詳細)

<cvip_Image> - pointer to input image 
    <halftone> - indicates method used to convert from grays- 
cale to binary. (one of QT_FS, QT_THRESH, QT_DITHER8, 
QT_CLUSTER3, QT_CLUSTER4, QT_CLUSTER8) 
    <maxval> - specifies maximum range of input image (usually 
255) 
    <fthreshval> - threshold value (for QT_THRESH) between [0.0 
... 1.0]. 
    <retain_image> - retain image after writing (CVIP_YES or 
CVIP_NO)? 
    <verbose> - shall I be verbose (CVIP_YES or CVIP_NO)?** 

我想重用origianlly用C編寫的我objec半色調功能通過使用MEX編寫包裝函數,可以在MATLAB中使該函數可執行。

下面是我寫的代碼,我可以成功編譯沒有任何錯誤。但是,執行MATLAB函數時會崩潰。有沒有人知道背後的原因?

#include <stdio.h> 
#include <math.h> 
#include <stdlib.h> 
#include "mex.h" 
#include "CVIPtools.h" 
#include "CVIPimage.h" 
#include "CVIPdef.h" 
#include "CVIPmap.h" 
#include "limits.h" 
#include "threshold.h" 
#include <float.h> 
#include "CVIPmatrix.h" 

#include "dithers.h" 
#include "CVIPhalftone.h" 

#define CVIP_WHITE 1 
#define CVIP_BLACK 0 

#define FS_SCALE 1024 
#define HALF_FS_SCALE 512 


Image *CVIPhalftone(Image *cvip_Image, int halftone, int maxval, float fthreshval, CVIP_BOOLEAN retain_image, CVIP_BOOLEAN verbose) 
{ 
    byte* grayrow; 
    register byte* gP; 
    byte* bitrow; 
    register byte* bP; 
    int rows, cols, row; 
    int col, limitcol, format; 
    char function_name[] = {"CVIPhalftone"}; 
    long threshval, sum; 
    long* thiserr; 
    long* nexterr; 
    long* temperr; 
    int fs_direction; 
    Image *bit_Image; 

    cols = cvip_Image->image_ptr[0]->cols; 
    rows = cvip_Image->image_ptr[0]->rows; 

    bit_Image = (Image *) image_allocate(cvip_Image->image_format, BINARY, 1, rows, cols, CVIP_BYTE, REAL); 

    format = cvip_Image->image_format; 
    if(!(format==PBM || format==PGM || format==TIF || format==RAS || format==BIN || format==ITX)) { 
     if(verbose) 
      fprintf(stderr, "\n%s: casting image to format that supports binary images - (PBM).\n",function_name); 
     bit_Image->image_format = PBM; 
    } 
    mexPrintf("Till here 1\n"); 
    /* Initialize. */ 
    switch (halftone) 
    { 
    case QT_FS:   // QT_FS=1 defined in CVIPhalftone.h 

    if(verbose) 
     fprintf(stderr, "%s: performing boustrophedonic Floyd-Steinberg error diffusion.\n\n",function_name); 
    /* Initialize Floyd-Steinberg error vectors. */ 
    thiserr = (long*) calloc(cols + 2, sizeof(long)); 
    nexterr = (long*) calloc(cols + 2, sizeof(long)); 
    srand((int) (time(0)^getpid())); 
    for (col = 0; col < cols + 2; ++col) 
     thiserr[col] = (rand() % FS_SCALE - HALF_FS_SCALE)/4; 
     /* (random errors in [-FS_SCALE/8 .. FS_SCALE/8]) */ 
    fs_direction = 1; 
    threshval = fthreshval * FS_SCALE; 
    break; 

    case QT_THRESH:   // QT_THRESH=2 defined in CVIPhalftone.h 

    threshval = fthreshval * maxval + 0.999999; 
    if(verbose) { 
     fprintf(stderr, "%s: performing simple thresholding operation.\n",function_name); 
     fprintf(stderr, "%s: threshold level - %ld.\n\n",function_name, threshval); 
    } 
    break; 


    case QT_DITHER8:  // QT_DITHER8=3 defined in CVIPhalftone.h 
    break; 


    case QT_CLUSTER3:  // QT_CLUSTER3=4 defined in CVIPhalftone.h 
    break; 

    case QT_CLUSTER4:  // QT_CLUSTER4=5 defined in CVIPhalftone.h 

    break; 

    case QT_CLUSTER8:  // QT_CLUSTER8=6 defined in CVIPhalftone.h 

    break; 

    default: 
    fprintf(stderr, "%s: can't happen... but apparently something did?!?\n" , function_name); break; 
    } 
    mexPrintf("Till here 2\n"); 
    for (row = 0; row < rows; ++row) 
    { 
    grayrow = (byte *) ((byte **) cvip_Image->image_ptr[0]->rptr)[row]; 
    bitrow = (byte *) ((byte **) bit_Image->image_ptr[0]->rptr)[row]; 

    switch (halftone) 
     { 
     case QT_FS: 

     for (col = 0; col < cols + 2; ++col) 
     nexterr[col] = 0; 
     if (fs_direction) 
     { 
     col = 0; 
     limitcol = cols; 
     gP = grayrow; 
     bP = bitrow; 
     } 
     else 
     { 
     col = cols - 1; 
     limitcol = -1; 
     gP = &(grayrow[col]); 
     bP = &(bitrow[col]); 
     } 
     do 
     { 
     sum = ((long) *gP * FS_SCALE)/maxval + thiserr[col + 1]; 
     if (sum >= threshval) 
      { 
      *bP = CVIP_WHITE; 
      sum = sum - threshval - HALF_FS_SCALE; 
      } 
     else 
      *bP = CVIP_BLACK; 

     if (fs_direction) 
      { 
      thiserr[col + 2] += (sum * 7)/16; 
      nexterr[col ] += (sum * 3)/16; 
      nexterr[col + 1] += (sum * 5)/16; 
      nexterr[col + 2] += (sum )/16; 

      ++col; 
      ++gP; 
      ++bP; 
      } 
     else 
      { 
      thiserr[col ] += (sum * 7)/16; 
      nexterr[col + 2] += (sum * 3)/16; 
      nexterr[col + 1] += (sum * 5)/16; 
      nexterr[col ] += (sum )/16; 

      --col; 
      --gP; 
      --bP; 
      } 
     } 
     while (col != limitcol); 
     temperr = thiserr; 
     thiserr = nexterr; 
     nexterr = temperr; 
     fs_direction = ! fs_direction; 
     break; 

     case QT_THRESH: 

     for (col = 0, gP = grayrow, bP = bitrow; col < cols; ++col, ++gP, ++bP) 
     if (*gP >= threshval) 
      *bP = CVIP_WHITE; 
     else 
      *bP = CVIP_BLACK; 
     break; 

     case QT_DITHER8: 

     for (col = 0, gP = grayrow, bP = bitrow; col < cols; ++col, ++gP, ++bP) 
     if (*gP >= dither8[row % 16][col % 16] * (maxval + 1)/256) 
      *bP = CVIP_WHITE; 
     else 
      *bP = CVIP_BLACK; 
     break; 

     case QT_CLUSTER3: 

     for (col = 0, gP = grayrow, bP = bitrow; col < cols; ++col, ++gP, ++bP) 
     if (*gP >= cluster3[row %6][col %6 ] * (maxval + 1)/18) 
      *bP = CVIP_WHITE; 
     else 
      *bP = CVIP_BLACK; 
     break; 

     case QT_CLUSTER4: 

     for (col = 0, gP = grayrow, bP = bitrow; col < cols; ++col, ++gP, ++bP) 
     if (*gP >= cluster4[row %8][col%8] * (maxval + 1)/32) 
      *bP = CVIP_WHITE; 
     else 
      *bP = CVIP_BLACK; 
     break; 

     case QT_CLUSTER8: 

     for (col = 0, gP = grayrow, bP = bitrow; col < cols; ++col, ++gP, ++bP) 
     if (*gP >= cluster8[row %16][col %16] * (maxval + 1)/128) 
      *bP = CVIP_WHITE; 
     else 
      *bP = CVIP_BLACK; 
     break; 

     default: 
     fprintf(stderr, "%s: can't happen... but apparently something did?!?\n" , function_name); break; 
     } 
    } 
    mexPrintf("Till here 1\n"); 
if(!retain_image) 
    image_free(cvip_Image); 
return bit_Image; 
mexPrintf("Till here 2\n"); 
} 



void midd(int choice, double *indata, double *outdata, int n, int row, int col, int bands) 
{ 
    Image *inputImage; 
    byte  **image;  
    unsigned int  r, c;  
    int i; 
    unsigned int no_of_rows, 
      no_of_cols, 
      no_of_bands;  
    COLOR_FORMAT color_space; 
    int check=0; 
    no_of_bands = bands; 

    no_of_rows = row; 

    no_of_cols = col; 

    for (i=0;i<n;i++) 
    { if (check<indata[i]) 
      check=indata[i]; 
    } 


    if (check<=1){ 

     for (i=0;i<n;i++){ 
     //outdata[i]= floor(255*indata[i]); //By Krishna Regmi 
     indata[i]= floor(255*indata[i]); 
    }} 
    else 
    {for (i=0;i<n;i++) 
     //outdata[i]= floor(indata[i]);  //By Krishna Regmi 
     indata[i]= floor(indata[i]); 
    } 

    // mexPrintf("\ first value after scaling to 0-255 %f\n", outdata[0]); 

    // typedef enum {PBM, PGM, PPM, EPS, TIF, GIF, RAS, ITX, IRIS, CCC, BIN, VIP, GLR, BTC, BRC, HUF, ZVL, ARITH, BTC2, BTC3, DPC, ZON, ZON2, SAFVR, JPG, WVQ, FRA, VQ, XVQ} IMAGE_FORMAT; 

    //typedef enum {BINARY, GRAY_SCALE, RGB, HSL, HSV, SCT, CCT, LUV, LAB, XYZ} 

    inputImage=new_Image (BMP, RGB, no_of_bands, row, col, CVIP_BYTE, REAL); 

    for(bands=0; bands < no_of_bands; bands++) { 
    image = getData_Image(inputImage, bands); 
    for(r=0; r < no_of_rows; r++) { 
      for(c=0; c < no_of_cols; c++) 
      { 
       image[r][c]=outdata[r+row*c+row*col*bands];  /* passing data from MATLAB variable to CVIPtools variable */ 
      } 
     } 
    } 


    //Image *CVIPhalftone(Image *cvip_Image, int halftone, int maxval, float fthreshval, CVIP_BOOLEAN retain_image, CVIP_BOOLEAN verbose) 

    //inputImage= CVIPhalftone(cvipImage,QT_THRESH,255,0.5,CVIP_NO,CVIP_NO); 

    inputImage = CVIPhalftone(inputImage, choice, 255, 0.5, CVIP_NO, CVIP_NO); 

for(bands=0; bands < no_of_bands; bands++) { 
     image = getData_Image(inputImage, bands); 
    for(r=0; r < no_of_rows; r++) { 
      for(c=0; c < no_of_cols; c++) 
      { 
       outdata[r+row*c+row*col*bands] = floor(image[r][c]);  /* passing data back to MATLAB variable from CVIPtools variable */ 

      } 
     } 
     } 

    }  /* end of wrapper function*/ 


/* main gateway function*/ 

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 
{ 
    double *outdata, *indata; 
    int r,c,bands; 
    const mwSize *dim_array; 
    int choice,n; 
    //char color_type; 
    // COLOR_FORMAT color_space; 
    //int choice; 
    //int n = mxGetNumberOfElements(prhs[0]); 
    n = mxGetNumberOfElements(prhs[0]); 
    indata = mxGetData(prhs[0]); 
    //double *indata = (double *)mxGetData(prhs[0]); 
    dim_array = mxGetDimensions(prhs[0]); 
    //color_type = mxGetChars(prhs[1]); 

    choice = mxGetScalar(prhs[1]); 
    r   = dim_array[0]; 
    c   = dim_array[1]; 
     bands   = dim_array[2]; 

     // mexPrintf("total elements %d\n", n); 

    if(bands==3){ 

     plhs[0] = mxCreateNumericArray(3, dim_array, mxDOUBLE_CLASS, mxREAL); 

    } 
    else 
    { plhs[0] = mxCreateDoubleMatrix(r,c,mxREAL); 
     bands=1; 
     } 
     outdata = mxGetData(plhs[0]); 
    midd(choice, indata, outdata, n, r, c, bands); 
} 

回答

4

聽起來像mex代碼中的段錯誤。檢查輸入數據類型。確保從matlab傳遞的參數的數據類型與C函數期望的數據類型匹配。另外,請記住,matlab數組是列主要的,大小是[行,列],而不是[寬度高度]。

如果你不容易發現問題,那麼你需要在matlab過程中附加一個調試器,或者在你的代碼中加入很多mexPrintf來查看它究竟發生了什麼故障。