安装cv2
pip install -i https://pypi.douban.com/simple opencv-python
1. 基本操作
(1)用opencv读取图像
代码
import cv2
im = cv2.imread(r"emo1.jpg", 1)
cv2.imshow("test", im)
cv2.waitKey()
(2)打印图像数据的类型和图像的尺寸
代码
print(type(im))
print(im.shape)
运行结果
输出了图像的数据类型和图像的尺寸,328×447×3表示是一个三通道的彩色图像。
(3)将图像保存到指定的路径
代码
cv2.imwrite('emo.jpg', im)
返回True表示图像保存成功
2. 颜色空间转换
(1)彩色图像灰度化
使用opencv里的cvtColor将图像变成灰度图像,再显示这幅灰度图
代码
import cv2
im = cv2.imread(r"emo1.jpg")
cv2.imshow("Gray0", im)
img_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
cv2.imshow("Gray1", img_gray)
cv2.waitKey()
运行结果
这是原始图像
这是变换后的灰度图像
(2)更换三通道顺序BGR为RGB
可以转换三个通道的顺序,将一个BGR的彩色图像转换成一个RBG的彩色图像,同样调用的是opencv里的cvtColor
代码
import cv2
im = cv2.imread(r"emo1.jpg")
cv2.imshow("BRG", im)
im_rgb = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
cv2.imshow("RGB", im_rgb)
cv2.waitKey()
运行结果
这是原始图像
这是图像转换后的一个结果
(3)BGR和HSV颜色空间转换
把一个BGR的图像转换成一个HSV的彩色图像
代码
import cv2
im = cv2.imread(r"emo1.jpg")
cv2.imshow("BRG", im)
im_rgb = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)
cv2.imshow("RGB", im_rgb)
cv2.waitKey()
运行结果
这是原始图像
这是转换的结果
3. 坐标变换
(1)图像的平移
A.定义平移的函数
a.首先需要获取图像的一个尺寸
b.然后再定义平移的一个矩阵
c.再调用仿射变换的函数实现图像平移(需要指定三个参数,第一个是输入图像,第二个是平移矩阵,第三个是获取图像的一个尺寸)
B.调用定义的平移函数来对图像进行平移操作
代码
import numpy as np
import cv2
def translate(img, x, y):
(h, w) = img.shape[:2]
M = np.float32([[1, 0, x], [0, 1, y]])
shifted = cv2.warpAffine(img, M, (w, h))
return shifted
im = cv2.imread("emo1.jpg")
cv2.imshow("Orig", im)
shifted = translate(im, 0, 50)
cv2.imshow("Shift1", shifted)
shifted = translate(im, -100, 0)
cv2.imshow("Shift2", shifted)
shifted = translate(im, 50, 100)
cv2.imshow("Shift3", shifted)
cv2.waitKey()
运行结果
这是原始图像
这是不同的平移尺寸后的效果
(2)图像的旋转
A.定义一个旋转的函数
a.获取图像的尺寸
b.如果旋转中心值缺失的话,就把旋转中心定义为图像的中心
c.然后调用opencv当中的getRotationMatrix2D计算旋转矩阵
d.然后我们再用opencv当中的仿射变换函数实现旋转操作
代码
import numpy as np
import cv2
def rotate(img, angle, center = None, scale = 0.7):
(h, w) = img.shape[:2]
if center is None:
center = (w/2, h/2)
M = cv2.getRotationMatrix2D(center, angle, scale)
rotated = cv2.warpAffine(img, M, (w, h))
return rotated
im = cv2.imread("emo1.jpg")
cv2.imshow("Orig", im)
rotated = rotate(im, 45)
cv2.imshow("Rotatel", rotated)
rotated = rotate(im, -20)
cv2.imshow("Rotate2", rotated)
rotated = rotate(im, 90)
cv2.imshow("Rotate3", rotated)
cv2.waitKey()
运行结果
这是原图
这是将图片逆时针旋转45度的效果
这是顺时针旋转45度的效果
这是将图片逆时针旋转90度的效果
(3)图像的镜像
调用opencv中的flip来实现图像镜像,需要传入两个参数,第一个参数是要读取的图像,第二个参数如果是零的话代表水平镜像,如果是一的话代表执行垂直镜像
代码
import numpy as np
import cv2
im = cv2.imread("emo1.jpg")
cv2.imshow("orig", im)
im_flip0 = cv2.flip(im, 0)
cv2.imshow("flip vertical", im_flip0)
im_flip1 = cv2.flip(im, 1)
cv2.imshow("flip horizontal", im_flip1)
cv2.waitKey()
运行结果
这是图像水平镜像和垂直镜像后的效果
(4)图像的缩放
实现缩放变换,首先要获取整个图像的一个尺寸,然后再定义目标缩放尺寸,用opencv里面的resize对图像进行缩放,需要实例化三个参数。第一个是需要缩放的图像,第二是播放后图像的尺寸,第三个是插值的方法,这里使用的是最邻近插值法,也可以用双线性插值法进行缩放。
代码
import numpy as np
import cv2
im = cv2.imread("emo1.jpg")
cv2.imshow("orig", im)
(h, w) = im.shape[:2]
dst_size = (200, 300)
method = cv2.INTER_NEAREST
resized = cv2.resize(im, dst_size, interpolation = method)
cv2.imshow("resized1", resized)
dst_size = (800,600)
method = cv2.INTER_LINEAR
resized = cv2.resize(im, dst_size, interpolation = method)
cv2.imshow("resized2", resized)
cv2.waitKey()
运行结果
这是原始的图像
这是用最邻近插值法缩放后的图像
这是用双线性插值法缩放后的图像
4.灰度变换
首先定义一个线性灰度变换的函数,输入包括原始图像k值
(1)如果k的取值范围在0~1的范围内就对灰度值进行压缩
(2)如果k的取值范围大于1的话,就对灰度值进行拉伸
(3)如果k=-1且b=255的话,就对图像进行灰度反转
代码
import numpy as np
import cv2
from matplotlib import pyplot as plt
def linear_trans(img, k, b=0):
trans_list = [(np.float32(x)*k+b) for x in range(256)]
trans_table = np.array(trans_list)
trans_table[trans_table>255] = 255
trans_table[trans_table<0] = 0
trans_table = np.round(trans_table).astype(np.uint8)
return cv2.LUT(img, trans_table)
im = cv2.imread("emo1.jpg")
cv2.imshow("orig", im)
im_inversion = linear_trans(im, -1, 255)
cv2.imshow("inversion", im_inversion)
im_stretch = linear_trans(im, 1.2)
cv2.imshow("garystrech", im_stretch)
im_compress = linear_trans(im, 0.8)
cv2.imshow("graycompress", im_compress)
cv2.waitKey()
运行结果
这是原始图像
这是我们对图像进行灰度压缩后的效果,可以看到图像的对比度降低了
这是灰度拉伸的效果,图像的对比度增强了
这是灰度反转的一个效果图
5. 伽玛变换
首先定义一个伽玛的变换函数,首先将图片当中的灰度值全都归一化到0-1的范围内,然后执行伽马变换,最后再将图像的灰度值恢复到0~255的范围之内
代码
import numpy as np
import cv2
from matplotlib import pyplot as plt
def gamma_trans(img, gamma):
gamma_list = [np.power(x/255.0, gamma) * 255 for x in range(256)]
gamma_table = np.round(np.array(gamma_list)).astype(np.uint8)
return cv2.LUT(img, gamma_table)
im = cv2.imread("emo1.jpg", 0)
cv2.imshow("orig", im)
img_gamma05 = gamma_trans(im, 0.5)
cv2.imshow("gamma0.5", img_gamma05)
img_gamma2 = gamma_trans(im, 2)
cv2.imshow("gamma2", img_gamma2)
cv2.waitKey()
运行结果
原始图像
这是通过伽玛等于0.5后的伽玛变化的结果,可以看到图像的暗部灰度值的动态范围是被拉伸了的,图像亮度灰度值的动态范围被压缩
这是做伽玛等于2的伽玛变化后的结果,可以看到亮部灰度值的动态范围被拉伸,而暗部灰度值的动态范围被压缩,所以整个画面会显得比较暗。
6. 基于直方图的灰度变化
可以用pyplot绘制图像的直方图,直方图当中灰度级的动态范围是从0~255,一共有256个灰度级。
代码
import cv2
from matplotlib import pyplot as plt
im = cv2.imread("emo1.jpg", 0)
cv2.imshow("orig", im)
plt.hist(im.ravel(), 256, [0,256])
plt.show()
cv2.waitKey()
运行结果
这是原始图像以及原始图像对应的直方图
可以调用opencv当中的equalizeHist对图像进行直方图均衡化
代码
from matplotlib import pyplot as plt
im = cv2.imread("emo1.jpg", 0)
cv2.imshow("orig", im)
im_equl = cv2.equalizeHist(im)
cv2.imshow("equal", im_equl)
plt.subplot(2, 1, 1)
plt.hist(im.ravel(), 256, [0,256], label="orig")
plt.legend()
plt.subplot(2, 1, 2)
plt.hist(im_equl.ravel(), 256, [0,256], label="equalize")
plt.legend()
plt.show()
cv2.waitKey()
运行结果
这是对原始图像进行直方图均值化后的图像
这是其对应的直方图,可以看到图像整个的对比度被增强了,暗处的一些细节信息更明显了
7. 图像滤波
(1)中值滤波器
可以调用opencv当中的medianBlur这个API对图像进行中值滤波。需要实例化两个参数,第一个是输入的图像,第二个是中值滤波器的大小,5代表中值滤波器的大小是5×5
代码
import cv2
import numpy as np
im = cv2.imread("dog.jpg")
cv2.imshow("orig", im)
im_medianblur = cv2.medianBlur(im, 5)
cv2.imshow("median_blur",im_medianblur )
cv2.waitKey()
运行结果
这是一个原图,可以看到原图里面是充满了噪声,这个噪声就是salt & pepper(椒盐噪声)。
这是对图像进行中值滤波后的效果
通过中值滤波之后,可以看到图像明显变得清晰了。这就是中值滤波的优点,它可以达到降噪的效果,同时可以保留原始图像的一个锐度。
(2)均值滤波器
A.我们调用opencv当中的blur这个API对图像进行均值滤波,均值滤波器的大小是3×3的
B.也可以自己定义一个均值算子,就需要创建一个矩阵,这里矩阵的大小是3×3,矩阵中的每一个元素都是1,最后对窗口当中的9个元素取均值,这就是均值算子。然后用opencv中的filter,用这个均值算子对图像进行均值滤波
代码
import cv2
import numpy as np
im = cv2.imread("emo1.jpg")
cv2.imshow ("orig", im)
im_meanblur1 = cv2.blur(im, (3, 3))
cv2.imshow("mean_blur_1", im_meanblur1)
cv2.waitKey ()
import cv2
import numpy as np
im = cv2.imread("emo1.jpg")
cv2.imshow ("orig", im)
mean_blur = np.ones([3,3], np.float32)/9
im_meanblur2 = cv2.filter2D(im, -1, mean_blur)
cv2.imshow("mean_blur_2", im_meanblur2)
cv2.waitKey()
运行结果
这是原始图像
这是对图像进行均值滤波后的效果,可以看到图像明显变得模糊化了,这就是均值滤波的一个效果,它可以达到图像平滑的一个效果
(3)高斯滤波
A.可以直接调用opencv当中的GaussianBlur这个API对图像进行高斯滤波
代码
import cv2
import numpy as np
im = cv2.imread("emo1.jpg")
cv2.imshow ("orig", im)
im_gaussianblur1 = cv2.GaussianBlur(im, (5, 5), 0)
cv2.imshow("gaussian_blur_1", im_gaussianblur1)
cv2.waitKey()
运行结果
B.也可以自己建一个高斯filter,然后用opencv当中filter2D对图像进行滤波
代码
import cv2
import numpy as np
im = cv2.imread("emo1.jpg")
cv2.imshow ("orig", im)
gaussian_blur = np.array([
[1, 4, 7, 4, 1],
[4, 16 , 26, 16, 4],
[7, 26, 41, 26, 7],
[4, 16 , 26, 16, 4],
[1, 4, 7, 4, 1]],np.float32)/273
im_gaussianblur2 = cv2.filter2D(im, -1, gaussian_blur)
cv2.imshow("gaussian_blur_2", im_gaussianblur2)
运行结果
相较于刚才均值滤波器的效果,如果用高斯滤波的话,可以一定程度的减少图像的模糊化
(4)锐化
图像的锐化分为两个步骤,第一是对图像进行边缘检测,第二步是原始图像乘以一定的系数然后再加上边缘检测后的效果图。锐化算子一般分为基于一阶梯度的和基于二阶梯度的。基于一阶梯度的锐化算子最典型的就是Sobel梯度算子,基于二阶梯度的锐化算子最典型的就是拉普拉斯算子。
这里我们建立的两个锐化算子都是二阶的锐化算子
代码
import cv2
import numpy as np
im = cv2.imread("emo1.jpg")
cv2.imshow ("orig", im)
sharpen_1 = np.array([
[-1, -1, -1],
[-1, 9, -1],
[-1, -1, -1]
])
im_sharpen_1 = cv2.filter2D(im, -1, sharpen_1)
cv2.imshow("sharpen_1", im_sharpen_1)
sharpen_2 = np.array([
[0, -1, 0],
[-1, 8, -1],
[0, 1, 0]])/4.0
im_sharpen_2 = cv2.filter2D(im, -1, sharpen_2)
cv2.imshow("sharpen_2", im_sharpen_2)
cv2.waitKey()
运行结果
这是原始图像
这是图像锐化后的一个效果
这是用第二个锐化算进行图像液化后的果,可以观察到第二个锐化算子最后有一个除以四的过程,就可以增加图像的一个模糊化。
Original: https://blog.csdn.net/qq_45070951/article/details/126103358
Author: 柒柒伍贰玖。
Title: 【python】图像数据预处理
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/636581/
转载文章受原作者版权保护。转载请注明原作者出处!