Ask Your Question

Conversion 16bit image to 8 bit image

asked 2019-01-18 04:59:03 -0600

snehal gravatar image

Hello ,

How to convert 16bit image to 8bit image without loosing information.

dst.convertTo(src, CV_8UC1);

I used convertTo() function but it losses information , it is not same as src image.

Is it possible to convert 16 bit image to 8bit image?

edit retag flag offensive close merge delete


Does this help?

dst.convertTo(src, CV_8UC1, 1/256.0);
supra56 gravatar imagesupra56 ( 2019-01-18 05:09:49 -0600 )edit

No still its losses information i tried.

snehal gravatar imagesnehal ( 2019-01-18 05:12:31 -0600 )edit

How about his one?

CvMat* depthMetersMat = cvCreateMat( 480, 640, CV_16UC1 );
cv::Mat m2(depthMetersMat, true);
m2.convertTo(m2, CV_8U);
supra56 gravatar imagesupra56 ( 2019-01-18 05:15:35 -0600 )edit

In my code. I used numpy for python.

img8 = (img16/256).astype('uint8')
supra56 gravatar imagesupra56 ( 2019-01-18 05:18:47 -0600 )edit

@supra56, please, no deprecated c-api attempts here (it's all DEADBEEF)

berak gravatar imageberak ( 2019-01-18 05:19:04 -0600 )edit

@berak. Sorry. I was sitting next to my friend.

supra56 gravatar imagesupra56 ( 2019-01-18 05:22:31 -0600 )edit

In opencv with c++ it is not possible?

snehal gravatar imagesnehal ( 2019-01-18 05:30:51 -0600 )edit

without loosing information.

impossible, irrespective of the language (why did you expect anything else ?). you simply loose half of the bits

berak gravatar imageberak ( 2019-01-18 05:33:11 -0600 )edit

yes correct. but processing on 16 bit image is little bit difficult.

snehal gravatar imagesnehal ( 2019-01-18 05:38:39 -0600 )edit

I think that processing on 16-bit image is not that difficult. What do you want to do exactly?

vps gravatar imagevps ( 2019-01-18 05:43:06 -0600 )edit

1 answer

Sort by ยป oldest newest most voted

answered 2019-01-19 14:32:48 -0600

Tetragramm gravatar image

There are several options, depending on what you mean. All lose information in one way or another.

  1. dst.converTo(src, CV_8U) will keep just the first 256 values, and everything higher becomes 255. Good for when someone just stuck an 8-bit image into 16-bits of memory.
  2. dst.convertTo(src, CV_8U, 1/256.0) divides everything by 256. Good for when someone just scaled all the values into 16-bits, or if someone has done something to the image, like below.
  3. normalize(src, dst, NORM_MINMAX, 0, 255) Takes the lowest value, sets it to 0, the highest to 255, and scales everything else linearly in between. Good if the image is fairly well distributed between min and max.
  4. equalizeHist(src, dst) Takes the image, and spreads it out across the range of values. Then do 2 to make it 8 bits. Only sort of counts as not losing information, as it distorts the image.
  5. CLAHE takes the image, spreads it across the range of values by regions. Good for when one part is brighter than the rest. Only sort of counts as not losing information, as it distorts the image, even more than equalizeHist.
  6. That's pretty much all OpenCV has. You are now in the world of Local Area Contrast Enhancement, which has hundreds if not thousands of methods. Get your google on and find one that works for you.
edit flag offensive delete link more


Thank you so much. I got the concept now.

snehal gravatar imagesnehal ( 2019-01-21 23:26:26 -0600 )edit

The factor is not 1/256 but 1/257 because you map range (0-65535) to (0-255), 65535/255 = 257. This is a common off-by-one error in range mapping.

vbl gravatar imagevbl ( 2019-08-08 03:52:37 -0600 )edit

@vbl is right: 2^16 - 1 = 65535
2^8-1 = 255
65535/255 = 257

VictorLamoine gravatar imageVictorLamoine ( 2020-07-01 03:44:08 -0600 )edit

Question Tools

1 follower


Asked: 2019-01-18 04:59:03 -0600

Seen: 40,304 times

Last updated: Jan 19 '19