1.OpenCV库的安装与使用
OpenCV全称为Open Source Computer Vision Library,是Intel公司支持开发的计算机视觉处理开源软件库,采用C或C++编写,同样提供了Python、MATLAB等语言的接口,可以自由的与醒来linux、Windows、Mac等多平台操作系统中。其充分利用了Intel处理器的高性能多媒体函数库的手工优化性能,提高了运行速度。其覆盖了医学影像、设计外观、定位标记、生物体检测等多个行业领域。
1.1 库下载链接
1.2 库安装
Anaconda Prompt: pip install 文件所在路径+文件名.whl
引用形式:
import cv2
问题:
安装过程可能提示“ImportError: numpy.core.multiarray failed to import”,原因是numpy版本与opencv版本不兼容,此时需要更新numpy
pip install -U numpy
2.OpenCV的基本图片读取
2.1 图片存储形式
在计算机中图片是以矩阵的形式存储在存储介质中的。在OpenCV中三原色(RGB)的排列顺序为BGR。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import cv2
img = np.mat(np.zeros((300, 300), dtype=np.uint8))
print(img.shape)
# cvtColor:Converts an image from one color space to another
# COLOR_GRAY2BGR: 色彩空间转化的全局变量
img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
print(img.shape)
# Displays an image in the specified window
cv2.imshow("test", img)
# Waits for a pressed key
cv2.waitKey(0)
2.2 图像的读取与存储
imread(filename, flags=None): Loads an image from a file.If the image cannot be read (because of missing file, improper permissions, unsupported or invalid format), the function . returns an empty matrix ( Mat::data==NULL )。该函数在读取图片的时候会删除所有图片Alpha通道信息。
参数:
filename: 待读取的文件名
flags: 读取之后被自动处理我何种色彩空间。设置为cv2中的全局变量。
imwrite(filename, img, params=None): Saves an image to a specified file. In general, only 8-bit . single-channel or 3-channel (with 'BGR' channel order) images . can be saved using this function. 要求输出的图片格式为BGR或者灰度图。
参数:
filename: 待存储图片的名称
img: 图片所对应的矩阵
import numpy as np
import cv2
img = cv2.imread("maxin.jpg")
print(img.shape) # (2000, 1360, 3)
img = cv2.imread("maxin.jpg", cv2.IMREAD_GRAYSCALE)
print(img.shape) # (2000, 1360)
cv2.imwrite("maxin.png", img)
2.3 图像的转换
在计算机中存储的时候,任何一个图片的存储都占有一定的空间,而为了减少图片的存储便于在有限的内存中更进一步的转换,对于每个图片来说,可以通过python自带的bytearray()函数对其进行转换。同样,bytearray可通过矩阵重构的方式转换为原本的图片矩阵。
import numpy as np
import cv2
import os
imgByteArray = bytearray(os.urandom(90000))
imgBGR = np.array(imgByteArray).reshape(300, 300)
cv2.imshow("cool", imgBGR)
cv2.waitKey(0)
2.4 Numpy对图像的编辑
由于图像在内存中的存储是通过矩阵的形式存储的,因此,可直接通过numpy对某一位置进行修改。下部代码中,在读取的图片中画了两条白色的线。
import numpy as np
import cv2
img = cv2.imread("maxin.jpg", cv2.IMREAD_GRAYSCALE)
print(img)
print(img.shape) # (2000, 1360)
img[:, 700] = 255
img[680, :] = 255
cv2.imshow(winname="img", mat=img)
cv2.waitKey(0)
3.OpenCV卷积处理
3.1 计算机视觉中常用的3中色彩空间
(1)灰度:仅保留黑白信息的色彩空间称为灰度空间。一般而言,灰度空间对人脸的处理特别有效。
(2)BGR: 在该空间中,每一个像素都是由一个三维数组表示的,分别代表蓝、绿、红三种颜色,且是OpenCV中的主要色彩空间。
(3)HSV: H是色调; S是饱和度; V是黑色度
3.2 卷积核与图像特征提取
卷积核:
在OpenCV甚至是平常的图像处理中,卷积核是一种最常用的图像处理工具。其主要是通过确定的核块来检测图像的某个区域,后根据所检测的像素与其周围存在的像素的亮度差值来改变像素明亮度的工具。
3.3 特征提取方式一:多维卷积
convolve(input, weights, output=None, mode='reflect', cval=0.0, origin=0):多维卷积
参数:
input: 输入的图片数组(array_like)
weights: 卷积核
mode: 亮度调节的方式(constant, reflect, nearest)
cval: 输入数组外边缘的填充值
import numpy as np
import cv2
# ndimage: Multi-dimensional image processing
from scipy import ndimage
kernel33 = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]])
kernel33_D = np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]])
# 读取时直接转换为灰度图
img = cv2.imread("lena.jpg", cv2.IMREAD_GRAYSCALE)
lightImg = ndimage.convolve(img, kernel33_D, mode="reflect", cval=0)
print(lightImg)
cv2.imshow("img", img)
cv2.waitKey(0)
3.4 特征提取方式二:高斯模糊
GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None): Blurs an image using a Gaussian filter
参数:
src: 图片数组,可为任何通道数
ksize: 高斯核的大小。(width, height) -> 长宽可以不同,但两者必须为正的奇数
sigmaX: x方向的高斯核标准差
sigmaY: y方向的高斯核标准差。如果sigmaY为零,则将其设置为等于sigmaX,如果两个sigma均为零,则分别从ksize.width和ksize.height计算(有关详细信息,请参阅#getGaussianKernel); 为了完全控制结果,无论将来可能修改所有这些语义,建议指定所有ksize,sigmaX和sigmaY。
dst: output image of the same size and type as src
borderType: 像素外推法
import numpy as np
import cv2
from scipy import ndimage
img = cv2.imread("lena.jpg", cv2.IMREAD_GRAYSCALE)
blurred = cv2.GaussianBlur(img, (11, 11), sigmaX=0)
gaussImg = img - blurred
cv2.imshow("GaussianBlur", gaussImg)
cv2.waitKey()
3.5 卷积的具体实现
import numpy as np
import cv2
from scipy import ndimage
def myConvolve(dataMat, kernel):
"""
design my convolve function
:param dataMat: img Mat (256, 256)
:param kernel: convolve (3, 3)
:return: Convolution kernel
"""
m, n = dataMat.shape
km, kn = kernel.shape
newMat = np.ones((m-km+1, n-kn+1))
tempMat = np.ones((km, kn))
for row in range(m-km+1):
for col in range(n-kn+1):
for m_k in range(km):
for n_k in range(kn):
tempMat[m_k, n_k] = dataMat[(row+m_k), (col+n_k)] * kernel[m_k, n_k]
newMat[row, col] = np.sum(tempMat)
return newMat
# (256, 256)
img = cv2.imread("lena.jpg", cv2.IMREAD_GRAYSCALE)
kernel33_D = np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]])
# (254, 254)
lightImg = myConvolve(img, kernel33_D)
# # 该函数实际上计算的是相关性,而并非卷积
# lightImg = cv2.filter2D(img, -1, kernel33_D)
# lightImg = ndimage.convolve(img, kernel33_D)
cv2.imshow("my_convolve", lightImg)
cv2.waitKey()
4.OpenCV图像的扩缩裁挖
【扩缩】:
cv.resize(src, dsize, dst=None, fx=None, fy=None, interpolation=None): 对图像进行扩缩
参数:
src: 待调整大小的图片矩阵
dsize: 调整后图片的大小(矩阵的x和y)。若dsize=0, 则为(round(fx*src.cols), round(fy*src.rows))。因此,dsize和fx\fy不能同时为0.
dst: 与src同类型的调整后的输出矩阵
fx/fy: 比例因子,即调整后的图片大小的x和y分别为src中x和y的多少倍。when fx/fy==0, fx = (dsize.width/src.cols), fy = (dsize.height/src.rows)
【挖掘】
即单纯的数组、矩阵操作
import tensorflow as tf
from scipy import ndimage
import cv2
import numpy as np
img = cv2.imread("leaf.png", cv2.IMREAD_GRAYSCALE)
# 放缩
imgBig = cv2.resize(img, (600, 600))
imgSml = cv2.resize(img, (100, 100))
cv2.imshow("Big", imgBig)
cv2.imshow("real", img)
cv2.imshow("Small", imgSml)
# 裁挖
part_of_imgBig = imgBig[200:, 25:575]
cv2.imshow("part", part_of_imgBig)
cv2.waitKey()
5.图像色调调整
cv2除了能够对图像的区域进行设置、自由拉伸和裁剪已有的图像,同样可以对图片的色调(H:[0, 180])、饱和度(S: [0, 255])、明暗度(V: [0, 255])
5.1 色调调整
import cv2
import numpy as np
img = cv2.imread("leaf.png")
# cvtColor: Converts an image from one color space to another
# 将BGR转换成HSV色彩空间
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
turn_green_hsv = img_hsv.copy()
# 每个像素点减30个色调,即黄色被大范围缩减(黄色被大范围缩减)
turn_green_hsv[:, :, 0] = (turn_green_hsv[:, :, 0] - 1000) % 180
turn_green_img = cv2.cvtColor(turn_green_hsv, cv2.COLOR_HSV2BGR)
cv2.imshow("change_H", turn_green_img)
cv2.waitKey()
5.2 饱和度调整
import cv2
import numpy as np
img = cv2.imread("leaf.png")
# cvtColor: Converts an image from one color space to another
# 将BGR转换成HSV色彩空间
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
less_color_hsv = img_hsv.copy()
# 降低图片的饱和度,使得色调变灰
less_color_hsv[:, :, 1] = less_color_hsv[:, :, 1] * 0.1
less_color_img = cv2.cvtColor(less_color_hsv, cv2.COLOR_HSV2BGR)
cv2.imshow("change_H", less_color_img)
cv2.waitKey()
5.3 明暗度调整
import cv2
import numpy as np
img = cv2.imread("leaf.png")
# cvtColor: Converts an image from one color space to another
# 将BGR转换成HSV色彩空间
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
less_light_hsv = img_hsv.copy()
# 降低图片的亮度
less_light_hsv[:, :, 2] = less_light_hsv[:, :, 2] * 0.5
less_light_img = cv2.cvtColor(less_light_hsv, cv2.COLOR_HSV2BGR)
cv2.imshow("change_H", less_light_img)
cv2.waitKey()
5.4 增强图片细节
Gamma变换主要是为了减少计算机视觉与人眼视觉的差异()而做的计算方式,但是在深度学习中,可作为噪声修改的方式增大数据量。
gamma > 1, 图像变暗; gamma < 1, 图像变亮
import cv2
import numpy as np
import pandas as pd
from scipy import ndimage
import matplotlib.pyplot as plt
# plt.imread: Return value is a :class:`numpy.array`. For grayscale images, the return array is MxN.
# For RGB images, the return value is MxNx3. For RGBA images the return value is MxNx4.
img = cv2.imread("leaf.png")
gamma = 2
# 先归一化,gamma作为指数,求出新像素值再还原
# np.round: 将数组舍入到给定的小数
gamma_change = [np.power(x/255, gamma) * 255 for x in range(256)]
gamma_img = np.round(np.array(gamma_change), 2).astype(np.uint8)
# cv2.LUT: 实现映射用的是Opencv的查表函数
img_corrected = cv2.LUT(src=img, lut=gamma_img)
plt.subplot(121)
plt.imshow(img)
plt.subplot(122)
plt.imshow(img_corrected)
plt.show()
6.图像的旋转,平移和翻转
该方法是深度学习对图片处理的常用功能,可以极大的增加数据量。
cv2.wrapAffine(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None)
参数:
src: 待处理的图片原始矩阵
M: 仿射矩阵
dsize: 输出图片矩阵的大小
borderMode: 像素外推法,实际上设置的是变换后的图片怎样显示
import cv2
import numpy as np
img = cv2.imread("leaf.png")
# 仿射矩阵
# 第三列:原点坐标
# 第二列:y轴坐标
# 第一列:x轴坐标
M_copy_img = np.array([[0, 0.8, -100],
[0.8, 0, -12]], dtype=np.float32)
# cv2.warpAffine:对图像应用仿射变换
# borderMode=cv2.BORDER_TRANSPARENT: 这意味着该功能不会修改与源图像中的“异常值”对应的目标图像中的像素(即:修改后的图
# 像直接打印在原始图像之上)
img_change = cv2.warpAffine(img, M_copy_img, (300, 300), borderMode=cv2.BORDER_TRANSPARENT)
# img_change = cv2.warpAffine(img, M_copy_img, (300, 300), borderMode=cv2.BORDER_CONSTANT)
# img_change = cv2.warpAffine(img, M_copy_img, (300, 300), borderMode=cv2.BORDER_DEFAULT)
# img_change = cv2.warpAffine(img, M_copy_img, (300, 300), borderMode=cv2.BORDER_REFLECT)
cv2.imshow("test", img_change)
cv2.waitKey()
7.OpenCV扩大图像数据库
见本博客文章