图像预处理

本文介绍了使用OpenCV进行图像预处理的常见步骤,包括读取图片、直方图均衡化以及双线性插值。在直方图均衡化部分,通过调用`cv.calcHist`和`cv.equalizeHist`函数改善图像的灰度分布。在双线性插值部分,由于TensorFlow API的更新,需要使用`tf.image.resize`替代旧的`resize_images`函数。同时,注意`tf.gfile`已被移至`tf.io.gfile`。最后,指出了`plt.imshow`与`cv.imshow`显示图像差异的原因在于颜色通道顺序不同。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

粗略记录一下,用于处理计算机视觉的图像处理代码(不涉及理论)
后续也会持续更新……

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()

image

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() 函数参数意义:

image

运行效果(效果其实挺明显的):

image

直方图对比,可以看到原来灰度值频率很低的地方得到了填充,也就是所谓的均衡化;

想要追求效果明显的化,可以找一下局部过曝,或者亮度不均匀的图片进行测试,效果会更加明细。

image

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’

image

原因与解决方案

然后百度,发现是说问题产生的原因:在当前的版本中,gfile已经定义在io包的file_io.py中。

img_raw_data = tf.gfile.FastGFile(imgpath2,'rb').read()

于是改为

    img_raw_data = tf.io.gfile.FastGFile(imgpath2,'rb').read()

仍然报错

image

然后查阅官方文档才发现,调用形式发生变化,这里附上官方文档地址:TensorFlow-Python 文档

image

img_raw_data = tf.io.gfile.GFile(imgpath2,'rb').read()

至此,问题解决

(2) 报错 AttributeError: module ‘tensorflow._api.v2.image’ has no attribute ‘resize_images’

image

原因应该如先前一样,版本高了,函数发生了变化:

image

代码如下,问题解决!

# 双线性插值    
resized = tf.image.resize(img_data, target_size, antialias='bilinear')
(3) plt.imshow() 和 cv.imshow() 展示的图片不一样?

问题如下,img_show() 是我自己封装的cv展示函数

image

image

原理很简单:

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)
        

image

问题解决!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值