void haarlick2D(ImageMatrix *Im, double distance, double *out) { int a,x,y; unsigned char **p_gray; TEXTURE *features; long angle; double min[14],max[14],sum[14]; double min_value=INF,max_value=-INF;//max_value=pow(2,Im->bits)-1; if (distance<=0) distance=1; p_gray=new unsigned char *[Im->height]; for (y=0;y<Im->height;y++) p_gray[y]=new unsigned char[Im->width]; /* for more than 8 bits - normalize the image to (0,255) range */ Im->BasicStatistics(NULL, NULL, NULL, &min_value, &max_value, NULL, 0); for (y=0;y<Im->height;y++) for (x=0;x<Im->width;x++) if (Im->bits>8) p_gray[y][x]=(unsigned char)((Im->pixel(x,y,0).intensity-min_value)*(255.0/(max_value-min_value))); else p_gray[y][x]=(unsigned char)(Im->pixel(x,y,0).intensity); for (a=0;a<14;a++) { min[a]=INF; max[a]=-INF; sum[a]=0; } for (angle=0;angle<=135;angle=angle+45) { features=Extract_Texture_Features((int)distance, angle, p_gray,Im->height,Im->width, (int)max_value); /* (1) Angular Second Moment */ sum[0]+=features->ASM; if (features->ASM<min[0]) min[0]=features->ASM; if (features->ASM>max[0]) max[0]=features->ASM; /* (2) Contrast */ sum[1]+=features->contrast; if (features->contrast<min[1]) min[1]=features->contrast; if (features->contrast>max[1]) max[1]=features->contrast; /* (3) Correlation */ sum[2]+=features->correlation; if (features->correlation<min[2]) min[2]=features->correlation; if (features->correlation>max[2]) max[2]=features->correlation; /* (4) Variance */ sum[3]+=features->variance; if (features->variance<min[3]) min[3]=features->variance; if (features->variance>max[3]) max[3]=features->variance; /* (5) Inverse Diffenence Moment */ sum[4]+=features->IDM; if (features->IDM<min[4]) min[4]=features->IDM; if (features->IDM>max[4]) max[4]=features->IDM; /* (6) Sum Average */ sum[5]+=features->sum_avg; if (features->sum_avg<min[5]) min[5]=features->sum_avg; if (features->sum_avg>max[5]) max[5]=features->sum_avg; /* (7) Sum Variance */ sum[6]+=features->sum_var; if (features->sum_var<min[6]) min[6]=features->sum_var; if (features->sum_var>max[6]) max[6]=features->sum_var; /* (8) Sum Entropy */ sum[7]+=features->sum_entropy; if (features->sum_entropy<min[7]) min[7]=features->sum_entropy; if (features->sum_entropy>max[7]) max[7]=features->sum_entropy; /* (9) Entropy */ sum[8]+=features->entropy; if (features->entropy<min[8]) min[8]=features->entropy; if (features->entropy>max[8]) max[8]=features->entropy; /* (10) Difference Variance */ sum[9]+=features->diff_var; if (features->diff_var<min[9]) min[9]=features->diff_var; if (features->diff_var>max[9]) max[9]=features->diff_var; /* (11) Diffenence Entropy */ sum[10]+=features->diff_entropy; if (features->diff_entropy<min[10]) min[10]=features->diff_entropy; if (features->diff_entropy>max[10]) max[10]=features->diff_entropy; /* (12) Measure of Correlation 1 */ sum[11]+=features->meas_corr1; if (features->meas_corr1<min[11]) min[11]=features->meas_corr1; if (features->meas_corr1>max[11]) max[11]=features->meas_corr1; /* (13) Measure of Correlation 2 */ sum[12]+=features->meas_corr2; if (features->meas_corr2<min[12]) min[12]=features->meas_corr2; if (features->meas_corr2>max[12]) max[12]=features->meas_corr2; /* (14) Maximal Correlation Coefficient */ sum[13]+=features->max_corr_coef; if (features->max_corr_coef<min[13]) min[13]=features->max_corr_coef; if (features->max_corr_coef>max[13]) max[13]=features->max_corr_coef; free(features); } for (y=0;y<Im->height;y++) delete p_gray[y]; delete p_gray; /* copy the values to the output vector in the right output order */ double temp[28]; for (a=0;a<14;a++) { temp[a]=sum[a]/4; temp[a+14]=max[a]-min[a]; } out[0]=temp[0]; out[1]=temp[14]; out[2]=temp[1]; out[3]=temp[15]; out[4]=temp[2]; out[5]=temp[16]; out[6]=temp[9]; out[7]=temp[23]; out[8]=temp[10]; out[9]=temp[24]; out[10]=temp[8]; out[11]=temp[22]; out[12]=temp[11]; out[13]=temp[25]; out[14]=temp[4]; out[15]=temp[18]; out[16]=temp[13]; out[17]=temp[27]; out[18]=temp[12]; out[19]=temp[26]; out[20]=temp[5]; out[21]=temp[19]; out[22]=temp[7]; out[23]=temp[21]; out[24]=temp[6]; out[25]=temp[20]; out[26]=temp[3]; out[27]=temp[17]; }
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) { mxArray* img; u_int8_t* p_img; /*The image from Matlab*/ u_int8_t** p_gray; /*Image converted for texture calcs*/ int mrows; /*Image height*/ int ncols; /*Image width*/ TEXTURE* features ; /*Returned struct of features*/ int i ; int imgsize[2] ; int imgindex[2] ; long offset ; int outputsize[2] ; /*Dimensions of TEXTURE struct*/ int outputindex[2] ; float* output ; /*Features to return*/ int distance, angle; /*Parameters for texture calculations*/ if (nrhs != 3) mexErrMsgTxt("\n mb_texture (im, distance, angle),\n\n" "This function returns the 14 image texture statistics described by R. Haralick.\n" "The statistics are calculated from the image's co-occurence matrix specified\n" "for a particular distance and angle. Distance is measured in pixels and\n" "the angle is measured in degrees.\n"); else if (nlhs != 1) mexErrMsgTxt("mb_texture returns a single output.\n") ; if (!mxIsNumeric(prhs[0])) mexErrMsgTxt("mb_texture requires the first input to be numeric\n") ; if (!mxIsUint8(prhs[0])) mexCallMATLAB(1, &img, 1, prhs, "im2uint8_dynamic_range"); else img = prhs[0]; mrows = mxGetM(img) ; ncols = mxGetN(img) ; if (!(mrows > 1) || !(ncols > 1)) mexErrMsgTxt("mb_texture requires an input image, not a scalar.\n") ; if ( !mxIsNumeric(prhs[1]) || (mxIsComplex(prhs[1])) ) mexErrMsgTxt("The second argument (distance) should be numeric and not complex."); if ( !mxIsNumeric(prhs[2]) || (mxIsComplex(prhs[2])) ) mexErrMsgTxt("The third argument (angle) should be numeric and not complex."); p_img = (u_int8_t*) mxGetData(img) ; distance = (double) mxGetScalar(prhs[1]) ; angle = (double) mxGetScalar(prhs[2]) ; imgsize[col] = ncols ; imgsize[row] = mrows ; p_gray = mxCalloc(mrows, sizeof(u_int8_t*)) ; if(p_gray) { for(i=0; i<mrows ; i++) { p_gray[i] = mxCalloc(ncols, sizeof(u_int8_t)) ; if(!p_gray[i]) mexErrMsgTxt("mb_texture : error allocating p_gray[i]") ; } } else mexErrMsgTxt("mb_texture : error allocating p_gray") ; for(imgindex[row] = 0 ; imgindex[row] < imgsize[row] ; imgindex[row]++) for(imgindex[col]=0; imgindex[col] < imgsize[col]; imgindex[col]++) { offset = mxCalcSingleSubscript(prhs[0], 2, imgindex) ; p_gray[imgindex[row]][imgindex[col]] = p_img[offset] ; } if (! (features=Extract_Texture_Features(distance, angle, p_gray,mrows, ncols, 255))) mexErrMsgTxt("ERROR: Could not compute Haralick Features."); outputsize[row] = 14; outputsize[col] = 1; plhs[0] = mxCreateNumericArray(2, outputsize, mxSINGLE_CLASS, mxREAL) ; if (!plhs[0]) mexErrMsgTxt("mb_texture: error allocating return variable.") ; output = (float*)mxGetData(plhs[0]) ; /* Copy the features into the return variable */ outputindex[row]=0 ; outputindex[col]=0 ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->ASM; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->contrast; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->correlation; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->variance; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->IDM; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->sum_avg; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->sum_var; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->sum_entropy; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->entropy; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->diff_var; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->diff_entropy; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->meas_corr1; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->meas_corr2; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->max_corr_coef; /* Memory clean-up. */ for (i=0; i<mrows ; i++) mxFree(p_gray[i]) ; mxFree(p_gray) ; /* features is calloc'd inside of Extract_Texture_Features */ free(features) ; }
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) { int distance; /*parameter for texture calculations*/ u_int8_t* p_img; /*The image from Matlab*/ u_int8_t** p_gray; /*Image converted for texture calcs*/ int mrows; /*Image height*/ int ncols; /*Image width*/ TEXTURE_FEATURE_MAP* features_used ; /*Indicate which features to calc.*/ TEXTURE* features ; /*Returned struct of features*/ int i ; int imgsize[2] ; int imgindex[2] ; long offset ; int outputsize[2] ; /*Dimensions of TEXTURE struct*/ int outputindex[2] ; float* output ; /*Features to return*/ u_int8_t* outtest ; if (nrhs != 1) { mexErrMsgTxt("ml_texture requires a single input argument.\n") ; } else if (nlhs != 1) { mexErrMsgTxt("ml_texture returns a single output.\n") ; } if (!mxIsNumeric(prhs[0])) { mexErrMsgTxt("ml_texture requires a single numeric input.\n") ; } if (!mxIsUint8(prhs[0])) { mexErrMsgTxt("ml_texture requires a single input of type unsigned 8-bit integer.\n") ; } mrows = mxGetM(prhs[0]) ; ncols = mxGetN(prhs[0]) ; if(!(mrows > 1) || !(ncols > 1)) { mexErrMsgTxt("ml_texture requires an input image, not a scalar.\n") ; } p_img = (u_int8_t*)mxGetData(prhs[0]) ; distance = 1 ; features_used = mxCalloc(1, sizeof(TEXTURE_FEATURE_MAP)) ; if(!features_used) mexErrMsgTxt("ml_texture: error allocating features_used.") ; features_used->ASM = 1 ; features_used->contrast = 1 ; features_used->correlation = 1 ; features_used->variance = 1 ; features_used->IDM = 1 ; features_used->sum_avg = 1 ; features_used->sum_var = 1 ; features_used->sum_entropy = 1 ; features_used->entropy = 1 ; features_used->diff_var = 1 ; features_used->diff_entropy = 1 ; features_used->meas_corr1 = 1 ; features_used->meas_corr2 = 1 ; features_used->max_corr_coef = 0 ; imgsize[col] = ncols ; imgsize[row] = mrows ; p_gray = mxCalloc(mrows, sizeof(u_int8_t*)) ; if(p_gray) { for(i=0; i<mrows ; i++) { p_gray[i] = mxCalloc(ncols, sizeof(u_int8_t)) ; if(!p_gray[i]) mexErrMsgTxt("ml_texture : error allocating p_gray[i]") ; } } else mexErrMsgTxt("ml_texture : error allocating p_gray") ; for(imgindex[row] = 0 ; imgindex[row] < imgsize[row] ; imgindex[row]++) for(imgindex[col] = 0 ; imgindex[col] < imgsize[col] ; imgindex[col]++ ) { offset = mxCalcSingleSubscript(prhs[0], 2, imgindex) ; p_gray[imgindex[row]][imgindex[col]] = p_img[offset] ; } features=Extract_Texture_Features(distance,p_gray,mrows,ncols,features_used) ; /* outputsize[row] = mrows ; outputsize[col] = ncols ; plhs[0] = mxCreateNumericArray(2, outputsize, mxUINT8_CLASS, mxREAL) ; if (!plhs[0]) mexErrMsgTxt("ml_texture: error allocating return variable.") ; outtest = (u_int8_t*)mxGetData(plhs[0]) ; for(imgindex[row] = 0 ; imgindex[row] < imgsize[row] ; imgindex[row]++) for(imgindex[col] = 0 ; imgindex[col] < imgsize[col] ; imgindex[col]++ ) { offset = mxCalcSingleSubscript(prhs[0], 2, imgindex) ; outtest[offset] = p_gray[imgindex[row]][imgindex[col]] ; } */ outputsize[row] = 14 ; outputsize[col] = 6 ; plhs[0] = mxCreateNumericArray(2, outputsize, mxSINGLE_CLASS, mxREAL) ; if (!plhs[0]) mexErrMsgTxt("ml_texture: error allocating return variable.") ; output = (float*)mxGetData(plhs[0]) ; /* Copy the features into the return variable */ for(outputindex[col]=0 ; outputindex[col] < outputsize[col] ; outputindex[col]++) { outputindex[row]=0 ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->ASM[outputindex[col]] ; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->contrast[outputindex[col]] ; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->correlation[outputindex[col]] ; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->variance[outputindex[col]] ; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->IDM[outputindex[col]] ; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->sum_avg[outputindex[col]] ; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->sum_var[outputindex[col]] ; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->sum_entropy[outputindex[col]] ; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->entropy[outputindex[col]] ; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->diff_var[outputindex[col]] ; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->diff_entropy[outputindex[col]] ; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->meas_corr1[outputindex[col]] ; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->meas_corr2[outputindex[col]] ; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->max_corr_coef[outputindex[col]] ; } /* Memory clean-up. */ for(i=0; i<mrows ; i++) { mxFree(p_gray[i]) ; } mxFree(p_gray) ; mxFree(features_used) ; /* val is calloc'd inside of Extract_Texture_Features */ free(features) ; }
int main (int argc, char* argv[]) { OID ID; int distance, angle; u_int8_t** p_gray; /*Image converted for texture calcs*/ TEXTURE* features ; /*Returned struct of features*/ /* OMEIS data structures */ omeis* is; pixHeader* head; void* pixels; if (argc != 4) { fprintf(stderr, "\n mb_texture (im, distance, angle),\n\n" "This function returns the 14 image texture statistics described by R. Haralick.\n" "The statistics are calculated from the image's co-occurence matrix specified\n" "for a particular distance and angle. Distance is measured in pixels and\n" "the angle is measured in degrees.\n"); return EXIT_FAILURE; } sscanf(argv[1], "%llu", &ID); sscanf(argv[2], "%d", &distance); sscanf(argv[3], "%d", &angle); is = openConnectionOMEIS ("http://localhost/cgi-bin/omeis","0000"); if (!(head = pixelsInfo (is, ID))){ fprintf (stderr, "PixelsID %llu or OMEIS URL '%s' is probably wrong\n", ID, is->url); return EXIT_FAILURE; } if (!(pixels = getPixels (is, ID))) { fprintf (stderr, "Couldn't get Pixels with ID %llu\n", ID); return 0; } p_gray = (u_int8_t**) OMEIStoCArray (pixels, head, "unsigned char"); if (! (features=Extract_Texture_Features(distance, angle, p_gray, head->dy, head->dx, 255))) { fprintf(stderr, "ERROR: Could not compute Haralick Features.\n"); return EXIT_FAILURE; } printf("%f\n",features->ASM); printf("%f\n",features->contrast); printf("%f\n",features->correlation); printf("%f\n",features->variance); printf("%f\n",features->IDM); printf("%f\n",features->sum_avg); printf("%f\n",features->sum_var); printf("%f\n",features->sum_entropy); printf("%f\n",features->entropy); printf("%f\n",features->diff_var); printf("%f\n",features->diff_entropy); printf("%f\n",features->meas_corr1); printf("%f\n",features->meas_corr2); printf("%f\n",features->max_corr_coef); free(p_gray); free(pixels); free(features); return(EXIT_SUCCESS); }