本次内容中包含了图片的读取和写入,以及“图片融合”、‘图片拼接’、‘图片的灰度直方图展示’
使用深度为8位24位的格式为bmp的图片,存放在“file”文件夹,实现位数为8和24的BMP图像读取和存储,并绘制其对应的灰度直方图。
# 标准库,用于数据计算和处理
import numpy as np
# 可视化模块,用于绘制可视化图像
import matplotlib.pyplot as plt
# 第三方库
import matplotlib
# 标准库,用于文件和目录操作
import os
# struct模块用于解析字节数据,unpack库用于将字节流转换成python数据类型,返回值为元组
from struct import unpack
from PIL import Image # 用于读取图像
import cv2 # 用于读取图像
# 读取24位BMP
im_24 = Image.open('./file/24bits.bmp')
#显示图像
plt.imshow(im_24)
#以jpg格式进行存储
im_24.save('im_24.jpg')
# 读取8位BMP
im_8 = cv2.imread('./file/8bits.bmp')
#显示图像
cv2.imshow('im_8',im_8)
# 设置图片展示时间
cv2.waitKey()
# 释放内存
cv2.destroyAllWindows()
plt.figure()
plt.imshow(im_8)
cv2.imwrite('im_8.jpg',im_8)
# 设置图片标题
titles = ['24bits','8bits']
pictures = [im_24,im_8]
# 灰度图、idc变换图、高频信息图、增强高频信息后的图
# 设置画布大小
plt.figure(6, figsize=(16, 8))
for i in range(2):
# 绘制子图
plt.subplot(1,2,i+1)
# 绘制图片
plt.imshow(pictures[i],'gray')
# 设置标题,并去除横纵坐标轴上的数字坐标
plt.title(titles[i]), plt.xticks([]), plt.yticks([])
plt.show()
#定义Rgb2gray函数
def Rgb2gray(image):
h = image.shape[0]
w = image.shape[1]
grayimage = np.zeros((h,w),np.uint8)
for i in tqdm(range(h)):
for j in range(w):
#Gray = R*0.299 + G*0.587 + B*0.114.
gray =h*0.299+w*0.587
return grayimage
from PIL import Image
from pylab import *
import cv2
from tqdm import tqdm
# 读取24bits.bmp图像到数组中,并灰度化
image = cv2.imread('./file/24bits.bmp')
im = array(Image.open('./file/24bits.bmp').convert('L'))
# 直方图图像
# flatten可将二维数组转化为一维
hist(image.flatten(), 128)
# 显示
show()
# 读取8bits.bmp图像到数组中,并灰度化
image = cv2.imread('./file/8bits.bmp')
im = Rgb2gray(image)
# 直方图图像
# flatten可将二维数组转化为一维
hist(image.flatten(), 128)
# 显示
show()
# 用于调用图像处理方法
from PIL import Image
# 用于显示图像
import matplotlib.pyplot as plt
# 用于文件和目录操作
import os
# 用于图像处理和操作
import cv2
# 读取本地真彩色图片
im_24 = Image.open('24.bmp')
# 显示图片
plt.imshow(im_24)
# 转换为灰度图像(8位)# 灰度化,8位像素,黑白
#显示为灰度图像
Lim = im_24.convert('L')
plt.figure(figsize=(4,4))
plt.imshow(Lim,'gray')
#matplotlib.pyplot.imshow(X, cmap=None),cmap:颜色图谱(colormap), 默认绘制为RGB(A)颜色空间
# 保存的灰度化图片,jpg形式
im_24.save('24bit_灰度.jpg')
# 转换为二值图像(1位)# 1位像素,黑白,每个字节一个像素存储
Bim = im_24.convert('1')
#创建第二个figure
plt.figure(figsize=(4,4))
#显示图像
plt.imshow(Bim)
#保存为jpg格式图片
Bim.save('24bit_二值.jpg')
# 设置一个带有常量阈值的转换表
threshold = 185
table = []
for i in range(256):
if i < threshold:
table.append(0)
else:
table.append(1)
# 通过表格转换为二进制图像
img = Lim.point(table,'1')
#创建第三个figure
plt.figure(figsize=(4,4))
#显示灰度图像
plt.imshow(img,'gray')
#保存png格式图片
img.save('24bit_二进制.png')
def image_compose():
# 创建一个新图
to_image = Image.new('RGB', (IMAGE_COLUMN * IMAGE_SIZE, IMAGE_ROW * IMAGE_SIZE))
# 循环遍历,把每张图片按顺序粘贴到对应位置上
for y in range(1, IMAGE_ROW + 1):
for x in range(1, IMAGE_COLUMN + 1):
from_image = Image.open(IMAGES_PATH + image_names[IMAGE_COLUMN * (y - 1) + x - 1]).resize(
(IMAGE_SIZE, IMAGE_SIZE), Image.ANTIALIAS)
to_image.paste(from_image, ((x - 1) * IMAGE_SIZE, (y - 1) * IMAGE_SIZE))
plt.imshow(to_image)
return to_image.save("拼接结果.jpg") # 保存拼接之后的结果图
# 图片集地址
IMAGES_PATH = 'img/'
# 图片格式
IMAGES_FORMAT = ['.bmp','.jpg']
# 每张小图片的大小为256
IMAGE_SIZE = 256
# 图片间隔,也就是合并成一张图后,一共有几行
IMAGE_ROW = 2
# 图片间隔,也就是合并成一张图后,一共有几列
IMAGE_COLUMN = 2
# 获取图片集地址下的所有图片名称
image_names = [name for name in os.listdir(IMAGES_PATH) for item in IMAGES_FORMAT if
os.path.splitext(name)[1] == item]
print(image_names)
# 简单的对于参数的设定和实际图片集的大小进行数量判断
l=len(image_names)
if l!=IMAGE_SIZE*IMAGE_COLUMN:
print('错误')
image_compose() # 调用函数
import cv2 # 用于图像处理和操作
#采用cv2读取24.bmp图像
img1 = cv2.imread('24.bmp')
img1 = cv2.cvtColor(img1,cv2.COLOR_BGR2RGB)
#采用cv2读取1.jpg图像
img2 = cv2.imread('1.jpg')
# 调整大小为(300,300)
img2 = cv2.resize(img2,(300,300))
# 获取矩阵行、列和维度
#rows = img2.shape[0]
#cols = img2.shape[1]
#channels = img2.shape[2]
rows,cols,channels = img2.shape
roi = img1[0:rows,0:cols]
dst = cv2.addWeighted(img2, 0.9, roi, 0.1, 0)#图像融合
dst1 = img1.copy()#对原图像进行拷贝
dst1[0:rows,0:cols] = dst
plt.imshow(dst1)
plt.show()
cv2.imshow('dst',dst)#查看融合结果
cv2.imshow('reusult',dst1)#显示处理后的结果
#保存为reusult.jpg
cv2.imwrite('reusult.jpg',dst1)
# 设置图片展示时间
cv2.waitKey()
# 释放内存
cv2.destroyAllWindows()
"""
cv2.imshow()和plt.imshow()的区别
如果需要展示读入的图像,或者展示对读入图像进行一系列操作后的图像时,使用cv2.imshow()
如果不需要展示原始图像,而是绘制一张新的图像,使用plt.imshow()
注意
opencv是BGR通道,plt默认RGB通道,若使用cv2.imread()读入图像,用plt.imshow()展示原始图像或者展示对读入图像进行一系列操作后的图像时,
需要进行通道转换。
在展示灰度图像时,cv2.imshow(‘gray’, gray)
plt.imshow(gray,cmap=‘gray’), plt.title(‘gray’)
"""
整个代码敲下来,也花费我不少时间,总结了一下一些难点(仅针对我自己):
1.图像的融合叠加
在思考这一部分的时候完全是懵的,在网上也找了许多资料,但都没有解决工作问题,后来是看到以前朋友写的代码才得以解决。
首先是对cv2.addWeighted((img2, 1, roi, 0.1, 0)函数的理解
img2 权重为0.9,roi 权重为0.1,补偿量为0。补偿量的作用为亮度调节。
其次呢roi = img1[0:rows,0:cols]这一行代码我将其都运行出来进行对比
通过运行结果可以发现
roi是图像img1同等大小的一个角
dst是roi与img2融合的结果
而最后的结果是经过dst1(就是img1)拷贝dst(融合好的)的r,g,因此就会出现图片上的情况
第二个问题就是上面颜色的问题
我在同时使用plt.show和cv2.imshow展示出来的效果不一样,查询后发现是其两个默认通道不同
opencv是BGR通道,plt默认RGB通道,若使用cv2.imread()读入图像,用plt.imshow()展示原始图像或者展示对读入图像进行一系列操作后的图像时,需要进行通道转换。