How to convert /map uint16 to int16 maintaining the dynamic range so that [0] and [2^16-1] in uint16 beomes [-2^15] and [2^15-1] without going through double

25 vues (au cours des 30 derniers jours)
I would like to convert my uint16 values to int16 values amd maintain the dynamic range. All my attempts with typecast and cast still map value 0 (uint16) to 0 (int16). I would like it to map 0 (uint16) directly to -2^15 (int16). I need to convert a rather large dataset so I would like to circumvent doing to double or single if I can.
The data comes from fread and if I can do the mapping there directly then that would be even better. This is what I use now to read the data:
Data = fread(fid,[m n],'uint16=>uint16')';
Ive tried asking for 'uint16=>int16', but that also cuts the data
  1 commentaire
Micke Malmström
Micke Malmström le 2 Fév 2024
Modifié(e) : Micke Malmström le 2 Fév 2024
% Example uint16 data
uint16Data = uint16([0, 2^16-1]);
% Map uint16 to int16
int16Data = int16(uint16Data - 2^15); % here is where the problem lies and I cant figure out how to circumvent going through double or single...
% Display the results
disp(['Original uint16 data: ', num2str(uint16Data)]);
Original uint16 data: 0 65535
disp(['Mapped int16 data: ', num2str(int16Data)]); % my desired result here is Mapped int16 data: -32768 32767
Mapped int16 data: 0 32767

Connectez-vous pour commenter.

Réponse acceptée

Stephen23
Stephen23 le 2 Fév 2024
Modifié(e) : Stephen23 le 2 Fév 2024
inp = uint16([-Inf,pi,Inf])
inp = 1×3
0 3 65535
Method one: use INT32 for the intermediate values:
off = int32(intmin('int16'));
out = int16(int32(inp)+off)
out = 1×3
-32768 -32765 32767
Method two: convert from two's complement to offset binary, which you can then simply TYPECAST into INT16:
out = typecast(bitset(inp,16,1-bitget(inp,16)),'int16')
out = 1×3
-32768 -32765 32767

Plus de réponses (1)

Bruno Luong
Bruno Luong le 3 Fév 2024
Modifié(e) : Bruno Luong le 3 Fév 2024
If you have C compiler this simple mex file will do the job:
/**************************************************************************
* Matlab Mex file castint16.C
Convert uint16 to int16 by adding 2^15 in 2-complement binary coding
Example:
a = uint16([0 2^16-1])
b = castint16(a)
will return
1×2 int16 row vector
-32768 32767
Compile:
mex -R2018a castint16.c
*************************************************************************/
#include "mex.h"
#include "matrix.h"
#define A prhs[0]
#define B plhs[0]
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]) {
size_t i, n;
mxUint16 *a, *b;
if (nrhs!=1)
mexErrMsgTxt("castint16 missing input argument");
/* n = numel(A) */
n = mxGetNumberOfElements(A);
if (mxGetClassID(A) == mxUINT16_CLASS) {
a = mxGetUint16s (A);
B = mxCreateNumericMatrix(mxGetM(A), mxGetN(A), mxINT16_CLASS, mxREAL);
b = mxGetInt16s(B);
for (i = 0; i < n; i++)
b[i] = a[i] + 0x8000;
} else
mexErrMsgTxt("castint16 suports only UINT16 input");
}

Catégories

En savoir plus sur Cell Arrays dans Help Center et File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by