下面的屏幕截圖是MATLAB中函數執行的結果。MATLAB執行半色調mex包裝函數時崩潰?
a=imread('C:\CVIPtools\images\car.bmp');
ad=im2double(a);
ht = halftoneCVIP(ad,4,255, 0.5, 0, 0);
半色調:它是通過創建點圖案或抖動模式表示各種灰度級減小的灰度級的數量的方法,減少了有效空間分辨率也。
有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);
}