我想读取元素图片,并进行像素值拉伸。代码中是直接将像素值乘以5.
for file in os.listdir(data_dir): ###最多读取两级目录找到图片
if os.path.isdir(os.path.join(data_dir,file)):
#print("it's a directory")
if os.path.exists(os.path.join(save_dir,file)):
#os.rmdir(os.path.join(save_dir,file)) #只能删除空目录
shutil.rmtree(os.path.join(save_dir,file)) #空目录、有内容的目录都可以删
os.mkdir(os.path.join(save_dir,file))
else:
os.mkdir(os.path.join(save_dir,file))
for sub_file in os.listdir(os.path.join(data_dir,file)):
if file is not "XLT_ASA01_IIT_L01_STP_20180308184752.png": ####该图片是问题图片
#if sub_file != "XLT_ASA01_IIT_L01_STP_20180308184752.png":
img = cv.imread(os.path.join(os.path.join(data_dir,file),sub_file),2)
print(type(img),img.dtype)
#img = cv2.imread('/home/zhongjia/plasmabubble/scale_test.png',2)
#print(type(img),img.shape,img.dtype)
#plt.figure()
#plt.imshow(img,cmap='Greys_r')
#print(img.max())
print(img.max(),img.min())
print(img[50][50])
img = img*5.0 ### imread输出的uint8变为float64
print(img[50][50],img.shape,img.max(),img.min(),img.dtype)
#img = np.array(img,dtype='uint16')
#print(img[50][50],img.shape,img.max(),img.min(),img.dtype)
### medianBlur(InputArray src, OutputArray dst, int ksize),
#InputArray src: 输入图像,图像为1、3、4通道的图像,当模板尺寸为3或5时,图像深度只能为CV_8U、CV_16U、CV_32F中的一个
#img = (img-img.min())*(255/(img.max()-img.min()))
#print(img[50][50])
#print(type(img),img.dtype)
cv.imwrite(os.path.join(os.path.join(save_dir,file),'pad_'+sub_file),img)
img = cv.imread(os.path.join(os.path.join(save_dir,file),'pad_'+sub_file))
print(img.max(),img.min(),img.dtype,img.shape)
print(img[50][50])
img = np.array(img,dtype='uint8')
print(img[50][50])
img_lvbo = cv.medianBlur(img, 5)
print(img.max(),img.min())
#print(img.max())
cv.imwrite(os.path.join(os.path.join(save_dir,file),'lvbo_'+sub_file),img_lvbo)
输出结果:
可以看到原图最大最小值127,6 ,uint8
乘以5后变为最大最小值635,30 ,float64, 第50行50列元素50
经过imwrite和imread后,最大值255,最小值不变,第50行50列元素50不变,通道由1变为3,float64变为uint8.
修改代码img*1.0:
for sub_file in os.listdir(os.path.join(data_dir,file)):
if file is not "XLT_ASA01_IIT_L01_STP_20180308184752.png": ####该图片是问题图片
#if sub_file != "XLT_ASA01_IIT_L01_STP_20180308184752.png":
img = cv.imread(os.path.join(os.path.join(data_dir,file),sub_file),2)
print(type(img),img.dtype)
#img = cv2.imread('/home/zhongjia/plasmabubble/scale_test.png',2)
#print(type(img),img.shape,img.dtype)
#plt.figure()
#plt.imshow(img,cmap='Greys_r')
#print(img.max())
print(img.max(),img.min())
print(img[50][50])
img = img*1.0 ### imread输出的uint8变为float64
print(img[50][50],img.shape,img.max(),img.min(),img.dtype)
#img = np.array(img,dtype='uint16')
#print(img[50][50],img.shape,img.max(),img.min(),img.dtype)
### medianBlur(InputArray src, OutputArray dst, int ksize),
#InputArray src: 输入图像,图像为1、3、4通道的图像,当模板尺寸为3或5时,图像深度只能为CV_8U、CV_16U、CV_32F中的一个
#img = (img-img.min())*(255/(img.max()-img.min()))
#print(img[50][50])
#print(type(img),img.dtype)
cv.imwrite(os.path.join(os.path.join(save_dir,file),'pad_'+sub_file),img)
img = cv.imread(os.path.join(os.path.join(save_dir,file),'pad_'+sub_file))
print(img.max(),img.min(),img.dtype,img.shape)
print(img[50][50])
img = np.array(img,dtype='uint8')
print(img[50][50])
img_lvbo = cv.medianBlur(img, 5)
print(img.max(),img.min())
#print(img.max())
cv.imwrite(os.path.join(os.path.join(save_dir,file),'lvbo_'+sub_file),img_lvbo)
输出结果:
可以看到imwrite和imread没有改变像素值,仅仅有uint8变为float64.
从结果看,那么只有超过255的值会发生像素变化,究竟是imwrite引起的还是imread函数引起的。
参考https://blog.csdn.net/oukohou/article/details/82378552,说是报错的图像格式引起的。
但是我这里读取和保存的都是png格式,不应该是格式问题。
而当我仅仅改变读取像素值为uint16时,
for sub_file in os.listdir(os.path.join(data_dir,file)):
if file is not "XLT_ASA01_IIT_L01_STP_20180308184752.png": ####该图片是问题图片
#if sub_file != "XLT_ASA01_IIT_L01_STP_20180308184752.png":
img = cv.imread(os.path.join(os.path.join(data_dir,file),sub_file),2)
print(type(img),img.dtype)
#img = cv2.imread('/home/zhongjia/plasmabubble/scale_test.png',2)
#print(type(img),img.shape,img.dtype)
#plt.figure()
#plt.imshow(img,cmap='Greys_r')
#print(img.max())
print(img.max(),img.min())
print(img[50][50])
img = img*1.0 ### imread输出的uint8变为float64
print(img[50][50],img.shape,img.max(),img.min(),img.dtype)
img = np.array(img,dtype='uint16')
#print(img[50][50],img.shape,img.max(),img.min(),img.dtype)
### medianBlur(InputArray src, OutputArray dst, int ksize),
#InputArray src: 输入图像,图像为1、3、4通道的图像,当模板尺寸为3或5时,图像深度只能为CV_8U、CV_16U、CV_32F中的一个
#img = (img-img.min())*(255/(img.max()-img.min()))
#print(img[50][50])
#print(type(img),img.dtype)
cv.imwrite(os.path.join(os.path.join(save_dir,file),'pad_'+sub_file),img)
img = cv.imread(os.path.join(os.path.join(save_dir,file),'pad_'+sub_file))
print(img.max(),img.min(),img.dtype,img.shape)
print(img[50][50])
img = np.array(img,dtype='uint8')
print(img[50][50])
img_lvbo = cv.medianBlur(img, 5)
print(img.max(),img.min())
#print(img.max())
cv.imwrite(os.path.join(os.path.join(save_dir,file),'lvbo_'+sub_file),img_lvbo)
最大值最小值结果就发生了变化。
所以应该是矩阵在存为图像或者读取时,数据类型引起的错误。可见imwrite或者imread不能自动将数据线性压缩到0-255,而是会发生截断,大于255的值赋值为255.
通过查看imread函数API:
imread()参数说明 2 cv2.IMREAD_UNCHANGED = -1, //返回原通道原深度图像 3 cv2.IMREAD_GRAYSCALE = 0, //返回单通道(灰度),8位图像 4 cv2.IMREAD_COLOR = 1, //返回三通道,8位图像,为默认参数 5 cv2.IMREAD_ANYDEPTH = 2, //返回单通道图像。如果原图像深度为16/32 位,则返回原深度,否则转换为8位 6 cv2.IMREAD_ANYCOLOR = 4, //返回原通道,8位图像。
读取原始位深图是imread参数设置为2
修改代码:
for sub_file in os.listdir(os.path.join(data_dir,file)):
if file is not "XLT_ASA01_IIT_L01_STP_20180308184752.png": ####该图片是问题图片
#if sub_file != "XLT_ASA01_IIT_L01_STP_20180308184752.png":
img = cv.imread(os.path.join(os.path.join(data_dir,file),sub_file),2)
print(type(img),img.dtype)
#img = cv2.imread('/home/zhongjia/plasmabubble/scale_test.png',2)
#print(type(img),img.shape,img.dtype)
#plt.figure()
#plt.imshow(img,cmap='Greys_r')
#print(img.max())
print(img.max(),img.min())
print(img[50][50])
img = img*5.0 ### imread输出的uint8变为float64
print(img[50][50],img.shape,img.max(),img.min(),img.dtype)
#img = np.array(img,dtype='uint16')
#print(img[50][50],img.shape,img.max(),img.min(),img.dtype)
### medianBlur(InputArray src, OutputArray dst, int ksize),
#InputArray src: 输入图像,图像为1、3、4通道的图像,当模板尺寸为3或5时,图像深度只能为CV_8U、CV_16U、CV_32F中的一个
#img = (img-img.min())*(255/(img.max()-img.min()))
#print(img[50][50])
#print(type(img),img.dtype)
cv.imwrite(os.path.join(os.path.join(save_dir,file),'pad_'+sub_file),img)
img = cv.imread(os.path.join(os.path.join(save_dir,file),'pad_'+sub_file),2)
print(img.max(),img.min(),img.dtype,img.shape)
print(img[50][50])
img = np.array(img,dtype='uint8')
print(img[50][50])
img_lvbo = cv.medianBlur(img, 5)
print(img.max(),img.min())
#print(img.max())
cv.imwrite(os.path.join(os.path.join(save_dir,file),'lvbo_'+sub_file),img_lvbo)
imread读取原始位uint8,所以float64的矩阵通过imwrite函数存储是发生了改变。