第一种: 将16位转换位8位的时候还保留住原来的像素值,这种只改变位数而不改变具体数值,但是超过255大小的像素会转为255,故会造成信息丢失,不推荐该方法;
#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
#include <stdio.h>
using namespace std;
using namespace cv;
int main(void) {
char buff1[100];
char buff2[100];
Mat src;
//Mat dst;
src = imread("C:\\Users\\Administrator\\Desktop\\unet_2\\traindata\\case01010046_Orignal_19.png", CV_LOAD_IMAGE_UNCHANGED);
Mat ff = Mat::zeros(src.rows, src.cols, CV_8UC1);
for (int k = 0; k<src.rows; k++) {
for (int kk = 0; kk<src.cols; kk++) {
int n = src.at<ushort>(k, kk);
ff.at<uchar>(k, kk) = n;
}
}
//src.copyTo(dst);
imshow("haha",ff);
//waitKey(0);
//imwrite("c", ff);
waitKey(0);
return 0;
}
第二种,先把16位的图像归一化,然后*255转成8位,这一种类最为常用,而且可视化效果好,推荐该方法;
一张16位图片保存为8位如下,(切记如果用opencv读取16位,flag字段为cv2.IMREAD_ANYDEPTH)
# -*- coding:utf8 -*-
import os
import re
import shutil
import cv2
import numpy as np
from PIL import Image
def norm_img(img):
max_v = img.max()
min_v = img.min()
img = (img - min_v) / (max_v - min_v)
return img*255
file1=r".\1false_8"
if not os.path.exists(file1):
os.makedirs(file1)
path1=r".\1false_16"
list_path=os.listdir(path1)
for i in range(len(list_path)):
dicom_paths=os.path.join(path1,list_path[i])
img_copy=cv2.imread(dicom_paths,cv2.IMREAD_ANYDEPTH)
img_copy=norm_img(img_copy)
prefix=str(i).zfill(5)+'.png'
cv2.imwrite(os.path.join(file1,prefix),img_copy)
可以显示
如果想保存16位的png图,最好用PIL库保存,不要用opencv!
参考链接:https://blog.csdn.net/u011764992/article/details/84501300
另外通常使用opencv读取16位并保存16位的图像有几点需要注意!
opencv使用imread读取16位图像时需要增加参数:cv2.IMREAD_UNCHANGED
这样才是读取原数据,其通道数才不会改变
image1=cv2.imread(os.path.join(img,imgs[i]),cv2.IMREAD_UNCHANGED)
opencv保存16位图像时候必须转化为该数据类型并保存为PNG等格式才行:
具体参考:http://www.sohu.com/a/318613851_823210