图像预处理
粗略记录一下,用于处理计算机视觉的图像处理代码(不涉及理论)
后续也会持续更新……
1. opencv 读取图片
import cv2 as cv # 导入open cv
# 读取图片路径
img = cv.imread("/home/tlooh/下载/Data/tmp/1",cv.IMREAD_GRAYSCALE)
# 显示图片,picture为显示窗口的title,第二个img为图片路径
cv.imshow("picture",img)
# 参数=0: (也可以是小于0的数值)一直显示,不会有返回值
# 若在键盘上按下一个键即会消失 ,则会返回一个按键对应的ascii码值
# 参数>0:显示多少毫秒 超过这个指定时间则返回-1
cv.waitKey(1000)
# 摧毁所有窗口
cv.destroyAllWindows()
cv.IMREAD_GRAYSCALE
这个参数应该是灰度化,更多的的灰度处理方式可以看这里:参考博客
2. 直方图均衡化
很详细的一篇参考博客:OpenCV计算机视觉学习(9)——图像直方图 & 直方图均衡化
import cv2 as cv
# 读取图像,并灰度化
img = cv.imread("/home/tlooh/下载/Data/tmp/1",cv.IMREAD_GRAYSCALE)
# 调用函数cv.calcHist() 绘制直方图
img_hist = cv.calcHist([img],[0],None,[256],[0,256])
# 调用函数 cv.equalizeHist() 实现直方图均衡化
result_img = cv.equalizeHist(img)
# 显示两幅图像对比
cv.imshow('before',img)
cv.imshow('after',result_img)
cv.waitKey(5000)
cv.destroyAllWindows()
# 使用matplotlib进行直方图绘制
import matplotlib.pyplot as plt
# 前后两副直方图对比
plt.hist(img.ravel(),256)
plt.show()
plt.hist(result_img.ravel(),256)
plt.show()
关于cv.calcHist() 函数参数意义:
运行效果(效果其实挺明显的):
直方图对比,可以看到原来灰度值频率很低的地方得到了填充,也就是所谓的均衡化;
想要追求效果明显的化,可以找一下局部过曝,或者亮度不均匀的图片进行测试,效果会更加明细。
3. 双线性插值
tf.gfile.FastGFile(path,decodestyle)
函数功能:实现对图片的读取。
函数参数: (1)path:图片所在路径
(2)decodestyle:图片的解码方式。(‘r’:UTF-8编码; ‘rb’:非UTF-8编码)
# 附上代码
# 图像大小调整
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import cv2 as cv
tf.compat.v1.disable_eager_execution()
imgpath2 = "/home/tlooh/下载/Data/tmp/2.jpeg"
def resize_img(imgpath,target_size):
img_raw_data = tf.io.gfile.GFile(imgpath2,'rb').read()
with tf.compat.v1.Session() as sess:
# 将图像使用JPEG的格式解码从而得到图像对应的三维矩阵
# TensorFlow提供了 tf.image.decode_png 函数对png格式的图像进行解码
# 解码之后的结果为一个张量,在使用它的取值之前需要明确调用运行的过程
img_data = tf.image.decode_jpeg(img_raw_data)
# img_data.set_shape([600,600,3])
# print(img_data.shape.as_list())
# 通过tf.image.resize_images函数调整图像的大小
# 这个函数第一个参数为原始图像,第二个和第三个参数为调整后图像的大小
# antialias 参数给出了调整图像大小的算法
resized = tf.image.resize(img_data, target_size, antialias=True)
# 输出调整后图像的大小,此处的结果为(300, 300, ?)表示图像的大小为300*300
# 但是在图像的深度还没有明确设置之前会是问号
# TensorFlow的函数处理图片后存储的数据是float32格式的,
# 需要转换成uint8才能正确打印图片。
resized_photo = np.asarray(resized.eval(), dtype='uint8')
plt.imshow(resized_photo)
plt.show()
# 通道转换
resized_photo = cv.cvtColor(resized_photo,cv.COLOR_BGR2RGB)
img_show("resized",resized_photo)
resize_img(imgpath2,[600,600])
(1) 报错 AttributeError: module ‘tensorflow’ has no attribute ‘gfile’
原因与解决方案
然后百度,发现是说问题产生的原因:在当前的版本中,gfile已经定义在io包的file_io.py中。
img_raw_data = tf.gfile.FastGFile(imgpath2,'rb').read()
于是改为
img_raw_data = tf.io.gfile.FastGFile(imgpath2,'rb').read()
仍然报错
然后查阅官方文档才发现,调用形式发生变化,这里附上官方文档地址:TensorFlow-Python 文档
img_raw_data = tf.io.gfile.GFile(imgpath2,'rb').read()
至此,问题解决
(2) 报错 AttributeError: module ‘tensorflow._api.v2.image’ has no attribute ‘resize_images’
原因应该如先前一样,版本高了,函数发生了变化:
代码如下,问题解决!
# 双线性插值
resized = tf.image.resize(img_data, target_size, antialias='bilinear')
(3) plt.imshow() 和 cv.imshow() 展示的图片不一样?
问题如下,img_show() 是我自己封装的cv展示函数
原理很简单:
opencv的是按照B、G、R 三个通道读取图片;
matplotlib.pyplot 则是R、G、B模式,也就是说opencv有点特别
所以我们需要用函数 cv.cvtColor( xxx , cv.COLOR_BGR2RGB) # CV BGR转变RGB
plt.imshow(resized_photo)
plt.show()
# 通道转换
resized_photo = cv.cvtColor(resized_photo,cv.COLOR_BGR2RGB)
img_show(resized_photo)