Use:

integer_array = (img5.astype(np.float32)/255.0*65535.0-32768.0).astype(np.int16)

That will scale properly your 0,255 range (uint8) to the -32768,32767 (int16) range.

Answer from Toyo on Stack Overflow
🌐
Reddit
reddit.com › r/learnpython › declaring an unsigned integer 16 in python for bit shift operation
r/learnpython on Reddit: Declaring an Unsigned Integer 16 in Python for Bit Shift Operation
October 29, 2023 -

SOLVED: 3 Solutions:

  1. using Numpy : np.uint16()

  2. Using CTypes : ctypes.c_uint16()

  3. Using Bitwise : & 0xFFFF


Hi, I'm trying to convert this code to Python from Go / C. It involves declaring a UInt16 variable and run a bit shift operation. However cant seem to create a variable with this specific type. Need some advise here.

Go Code:

package main

import "fmt"

func main() {

var dx uint16 = 38629

var dy uint16 = dx << 8

fmt.Println(dy) //58624 -> Correct value

}

Python Code:

dx = 38629

dy = (dx << 8)

print(dy) # 9889024 -> not the expected value

print(type(dx)) # <class 'int'>

print(type(dy)) # <class 'int'>

I cant seem to figure out a way to cast or similar function to get this into an Unsigned Int 16.\

Please help.

Discussions

Newest 'uint16' Questions - Stack Overflow
I am creating a python OPC UA client based on opcua-asyncio github (https://github.com/FreeOpcUa/opcua-asyncio) to read values in an instrument that has a server already set up. My problem lies in ... ... I am trying to register two 16bit images. One is a .dcm CT series and the other is TIFF image. Both are uint16 ... More on stackoverflow.com
🌐 stackoverflow.com
overflow - Converting float64 array to uint16 (Python) - Stack Overflow
I'm having trouble in a data type conversion from float64 to uint16. If I have an array of floats and I try to convert it with array_uint16 = array_float64.astype(np.uint16) is there a sort of &q... More on stackoverflow.com
🌐 stackoverflow.com
python - numpy array convert uin8 lsb to uint16 msb - Stack Overflow
I already asked here but I just wonder if this could not be done natively with numpy because I will use numpy later anyway with cv2 that reads numpy arrays. Background is, I read 13 chunks of 13680 More on stackoverflow.com
🌐 stackoverflow.com
python - Conversion of image type int16 to uint8 - Stack Overflow
I have an image with data type int16. So when I have to convert its range to 0-255, I got two ways to do that in Python. 1) Use numpy.uint8 function directly 2) Use OpenCV cv2.normalize function ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Stack Overflow
stackoverflow.com › questions › tagged › uint16
Newest 'uint16' Questions - Stack Overflow
I'm having trouble in a data type conversion from float64 to uint16. If I have an array of floats and I try to convert it with array_uint16 = array_float64.astype(np.uint16) is there a sort of "...
Top answer
1 of 2
19

All of these do different things.

np.uint8 considers only the lowest byte of your number. It's like doing value & 0xff.

>>> img = np.array([2000, -150, 11], dtype=np.int16)
>>> np.uint8(img)
array([208, 106,  11], dtype=uint8)

cv2.normalize with the cv2.NORM_MINMAX norm type normalises your values according to the normalisation function

img_new = (img - img.min()) * ((max_new - min_new) / (img.max() - img.min())) + min_new

It effectively changes one range to another and all the values in the between are scaled accordingly. By definition the original min/max values become the targetted min/max values.

>>> cv2.normalize(img, out, 0, 255, cv2.NORM_MINMAX)
array([255,   0,  19], dtype=int16)

uint8 in Matlab simply saturates your values. Everything above 255 becomes 255 and everything below 0 becomes 0.

>> uint8([2000 -150 11])

ans =

  255    0   11

If you want to replicate Matlab's functionality, you can do

>>> img[img > 255] = 255
>>> img[img < 0] = 0

Which one you want to use depends on what you're trying to do. If your int16 covers the range of your pixel values and you want to rescale those to uint8, then cv2.normalize is the answer.

2 of 2
2

the simply way to convert data format is to use the following formula. In this case it is possible to convert any array to a new custom format.

# In the case of image, or matrix/array conversion to the uint8 [0, 255] 
# range

Import numpy as np

new_data = (newd_ata - np.min(new_data)) * ((255 - 0) / (np.max(new_data) - 
np.new_data))) + 0
Find elsewhere
🌐
GitHub
github.com › pandas-dev › pandas › issues › 47294
BUG: uint16 inserted as int16 when assigning row with dict · Issue #47294 · pandas-dev/pandas
June 9, 2022 - Inserting a row with a dict, uint16 values are converted to int16 and the value conversion does not preserve the correct value. This also happens when assigning into an existing object-typed column (the conversion sequence seems to be -> int16 -> int in that case). It's expected the dtype is preserved - uint16 if possible, or an int which is large enough to represent the value. python ...
Author: pandas-dev
🌐
Stack Overflow
stackoverflow.com › questions › 72563282 › how-to-use-c-sharp-uint16-in-python
.net - How to use C# UInt16[,] in python - Stack Overflow
I can do the conversion only by looping on the matrix, reading each element and assigning its value to the respective position in another numpy matrix, but this solution is very slow. Is there a faster conversion method which can utilize numpy vectorization ? ... import clr import os import numpy as np dll_name = os.path.join(os.path.abspath(os.path.dirname(__file__)), ("mydll") + ".dll") clr.AddReference(dll_name) from mynamespace import myclass myobject = myclass() numpy_matrix = np.empty([80,260],dtype = np.uint16) SystemInt16_matrix = myobject.Getdata() for i in range(20): for j in range(32): numpy_matrix[i,j]=SystemInt16_matrix[i,j]
Top answer
1 of 1
4

Your data corruption is caused by integer overflow.

Once a numpy integer goes outside the range of a datatype (0-255 for uint8), the value overflows and wraps around to 0 again.

For example:

np.uint16(255).astype(np.uint8) == 255
np.uint16(256).astype(np.uint8) == 0
np.uint16(258).astype(np.uint8) == 2
np.uint16(260).astype(np.uint8) == 4
np.uint16(511).astype(np.uint8) == 255
np.uint16(512).astype(np.uint8) == 0
np.uint16(514).astype(np.uint8) == 2
np.uint16(516).astype(np.uint8) == 4

A simple rescale will work, e.g.

data_8bit = ((data - data.min()) / (data.max() - data.min()) * 255).astype(np.uint8)

But you'll get a much nicer looking image if you rescale per band and even better with a per band percentile stretch similar to what most GIS software does, such as [2, 98] or [1, 99]. E.g.

import rasterio
import numpy as np

input_tiff = "test_uint16.tif"
output_tiff = "test_uint8.tif"

percentiles = [1, 99]

with rasterio.open(input_tiff) as src:
    profile = src.profile
    profile.update(dtype=rasterio.uint8)

    with rasterio.open(output_tiff, 'w', **profile) as dst:
        for i in range(src.count):
            band = i+1
            data = src.read(band, masked=True)

            # data.compressed() returns an array of non-masked pixel values
            pmin, pmax = np.percentile(data.compressed(), percentiles)

            # rescale 0-1
            data = (data - pmin) / (pmax - pmin)

            # Ensure data is >= pmin <= pmax
            data[data<0] = 0
            data[data>1] = 1

            # Make it 0-255 8bit unsigned.
            data_int8 = (data * 255).astype(np.uint8)

            dst.write(data_int8, band)
🌐
Reddit
reddit.com › r/python › numpy : why cant numpy cast uint in int
r/Python on Reddit: Numpy : why cant numpy cast uint in int
June 1, 2015 -

It seems that numpy cannot "safely" cast uint into int while using union1d operation. Is there a particular reason why? While i understand why you cannot cast float to int in a safe way, or int to uint, the reason for not being able to cast from uint to int is nebulous to me.

a = np.array([0,1,2,3],dtype='uint')
b = np.array([4,5,6],dtype='int')
c = np.union1d(a,b)
print(c.dtype)

The above example prints float64. Also, the following line returns False :

np.can_cast('uint','int')

The next example can cast without trouble :

np.array(np.array([0,1,2],dtype='uint'),dtype='int')
🌐
Readthedocs
iec104-python.readthedocs.io › latest › python › number › uint16.html
Usigned Integer (16-bit) — iec104-python 2.2 documentation
c104 python module · Number · Usigned Integer (16-bit) View page source · class c104.UInt16 · __init__(self, value: int) → None · create a fixed-length integer instance · Parameters: value (int) – the value · Raises: ValueError – cannot convert value to fixed-length integer ·
🌐
PyTorch Forums
discuss.pytorch.org › vision
Doubt with torch.from_numpy with uint16 and how to_tensor manage these kinds of images - vision - PyTorch Forums
June 22, 2020 - Hi, I have a doubt related to the function torch.from_numpy. I’m trying to convert a numpy array that contains uint16 and I’m getting the following error: TypeError: can’t convert np.ndarray of type numpy.uint16. The only supported types are: float64, float32, float16, int64, int32, int16, ...