📄 imhistc.c
字号:
/* Copyright 1993-1998 The MathWorks, Inc. All Rights Reserved. */
/* $Revision: 5.7 $ $Date: 1997/11/24 15:56:56 $ */
static char rcsid[] = "$Id: imhistc.c,v 5.7 1997/11/24 15:56:56 eddins Exp $";
/*
* imhistc.c
*
* Y = IMHISTC( A, N, ISSCALED, TOP ) makes an N bin histogram of
* the image matrix A. This function is written as an auxiliary to
* the M-file IMHIST.M.
*
* This is a MEX file for MATLAB.
*
*/
#include <math.h>
#include "mex.h"
static int flopsCount;
void ScaledHistDouble(double *a,
double top,
int n,
int length,
double *y);
void HistDouble(double *a,
int n,
int length,
double *y);
void HistUint8(uint8_T *a,
int n,
int length,
double *y);
void ScaledHistUint8(uint8_T *a,
double top,
int n,
int length,
double *y);
void ValidateInputs(int nlhs,
const mxArray *prhs[],
int nrhs,
const mxArray **A,
int *n,
bool *isScaled,
double *top);
void ScaledHistDouble(double *a,
double top,
int n,
int length,
double *y) {
int i;
double scale;
double z;
scale = (double) (n-1) / top;
for (i = 0; i < length; i++) {
z = floor(a[i] * scale + .5);
if (z < 0.0) {
y[0]++;
} else if (z > (n-1)) {
y[n-1]++;
} else {
y[(int) z]++;
}
}
flopsCount += 3*length; /* 1 multiply, 1 add, 1 floor() per element */
}
void HistDouble(double *a,
int n,
int length,
double *y) {
int i;
int idx;
int warnFlag = 0;
for (i = 0; i < length; i++) {
idx = a[i] - 1;
if (idx < 0) {
warnFlag = 1;
y[0]++;
} else if (idx >= n) {
warnFlag = 1;
y[n-1]++;
} else {
y[idx]++;
}
}
if (warnFlag == 1)
{
mexWarnMsgTxt("Input has out-of-range values");
}
/* no flops in this function */
}
void HistUint8(uint8_T *a,
int n,
int length,
double *y) {
int i;
int idx;
int warnFlag = 0;
for (i = 0; i < length; i++) {
idx = a[i];
if (idx < 0) {
warnFlag = 1;
y[0]++;
} else if (idx > (n-1)) {
warnFlag = 1;
y[n-1]++;
} else {
y[idx]++;
}
}
if (warnFlag == 1)
{
mexWarnMsgTxt("Input has out-of-range values");
}
/* no flops in this function */
}
void ScaledHistUint8(uint8_T *a,
double top,
int n,
int length,
double *y) {
int i;
double scale;
double z;
scale = (double) (n-1) / top;
for (i = 0; i < length; i++) {
z = floor(a[i] * scale + 0.5);
if (z < 0.0) {
y[0]++;
} else if (z > (n-1)) {
y[n-1]++;
} else {
y[(int) z]++;
}
}
flopsCount += 3*length; /* 1 multiply, 1 add, 1 floor() per element */
}
void mexFunction(int nlhs,
mxArray *plhs[],
int nrhs,
const mxArray *prhs[])
{
int i;
int length;
const mxArray *A;
int n;
bool isScaled;
double top;
double *a_real;
uint8_T *a_int;
double *y;
mxArray *Y;
ValidateInputs(nlhs, prhs, nrhs, &A, &n, &isScaled, &top);
length = mxGetM(A) * mxGetN(A);
flopsCount = 0;
Y = mxCreateDoubleMatrix(n, 1, mxREAL);
y = (double *) mxGetPr(Y);
if (mxIsDouble(A)) {
a_real = (double *) mxGetPr(A);
if (isScaled) {
ScaledHistDouble(a_real, top, n, length, y);
} else {
HistDouble(a_real, n, length, y);
}
} else {
a_int = (uint8_T *) mxGetPr(A);
if (isScaled) {
if ((n == 256) && (top == 255.0)) {
HistUint8(a_int, n, length, y);
} else {
ScaledHistUint8(a_int, top, n, length, y);
}
} else {
HistUint8(a_int, n, length, y);
}
}
/* Done! Give the answer back */
plhs[0] = Y;
mexAddFlops(flopsCount);
}
void ValidateInputs(int nlhs,
const mxArray *prhs[],
int nrhs,
const mxArray **A,
int *n,
bool *isScaled,
double *top)
{
int i;
int length;
double n_real;
double isScaled_real;
if (nrhs != 4) {
mexErrMsgTxt("IMHISTC requires 4 input arguments");
}
for (i = 0; i < nrhs; i++) {
if (mxIsComplex(prhs[i])) {
mexWarnMsgTxt("Ignoring imaginary part of complex inputs");
}
if (!mxIsNumeric(prhs[i])) {
mexErrMsgTxt("Inputs to IMHISTC must be numeric");
}
}
if (!mxIsDouble(prhs[0]) && !mxIsUint8(prhs[0])) {
mexErrMsgTxt("First input to IMHISTC must be DOUBLE or UINT8");
}
*A = prhs[0];
for (i = 1; i < nrhs; i++) {
if (!mxIsDouble(prhs[i])) {
mexErrMsgTxt("IMHISTC inputs 2, 3, and 4 must be DOUBLE");
}
}
length = mxGetM(prhs[1]) * mxGetN(prhs[1]);
if (length == 0) {
mexErrMsgTxt("Second input to IMHISTC must not be empty");
} else if (length == 1) {
n_real = *((double *) mxGetPr(prhs[1]));
} else {
mexWarnMsgTxt("Second input to IMHISTC should be a scalar");
n_real = *((double *) mxGetPr(prhs[1]));
}
*n = (int) n_real;
if (((double) *n) != n_real) {
mexWarnMsgTxt("Second input to IMHISTC should be an integer");
}
if (*n <= 0) {
mexErrMsgTxt("Second input to IMHISTC should be positive");
}
length = mxGetM(prhs[2]) * mxGetN(prhs[2]);
if (length == 0) {
mexErrMsgTxt("Third input to IMHISTC must not be empty");
} else if (length == 1) {
isScaled_real = *((double *) mxGetPr(prhs[2]));
} else {
mexWarnMsgTxt("Third input to IMHISTC should be a scalar");
isScaled_real = *((double *) mxGetPr(prhs[2]));
}
if (isScaled_real != 0.0) {
*isScaled = true;
} else {
*isScaled = false;
}
length = mxGetM(prhs[3]) * mxGetN(prhs[3]);
if (length == 0) {
mexErrMsgTxt("Fourth input to IMHISTC must not be empty");
} else if (length == 1) {
*top = *((double *) mxGetPr(prhs[3]));
} else {
mexWarnMsgTxt("Fourth input to IMHISTC should be a scalar");
*top = *((double *) mxGetPr(prhs[3]));
}
if (*top <= 0.0) {
mexErrMsgTxt("Fourth input to IMHISTC must be positive");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -