面试题 (opencv前十道)
1. 归一化:将特征缩放到0~1或-1~1之间
2. 模型参数:y = wx + b 中的w和b,通过学习得来的
超参数:提前设置好的,主要根据经验值或试验得来
3. 激活函数的比较
1)Sigmoid和RELU
- Sigmoid容易出现梯度消失, RELU修正了梯度消失的问题
2)Sigmoid和tanh
- Sigmoid范围0~1,均值点为0.5; tanh范围-1~1,均值点为0
- tanh收敛速度比sigmoid快
3)Sigmoid和softmax
- Sigmoid用于二分类,softmax用于多分类
4)softmax和Relu
```shell
# 安装opencv核心库
pip3 install --user opencv-python==3.4.2.16 --index-url https://pypi.tuna.tsinghua.edu.cn/simple/ --trusted-host https://pypi.tuna.tsinghua.edu.cn
# 安装opencv贡献库
pip3 install --user opencv-contrib-python==3.4.2.16 --index-url https://pypi.tuna.tsinghua.edu.cn/simple/ --trusted-host https://pypi.tuna.tsinghua.edu.cn
2)色彩通道操作
#### 3)灰度直方图均衡化
#### 4)彩色亮度直方图均衡化
#### 5)色彩提取
从图片中提取特定颜***r />
#### 6)二值化与反二值化
2. 模型参数:y = wx + b 中的w和b,通过学习得来的
超参数:提前设置好的,主要根据经验值或试验得来
3. 激活函数的比较
1)Sigmoid和RELU
- Sigmoid容易出现梯度消失, RELU修正了梯度消失的问题
2)Sigmoid和tanh
- Sigmoid范围0~1,均值点为0.5; tanh范围-1~1,均值点为0
- tanh收敛速度比sigmoid快
3)Sigmoid和softmax
- Sigmoid用于二分类,softmax用于多分类
4)softmax和Relu
- softmax主要用于输出层,Relu主要用于隐藏层
2. 计算N个概率的交叉熵
# 计算交叉熵 import math p_true = [0, 1, 0, 0, 0] # 真实概率 p_pred1 = [0.1, 0.6, 0.1, 0.1, 0.1] # 预测概率 p_pred2 = [0.1, 0.7, 0.1, 0.05, 0.05] # 预测概率 p_pred3 = [0.1, 0.8, 0.04, 0.03, 0.03] # 预测概率 print(sum(p_true)) print(sum(p_pred1)) print(sum(p_pred2)) print(sum(p_pred3)) cross_entropy1 = 0.0 cross_entropy2 = 0.0 cross_entropy3 = 0.0 # 计算每组预测概率和真实概率的交叉熵(实际上只计算对应正确解标签的输出的自然对数) for i in range(len(p_true)): cross_entropy1 += (p_true[i] * math.log(p_pred1[i])) cross_entropy2 += (p_true[i] * math.log(p_pred2[i])) cross_entropy3 += (p_true[i] * math.log(p_pred3[i])) # 打印结果 print("交叉熵1:", -cross_entropy1) print("交叉熵2:", -cross_entropy2) print("交叉熵3:", -cross_entropy3) ```
### 3. 验证图像卷积运算效果 ```python from scipy import signal from scipy import misc import matplotlib.pyplot as plt import numpy as np import scipy.ndimage as sn im = misc.imread("data/zebra.png", flatten=True) # face = sn.imread("data/zebra.png", flatten=True) flt = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]) flt2 = np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]]) # 把图像的face数组和设计好的卷积和作二维卷积运算,设计边界处理方式为symm conv_img1 = signal.convolve2d(im, flt,boundary='symm',mode='same').astype("int32") conv_img2 = signal.convolve2d(im, flt2,boundary='symm',mode='same').astype("int32") plt.figure("Conv2D") plt.subplot(131) plt.imshow(im, cmap='gray') # 显示原始的图 plt.xticks([]) plt.yticks([]) plt.subplot(132) plt.xticks([]) plt.yticks([]) plt.imshow(conv_img1, cmap='gray') # 卷积后的图 cmap:颜色图谱 plt.subplot(133) plt.xticks([]) plt.yticks([]) plt.imshow(conv_img2, cmap='gray') # 卷积后的图 plt.show() 图片:三个斑马那个OpenCV版:
from scipy import misc from scipy import signal import matplotlib.pyplot as plt import matplotlib import numpy as np import scipy.ndimage as sn import cv2 import pylab im = cv2.imread("../data/zebra.png",0) flt = np.array([[-1,0,1], [-2,0,2], [-1,0,1]])/2 flt2 = np.array([[1,2,1], [0,0,0], [-1,-2,-1]])/2 conv_img1 = cv2.filter2D(im, -1, flt,borderType=1) conv_img2 = cv2.filter2D(im, -1, flt2,borderType=1) cv2.imshow("im",im) cv2.imshow("conv_img1",conv_img1) cv2.imshow("conv_img2",conv_img2) cv2.waitKey() cv2.destroyAllWindows()
二、OpenCV部分
1. OpenCV安装
执行以下命令安装opencv-python库(核心库)和opencv-contrib-python库(贡献库)。注意:命令拷贝后要合成一行执行,中间不要换行。```shell
# 安装opencv核心库
pip3 install --user opencv-python==3.4.2.16 --index-url https://pypi.tuna.tsinghua.edu.cn/simple/ --trusted-host https://pypi.tuna.tsinghua.edu.cn
# 安装opencv贡献库
pip3 install --user opencv-contrib-python==3.4.2.16 --index-url https://pypi.tuna.tsinghua.edu.cn/simple/ --trusted-host https://pypi.tuna.tsinghua.edu.cn
2. OpenCV基本操作
1)读取、图像、保存图像 读取图像 import cv2 im = cv2.imread("../data/Linus.png", 1) # 1表示3通道彩色,0表示单通道灰度 cv2.imshow("test", im) # 在test窗口中显示图像 print(type(im)) # 打印数据类型 print(im.shape) # 打印图像尺寸 cv2.imwrite("../data/Linus_2.png", im) # 将图像保存到指定路径 cv2.waitKey() # 等待用户按键反馈 cv2.destroyAllWindows() # 销毁所有创建的窗口
3.图像色彩操作
#### 1)彩色图像转换为灰度图像# 彩色图像转换为灰度图像示例 import cv2 im = cv2.imread("../data/Linus.png", 1) cv2.imshow("RGB", im) # 在test窗口中显示图像 # 使用cvtColor进行颜色空间变化,COLOR_BGR2GRAY表示BGR to GRAY img_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) # 彩色图像灰度化 cv2.imshow("Gray", img_gray) cv2.waitKey() # 等待用户按键反馈 cv2.destroyAllWindows() # 销毁所有创建的窗口
2)色彩通道操作
# 色彩通道操作:通道表示为BGR import numpy as np import cv2 im = cv2.imread("../data/opencv2.png") print(im.shape) cv2.imshow("im", im) # 取出蓝色通道,当做单通道图像显示 b = im[:, :, 0] cv2.imshow("b", b) # 去掉蓝色通道(索引为0的通道) im[:, :, 0] = 0 cv2.imshow("im-b0", im) # 去掉绿色通道(索引为1的通道) im[:, :, 1] = 0 cv2.imshow("im-b0g0", im) cv2.waitKey() cv2.destroyAllWindows()
#### 3)灰度直方图均衡化
# 直方图均衡化示例 import numpy as np import cv2 from matplotlib import pyplot as plt im = cv2.imread("../data/sunrise.jpg", 0) cv2.imshow("orig", im) # 直方图均衡化 im_equ = cv2.equalizeHist(im) cv2.imshow("equ1", im_equ) # 绘制灰度直方图 ## 原始直方图 print(im.ravel()) plt.subplot(2, 1, 1) plt.hist(im.ravel(), #ravel返回一个连续的扁平数组 256, [0, 256], label="orig") plt.legend() ## 均衡化处理后的直方图 plt.subplot(2, 1, 2) plt.hist(im_equ.ravel(), 256, [0, 256], label="equalize") plt.legend() plt.show() cv2.waitKey() cv2.destroyAllWindows()
#### 4)彩色亮度直方图均衡化
# 彩色图像亮度直方图均衡化 import cv2 # 读取原始图片 original = cv2.imread('../data/sunrise.jpg') cv2.imshow('Original', original) # BRG空间转换为YUV空间 # YUV:亮度,色度,饱和度,其中Y通道为亮度通道 yuv = cv2.cvtColor(original, cv2.COLOR_BGR2YUV) print("yuv.shape:", yuv.shape) yuv[..., 0] = cv2.equalizeHist(yuv[..., 0]) # 取出亮度通道,均衡化并赋回原图像 equalized_color = cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR) cv2.imshow('Equalized Color', equalized_color) cv2.waitKey() cv2.destroyAllWindows()
#### 5)色彩提取
从图片中提取特定颜***r />
import cv2 import numpy as np im = cv2.imread("../data/opencv2.png") hsv = cv2.cvtColor(im, cv2.COLOR_BGR2HSV) cv2.imshow('opencv', im) # =============指定蓝色值的范围============= # 蓝色H通道值为120,通常取120上下10的范围 # S通道和V通道通常取50~255间,饱和度太低、色调太暗计算出来的颜色不准确 minBlue = np.array([110, 50, 50]) maxBlue = np.array([130, 255, 255]) # 确定蓝***域 mask = cv2.inRange(hsv, minBlue, maxBlue) # 选取出掩模 # cv2.imshow("mask", mask) # 通过掩码控制的按位与运算,锁定蓝***域 blue = cv2.bitwise_and(im, im, mask=mask) # 执行掩模运算 cv2.imshow('blue', blue) # =============指定绿色值的范围============= minGreen = np.array([50, 50, 50]) maxGreen = np.array([70, 255, 255]) # 确定绿***域 mask = cv2.inRange(hsv, minGreen, maxGreen) # cv2.imshow("mask", mask) # 通过掩码控制的按位与运算,锁定绿***域 green = cv2.bitwise_and(im, im, mask=mask) # 执行掩模运算 cv2.imshow('green', green) # =============指定红色值的范围============= minRed = np.array([0, 50, 50]) maxRed = np.array([30, 255, 255]) # 确定红***域 mask = cv2.inRange(hsv, minRed, maxRed) # cv2.imshow("mask", mask) # 通过掩码控制的按位与运算,锁定红***域 red = cv2.bitwise_and(im, im, mask=mask) # 执行掩模运算 cv2.imshow('red', red) cv2.waitKey() cv2.destroyAllWindows()
#### 6)二值化与反二值化
# 二值化处理 import cv2 as cv # 读取图像 img = cv.imread("../data/lena.jpg", 0) cv.imshow("img", img) # 显示原始图像 # 二值化 t, rst = cv.threshold(img, 127, 255, cv.THRESH_BINARY) cv.imshow("rst", rst) # 显示二值化图像 # 反二值化 t, rst2 = cv.threshold(img, 127, 255, cv.THRESH_BINARY_INV) cv.imshow("rst2", rst2) # 显示反二值化图像 cv.waitKey() cv.destroyAllWindows()
### 4. 图像形态操作
#### 1)图像翻转
#### 2)图像仿射变换
#### 1)图像翻转
# 图像翻转示例 import numpy as np import cv2 im = cv2.imread("../data/Linus.png") cv2.imshow("src", im) # 0-垂直镜像 im_flip0 = cv2.flip(im, 0) cv2.imshow("im_flip0", im_flip0) # 1-水平镜像 im_flip1 = cv2.flip(im, 1) cv2.imshow("im_flip1", im_flip1) cv2.waitKey() cv2.destroyAllWindows()
#### 2)图像仿射变换
# 图像仿射变换 import numpy as np import cv2 def translate(img, x, y): """ 坐标平移变换 :param img: 原始图像数据 :param x:平移的x坐标 :param y:平移的y坐标 :return:返回平移后的图像 """ h, w = img.shape[:2] # 获取图像高、宽 # 定义平移矩阵 M = np.float32([[1, 0, x], [0, 1, y]]) # 使用openCV仿射操作实现平移变换 shifted = cv2.warpAffine(img, M, (w, h)) # 第三个参数为输出图像尺寸 return shifted # 返回平移后的图像 def rotate(img, angle, center=None, scale=1.0): """ 图像旋转变换 :param img: 原始图像数据 :param angle: 旋转角度 :param center: 旋转中心,如果为None则以原图中心为旋转中心 :param scale: 缩放比例,默认为1 :return: 返回旋转后的图像 """ 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 # 返回旋转后的矩阵 if __name__ == "__main__": # 读取并显示原始图像 im = cv2.imread("../data/Linus.png") cv2.imshow("SrcImg", im) # 图像向下移动50像素 shifted = translate(im, 0, 50) cv2.imshow("Shifted1", shifted) # 图像向左移动40, 下移动40像素 shifted = translate(im, -40, 40) cv2.imshow("Shifted2", shifted) # 逆时针旋转45度 rotated = rotate(im, 45) cv2.imshow("rotated1", rotated) # 顺时针旋转90度 rotated = rotate(im, -90) cv2.imshow("rorated2", rotated) cv2.waitKey() cv2.destroyAllWindows()
#### 3)图像缩放
#### 4)图像裁剪
#### 5)图像相加
#### 6)图像相减
# 图像缩放示例 import numpy as np import cv2 im = cv2.imread("../data/Linus.png") cv2.imshow("src", im) h, w = im.shape[:2] # 获取图像尺寸 dst_size = (int(w/2), int(h/2)) # 缩放目标尺寸,宽高均为原来1/2 resized = cv2.resize(im, dst_size) # 执行缩放 cv2.imshow("reduce", resized) dst_size = (200, 300) # 缩放目标尺寸,宽200,高300 method = cv2.INTER_NEAREST # 最邻近插值 resized = cv2.resize(im, dst_size, interpolation=method) # 执行缩放 cv2.imshow("NEAREST", resized) dst_size = (200, 300) # 缩放目标尺寸,宽200,高300 method = cv2.INTER_LINEAR # 双线性插值 resized = cv2.resize(im, dst_size, interpolation=method) # 执行缩放 cv2.imshow("LINEAR", resized) cv2.waitKey() cv2.destroyAllWindows()
#### 4)图像裁剪
import numpy as np import cv2 # 图像随机裁剪 def random_crop(im, w, h): start_x = np.random.randint(0, im.shape[1]) # 裁剪起始x像素 start_y = np.random.randint(0, im.shape[0]) # 裁剪起始y像素 new_img = im[start_y:start_y + h, start_x: start_x + w] # 执行裁剪 return new_img # 图像中心裁剪 def center_crop(im, w, h): start_x = int(im.shape[1] / 2) - int(w / 2) # 裁剪起始x像素 start_y = int(im.shape[0] / 2) - int(h / 2) # 裁剪起始y像素 new_img = im[start_y:start_y + h, start_x: start_x + w] # 执行裁剪 return new_img im = cv2.imread("../data/banana_1.png", 1) new_img = random_crop(im, 200, 200) # 随机裁剪 new_img2 = center_crop(im, 200, 200) # 中心裁剪 cv2.imshow("orig", im) cv2.imshow("random_crop", new_img) cv2.imshow("center_crop", new_img2) cv2.waitKey() cv2.destroyAllWindows()
#### 5)图像相加
# 图像相加示例 import cv2 a = cv2.imread("../data/lena.jpg", 0) b = cv2.imread("../data/lily_square.png", 0) dst1 = cv2.add(a, b) # 图像直接相加,会导致图像过亮、过白 # 加权求和:addWeighted # 图像进行加权和计算时,要求src1和src2必须大小、类型相同 dst2 = cv2.addWeighted(a, 0.6, b, 0.4, 0) # 最后一个参数为亮度调节量 cv2.imshow("a", a) cv2.imshow("b", b) cv2.imshow("dst1", dst1) cv2.imshow("dst2", dst2) cv2.waitKey() cv2.destroyAllWindows()
#### 6)图像相减
# 图像相减运算示例 import cv2 a = cv2.imread("../data/3.png", 0) b = cv2.imread("../data/4.png", 0) dst = cv2.subtract(a, b) # 两幅图像相减,是求出图像的差异 cv2.imshow("a", a) cv2.imshow("b", b) cv2.imshow("dst1", dst) cv2.waitKey() cv2.destroyAllWindows()
#### 7)透视变换
#### 8)图像腐蚀
#### 9)图像膨胀 (根据原图像的形状,向外进行扩充)
#### 10)图像开运算 (先腐蚀后膨胀)
# 透视变换 import cv2 import numpy as np img = cv2.imread('../data/pers.png') rows, cols = img.shape[:2] print(rows, cols) pts1 = np.float32([[58, 2], [167, 9], [8, 196], [126, 196]])# 输入图像四个顶点坐标 pts2 = np.float32([[16, 2], [167, 8], [8, 196], [169, 196]])# 输出图像四个顶点坐标 # 生成透视变换矩阵 M = cv2.getPerspectiveTransform(pts1, # 输入图像四个顶点坐标 pts2) # 输出图像四个顶点坐标 print(M.shape) # 执行透视变换,返回变换后的图像 dst = cv2.warpPerspective(img, # 原始图像 M, # 3*3的变换矩阵 (cols, rows)) # 输出图像大小 # 生成透视变换矩阵 M = cv2.getPerspectiveTransform(pts2, # 输入图像四个顶点坐标 pts1) # 输出图像四个顶点坐标 # 执行透视变换,返回变换后的图像 dst2 = cv2.warpPerspective(dst, # 原始图像 M, # 3*3的变换矩阵 (cols, rows)) # 输出图像大小 cv2.imshow("img", img) cv2.imshow("dst", dst) cv2.imshow("dst2", dst2) cv2.waitKey() cv2.destroyAllWindows()
#### 8)图像腐蚀
# 图像腐蚀 import cv2 import numpy as np # 读取原始图像 im = cv2.imread("../data/5.png") cv2.imshow("im", im) # 腐蚀 kernel = np.ones((3, 3), np.uint8) # 用于腐蚀计算的核 erosion = cv2.erode(im, # 原始图像 kernel, # 腐蚀核 iterations=3) # 迭代次数 cv2.imshow("erosion", erosion) cv2.waitKey() cv2.destroyAllWindows()
#### 9)图像膨胀 (根据原图像的形状,向外进行扩充)
# 图像膨胀 import cv2 import numpy as np # 读取原始图像 im = cv2.imread("../data/6.png") cv2.imshow("im", im) # 膨胀 kernel = np.ones((3, 3), np.uint8) # 用于膨胀计算的核 dilation = cv2.dilate(im, # 原始图像 kernel, # 膨胀核 iterations=5) # 迭代次数 cv2.imshow("dilation", dilation) cv2.waitKey() cv2.destroyAllWindows()
#### 10)图像开运算 (先腐蚀后膨胀)
# 开运算示例 import cv2 import numpy as np # 读取原始图像 im1 = cv2.imread("../data/7.png") im2 = cv2.imread("../data/8.png") # 执行开运算 k = np.ones((10, 10), np.uint8) r1 = cv2.morphologyEx(im1, cv2.MORPH_OPEN, k) r2 = cv2.morphologyEx(im2, cv2.MORPH_OPEN, k) cv2.imshow("im1", im1) cv2.imshow("result1", r1) cv2.imshow("im2", im2) cv2.imshow("result2", r2) cv2.waitKey() cv2.destroyAllWindows()
#### 11)图像闭运算 (先膨胀后腐蚀)
# 闭运算示例 import cv2 import numpy as np # 读取图像 im1 = cv2.imread("../data/9.png") im2 = cv2.imread("../data/10.png") # 闭运算 k = np.ones((8, 8), np.uint8) r1 = cv2.morphologyEx(im1, cv2.MORPH_CLOSE, k, iterations=2) r2 = cv2.morphologyEx(im2, cv2.MORPH_CLOSE, k, iterations=2) cv2.imshow("im1", im1) cv2.imshow("result1", r1) cv2.imshow("im2", im2) cv2.imshow("result2", r2) cv2.waitKey() cv2.destroyAllWindows()