上机练习 2 图像灰度变换、几何变换及图像运算
一、上机目的
学习编程实现常见的图像灰度变换、几何变换及图像运算方法
二、相关知识及练习
- 彩色图像转化为灰度图像
现在大部分的彩色图像都是采用 RGB 颜色模式,处理图像的时候,要分别对 RGB 三种分量进行处理,但实际上单纯 RGB 图像并不能反映图像的形态特征,只是从光学的原理上进行颜色的调配,机器并不能够通过人眼的角度来迅速智慧的识别物体的框架、边角等信息,机器在进行计算的时候,如果是包含色彩的图片,特征量,计算量会成指数倍数增加。将图片转化为灰度图片,能使计算范围降低、提升计算效率。
可使用加权平均法进行灰度化处理
算法实现:
import cv2
import numpy as np
img = cv2.imread ('lena.png') h, w = img.shape[0:2] print(h,w)
gray = np.zeros((h, w), dtype=img.dtype)
for i in range(h):
for j in range(w):
gray[i, j] = (0.3*int(img[i, j, 0]) + 0.59*int(img[i, j, 1]) + 0.11*int(img[i, j, 2]))
cv2.imshow('Gray',gray) cv2.imshow('Result',img) cv2.waitKey(0)
练习:运行并分析上述算法程序,对关键程序语句进行注解。
在 OpenCV 中,也有函数 cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)可实现灰度化处理,其函数原型如下所示:
dst = cv2.cvtColor(src, code[, dst[, dstCn]])
src 表示输入图像,需要进行颜色空间变换的原图像
dst 表示输出图像,其大小和深度与 src 一致
code 表示转换的代码或标识
dstCn 表示目标图像通道数,其值为 0 时,则有 src 和 code 决定
该函数的作用是将一个图像从一个颜色空间转换到另一个颜色空间,其中,RGB 是指 Red、Green 和 Blue,一副图像由这三个通道(channel)构成;Gray 表示只有灰度值一个通道;HSV 包含 Hue(色调)、Saturation(饱和度)和 Value(亮度)三个通道。在 OpenCV中,常见的颜色空间转换标识包括 CV_BGR2BGRA、CV_RGB2GRAY、CV_GRAY2RGB、CV_BGR2HSV、 CV_BGR2XYZ、CV_BGR2HLS 等。
练习:编写利用 cv2.cvtColor 函数实现彩色图像转化为灰度图像的程序。
- 灰度变换
灰度变换属于对图像的空间域进行变换的技术,灰度变换是对每一个像素点的,即将每一个灰度值放入某个变换函数中,然后将输出值作为输出图像的灰度值。利用灰度变换可以实现图像增强,注意图像增强是面向特定的问题,即不同的问题增强图像的需求也不一样,有的需要增强对比度,有的需要增强低像素值处的细节。常见的一些变换函数如下:
3.伽马变换
灰度变换程序实例:反转,灰度拉伸,灰度压缩。
import numpy as np
import cv2
from matplotlib import pyplot as plt
# 定义线性灰度变化函数
# k>1 时 实现灰度数值的拉伸
# 0<k<1 时 实现灰度数值的压缩
# k=-1 b=255 实现灰度反转
def linear_trans(img, k, b=0):
# 计算灰度线性变化的映射表
trans_list = [(np.float32(x)*k+b) for x in range(256)]
# 将列表转换为 np.array
trans_table =np.array(trans_list)
# 将超过[0,255]灰度范围的数值进行调整,并指定数据类型为 uint8
trans_table[trans_table>255] = 255
trans_table[trans_table<0] = 0
trans_table = np.round(trans_table).astype(np.uint8) # 使用 OpenCV 的 look up table 函数修改图像的灰度值 return cv2.LUT(img, trans_table)
im = cv2.imread('lena.png',0) cv2.imshow('org', im)
# 反转
im_inversion = linear_trans(im, -1, 255) cv2.imshow('inversion', im_inversion)
# 灰度拉伸
im_stretch = linear_trans(im, 1.2) cv2.imshow('graystretch', im_stretch)
# 灰度压缩
im_compress = linear_trans(im, 0.8) cv2.imshow('graycompress', im_compress) cv2.waitKey(0)
cv2.destroyAllWindows()
理解分析上面的程序,掌握灰度变换中反转、灰度拉伸、灰度压缩等方法的实现原理。注:LUT 是 look-up table 查找表的意思,cv2.LUT(src, lut, dst=None)的作用是对输
入的 src 执行查找表 lut 转换
cv2. LUT(src, lut, dst=None)有三个参数,分别为: src:输入数据 array,类型为 8 位整型(np.uin8)
lut:查找表,如果输入 src 是多通道的,例如是 BGR 三通到的图像,而查表是单通道的,则此时 B、G、R 三个通道使用的是同一个查找表
dst=None:输出数组,大小和通道数与 src 相同,而深度 depth 与 lut 相同
图像几何变换
图像的几何变换是指图像的平移、旋转、仿射变换等。请练习及理解下面的图像几何变换程序。
步骤 1 平移
平移例程 2:
import numpy as np
import cv2
# 定义平移 translate 函数
def translate(img, x, y): # 获取图像尺寸
(h, w) = img.shape[:2]
# 定义平移矩阵
M = np.float32([[1, 0, x], [0, 1, y]])
# 使用 OpenCV 仿射变换函数实现平移操作
shifted = cv2.warpAffine(img, M, (w, h)) # 返回转换后的图像
return shifted # 加载图像并显示
im = cv2.imread('lena.png') cv2.imshow("Orig", im)
# 对原图做平移操作
# 下移 50 像素
shifted = translate(im, 0, 50)
cv2.imshow("Shift1", shifted) # 左移 100 像素
shifted = translate(im, -100, 0) cv2.imshow("Shift2", shifted)
# 右移 50,下移 100 像素
shifted = translate(im, 50, 100) cv2.imshow("Shift3", shifted) cv2.waitKey(0) cv2.destroyAllWindows()
步骤 2 旋转
center = (w / 2, h / 2) # 调用计算旋转矩阵函数
M = cv2.getRotationMatrix2D(center, angle, scale)
# 使用 OpenCV 仿射变换函数实现旋转操作 rotated = cv2.warpAffine(img, M, (w, h)) # 返回旋转后的图像
return rotated
im = cv2.imread('lena.png') cv2.imshow("Orig", im)
# 对原图做旋转操作
# 逆时针 45 度
rotated = rotate(im, 45) cv2.imshow("Rotate1", rotated) # 顺时针 20 度
rotated = rotate(im, -20) cv2.imshow("Rotate2", rotated) # 逆时针 90 度
rotated = rotate(im, 90) cv2.imshow("Rotate3", rotated) cv2.waitKey(0) cv2.destroyAllWindows()
例程 2:
import numpy as np import cv2
# 定义旋转 rotate 函数
def rotate(img, angle, center=None, scale=1.0): # 获取图像尺寸
(h, w) = img.shape[:2]
# 旋转中心的缺失值为图像中心
if center is None:
center = (w / 2, h / 2) # 调用计算旋转矩阵函数
M = cv2.getRotationMatrix2D(center, angle, scale)
# 使用 OpenCV 仿射变换函数实现旋转操作 rotated = cv2.warpAffine(img, M, (w, h)) # 返回旋转后的图像
return rotated
im = cv2.imread('lena.png') cv2.imshow("Orig", im)
# 对原图做旋转操作
# 逆时针 45 度
rotated = rotate(im, 45) cv2.imshow("Rotate1", rotated) # 顺时针 20 度
rotated = rotate(im, -20) cv2.imshow("Rotate2", rotated) # 逆时针 90 度
rotated = rotate(im, 90) cv2.imshow("Rotate3", rotated) cv2.waitKey(0) cv2.destroyAllWindows()
步骤 3 镜像
im = cv2.imread('lena.jpg') # 进行垂直镜像
im = cv2.imread('lena.jpg') # 进行垂直镜像
im_flip0 = cv2.flip(im, 0) # 进行水平镜像
im_flip1 = cv2.flip(im, 1)
im_flip0 = cv2.flip(im, 0) # 进行水平镜像
im_flip1 = cv2.flip(im, 1)
步骤 4 缩放
import numpy as np import cv2
im = cv2.imread('lena.jpg') matshow("orig", im)
# 获取图像尺寸
(h, w) = im.shape[:2] # 缩放的目标尺寸 dst_size = (200,300) # 最邻近插值
method = cv2.INTER_NEAREST # 进行缩放
resized = cv2.resize(im, dst_size, interpolation = method) # 缩放的目标尺寸
dst_size = (800,600) # 双线性插值
method = cv2.INTER_LINEAR # 进行缩放
resized = cv2.resize(im, dst_size, interpolation = method)
步骤 5
图像上的算术运算
|
图像上的算术运算
三、上机内容
-
- 按照上面相关知识的介绍,通过编写或运行相应的程序实例掌握图像灰度变换、几何变换及图像运算的原理及程序实现方法,所有运行过的程序及运行结果截图保存到 word 文档中。
- 练习:编写图像仿射变换的程序,并展示运行结果。
- 练习:如果输入的两幅图像分辨率大小不同,如何进行图像融合,尝试编写相应的程序。
- 练习:尝试编写图像灰度伽马变换的程序,并对比不同 gamma 值变换前后的效果变化。