执行半色调mex包装函数时MATLAB崩溃了吗?

时间:2015-10-14 21:52:42

标签: c++ c matlab image-processing mex

屏幕截图是在MATLAB中执行函数的结果。

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

enter image description here

半色调:它是一种通过创建点图案或抖动图案来表示各种灰度级来减少灰度级数的方法,也降低了有效的空间分辨率。

半色调有6种方法。 弗洛伊德·斯蒂恩伯格 2.抖动 3.门槛 4.集群3 5.集群4 6.第8组

* Image * CVIPhalftone(Image cvip_Image,int halftone,int      maxval,float 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)?**

我正在尝试重复使用C语言编写的半色调函数。我的目标是通过使用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);
 }

1 个答案:

答案 0 :(得分:4)

听起来像是mex代码中的分段错误。检查输入数据类型。确保从matlab传递的参数的数据类型与C函数预期的参数的数据类型相匹配。另外,请记住,matlab数组是列主要的,大小是[rows,cols],而不是[width height]。

如果您无法轻松发现问题,那么您需要将调试器附加到matlab流程,或者在代码中添加大量mexPrintf以查看确切的位置它失败了。