(1)使用opencv读取一幅彩色图像,编写统计单个波段的直方图的函数,
对三个波段调用并用matplotlib画图用不同颜色的线条显示每个波段的直方图。
并于opencv自带的直方图统计函数的结果做比较。
import cv2 # opencv读取格式是BGR
import matplotlib.pyplot as plt
import numpy as np
import pylab
"""
定义直方图hist
hist = cv2.calcHist([img], [0], None, [256], [0, 256])
calcHist(images,channels,mask,histSize,ranges)
mask = np.zeros(img.shape, np.uint8)
mask[200:400, 200:400]
channels:如果传入图像是灰度图,他的值就是[0],如果是彩色图像,传入的值可以是[0][1][2],对应着BGR
mask:掩模图像,统计整幅图像的直方图用None,如果想统计某一部分图像的直方图,可以制作一个掩模图像
histSize:BIN的数目
像素值范围常为[0,256]
"""
# 定义展示图片的函数
def cv_show(name, img):
cv2.namedWindow(name, 0)
cv2.imshow(name, img)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
# 定义统计R\G\B直方图的函数
def cal(tongdao, color):
a = np.zeros(256, dtype=int)
for i in range(tongdao.shape[0]):
for j in range(tongdao.shape[1]):
a[tongdao[i, j]] += 1
print(a)
x = np.arange(0, 256)
plt.plot(x, a, color)
# 读取图片,将其命名为img
img = cv2.imread('photo.png', cv2.IMREAD_COLOR)
b, g, r = cv2.split(img) # 通道分离,r,g,b都是二维数组
# 调用展示图片的函数
cv_show('image', img)
# 调用自己写的函数画出三个通道的直方图
cal(b, 'b')
cal(g, 'g')
cal(r, 'r')
# 调用opencv自带的函数统计直方图
color = ('b', 'g', 'r')
for i, col in enumerate(color): # 枚举格式enumerate(color),i作为索引0,1,2代表三个颜色通道
hist = cv2.calcHist([img], [i], None, [256], [0, 256])
plt.plot(hist, color=col)
# plt.show() # 三个线条在3个图中
plt.show() # 三个线条在同一个图中
(2)将图像的每个波段按照公式:Gray = R*0.299 + G*0.587 + B*0.114,生成灰度图,
再次调用统计直方图的函数,并画出直方图。
img = cv2.imread('photo.png', cv2.IMREAD_COLOR)
b, g, r = cv2.split(img) # 通道分离,r,g,b都是二维数组
gray = r * 0.299 + g * 0.587 + b * 0.114
# 合并三个通道
gray = cv2.merge([b, g, r])
# 保存新的图片gray
cv2.imwrite('try.jpg', gray)
"""
灰度转换函数:cvtColor(参数1,参数2),参数1代表原图,参数2代表转换方式
转换方式:
BGR变成GRAY:cv2.COLOR_BGR2GRAY
GRAY变成BGR:cv2.COLOR_GRAY2BGR
BGR变成BGR:cv2.COLOR_BGR2BGR
"""
gray1 = cv2.cvtColor(gray, cv2.COLOR_BGR2GRAY) # 灰度图gray1
color = ('b', 'g', 'r')
for i, col in enumerate(color): # 枚举格式enumerate(color),i作为索引0,1,2代表三个颜色通道
hist = cv2.calcHist([gray], [i], None, [256], [0, 256])
plt.plot(hist, color=col)
# plt.show()
cv_show('image', gray1)
(3)将R波段乘以1.5,B波段进行灰度线性拉伸,范围由(min, max)拉伸至50-150,G波段进行分段线性拉伸,由(0,100,200,255)拉伸至(0,20,150,200),再合成为新的RGB图像,保存为png图片。
img = cv2.imread('photo.png', cv2.IMREAD_COLOR)
b, g, r = cv2.split(img) # 通道分离,r,g,b都是二维数组
out_r = np.uint8(r * 1.5) # 灰度图必须为整形,利用函数np.unit8()
'''
灰度拉伸
output=255/(B-A)*[img_gray-A]
其中,A为最小灰度级,B为最大灰度级
img_gray为输入图像,output为输出图像
缺点:若图像中最小灰度值=0,最大灰度值=255,则图像不会有什么改变
'''
def grey_scale(image, min, max):
A = min
B = max
print("最小灰度值:%d,最大灰度值:%d" % (A, B))
output = np.uint8(255 / (B - A) * (image - A) + 0.5)
return output
out_b = grey_scale(r, 50, 150)
out_g = grey_scale(g, 0, 200)
cv2.namedWindow("in", 0) # 可以拖动窗口大小
cv2.resizeWindow("in", 640, 480) # 设置窗口大小
cv2.moveWindow("in", 10, 20) # 设置窗口位置
cv2.namedWindow("out", 0) # 可以拖动窗口大小
cv2.resizeWindow("out", 640, 480) # 设置窗口大小
cv2.moveWindow("out", 600, 300) # 设置窗口位置
cv2.imshow("in", cv2.cvtColor(img, cv2.COLOR_BGR2GRAY))
cv2.imshow("out", out_r)
cv2.imwrite('gray1.jpg', out_r)
cv2.imshow("out", out_g)
cv2.imwrite('gray2.jpg', out_g)
cv2.imshow("out", out_b)
cv2.imwrite('gray3.jpg', out_b)
(4)调用opencv的函数实现彩色图像缩放、旋转、翻转、平移,
再使用numpy实现图像的左右翻转和上下翻转,使用matplotlib画图,同时保存为新的图像。
img = cv2.imread('photo.png', cv2.IMREAD_COLOR)
# opencv缩放:
# 按照指定的宽度、高度缩放图片(图像可能变形)
res1 = cv2.resize(img, (132, 150))
# 按照比例缩放,如x,y轴均放大一倍
res2 = cv2.resize(img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_LINEAR)
cv2.imshow('shrink', res1), cv2.imshow('zoom', res2)
# opencv平移:
rows, cols = img.shape[:2]
# 定义平移矩阵,需要是numpy的float32类型
# x轴平移200,y轴平移100
M = np.float32([[1, 0, 200], [0, 1, 100]])
# 用仿射变换实现平移,第三个参数为输出的图像大小,值得注意的是该参数形式为(width, height)。
dst = cv2.warpAffine(img, M, (cols, rows))
namedWindow = ('des', 0)
cv2.imshow('dst', dst)
# opencv旋转:
image_1 = cv2.transpose(img) # 矩阵的转置也可以凑合实现90旋转
# cv2.namedWindow('image1', 0)
cv2.imshow('image1', image_1)
image_2 = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)
# cv2.namedWindow('image2', 0)
cv2.imshow('image2', image_2)
# opencv翻转:
"""
第二个参数=0:上下翻转
第二个参数>0:左右翻转
第二个参数<0:上下左右翻转
"""
dst = cv2.flip(img, -1)
cv2.namedWindow('dst', 0)
cv2.imshow('dst', dst)
img = cv2.imread('photo.png', cv2.IMREAD_COLOR)
print(type(img)) # <class 'numpy.ndarray'>
print(img.shape) # (2584, 4592, 3)
# img = img[:, :, (2, 1, 0)] # BGR通道顺序改变为RGB
# 左右翻转(调换列):
plt.imshow(img[:, ::-1, (2, 1, 0)]) # 注意通道顺序
# img_lr = np.fliplr(img)
# plt.imshow(img_lr) # 注意通道顺序
plt.savefig('matplotlib1.jpg')
pylab.show() # 调用不同模块的问题,为了可视化显示图片
# 使用opencv显示图片:
# img_lr = img[:, ::-1, :]
# cv2.namedWindow("img_lr", 0)
# cv2.imshow('img_lr', img_lr)
# 上下翻转(调换行):
plt.imshow(img[::-1, :, (2, 1, 0)]) # 注意通道顺序
# img_ud = np.flipud(img)
# plt.imshow(img_ud) # 注意通道顺序
plt.savefig('matplotlib2.jpg')
pylab.show() # 调用不同模块的问题,为了可视化显示图片
注意图片路径: