"""
使用卷积函数对图像感兴趣区域进行标注,实际应用中,可以使用不同的卷积核,对图像
感兴趣区域进行特征的自动提取
卷积运算生成的特征图的大小(特征图的维度)计算
1. 卷积方式padding="VALID"时,输入图片的大小为[h,w],卷积核的大小为[m,n],卷积核的数目为a(特征图的个数,即特征个数),
步长为k,那么,对于每个h*w的图像,假设已经学习得到了a个定义在m*n输入上的特征,那么每一个特征和图片卷积
都会得到一个(h-m+1)*(w-n+1)/k维的卷积特征,由于有a个特征,所以每个图片都会得到(h-m+1)*(w-n+1)/k*a维的卷积特征向量
2. 卷积方式padding="SAME"时,上述表述不变,则每个图片都会得到h*w/k*a维的卷积特征向量
"""
import tensorflow as tf
import cv2
import numpy as np
"""
使用大小为7*7的卷积核对图片进行处理,将提取出边缘特征。试着对lena.jpg图片进行
卷积,观察卷积后的结果
"""
imgPath = "tensorflow_application/lena.jpg"
img = cv2.imread(imgPath)
img = np.array(img, dtype=np.float32)
img_for_origin = img.astype("uint8")
x_image = tf.reshape(img, [1, 512, 512, 3]) # 将图片变为TensorFlow需要的input格式,即4维Tensor
filter = tf.Variable(tf.ones([7, 7, 3, 1]))
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
res = tf.nn.conv2d(x_image, filter, strides=[1, 2, 2, 1], padding="SAME")
# 此时的res为一个4维Tensor,为了将其显示,需要转变为二维数组形式
res_image = sess.run(tf.reshape(res, [256, 256])) / 128 + 1
res_image = res_image.astype("uint8")
# 查看原图和卷积后的图片
cv2.imshow("origin", img_for_origin)
cv2.imshow("cnn", res_image)
sess.close()
# 然后加大卷积核的大小,调整为[11, 11],可以发现随着卷积核的增大,区域特征愈发明显
# 为了练习,再敲一遍代码
imgPath = "tensorflow_application/lena.jpg"
img = cv2.imread(imgPath)
img_float = np.array(img, dtype=np.float32)
# 将img_float变为Tensorflow的input输入格式,4维Tensor
x_image = tf.reshape(img_float, [1, 512, 512, 3])
# 定义卷积核
filter = tf.Variable(tf.ones([11, 11, 3, 1]))
# 启动会话
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)
res = tf.nn.conv2d(x_image, filter, strides=[1, 2, 2, 1], padding="SAME")
# 将结果重塑为可以用于显示的二维数组
res_image = sess.run(tf.reshape(res, [256, 256])) / 128 + 1
# float格式是显示不出来的,需要转变为uint8类型
res_image = res_image.astype("uint8")
# 显示原图和卷积后的图片
cv2.imshow("origin", img)
cv2.imshow("cnn", res_image)
sess.close()