Open CV 图像处理作业

Open CV 图像处理作业

0. 环境

代码很多都参考了 小白YouCans ,感谢这位博主。
环境使用 Kaggle 里免费建立的 Notebook。

%matplotlib inline
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

因为使用的是 Notebook,如果使用 cv.imshow(img) ,在 Pycharm 上运行会弹出一个窗口显示图片,但是在 Notebook 中会报错,所以使用 %matplotlib inlineplt.imshow(img) 可以让代码块执行后直接在下面输出图像。

添加图片数据集:

按照 URL 搜索,Add 添加即可,数据集地址:https://www.kaggle.com/datasets/xenxiou/common-pictures-of-opencv

1. 文件操作

实现打开一幅图片,完成对图像数据的读取,存储和显示。

1.1 读取图片

cv.imread 默认读入的矩阵是 BGR 格式的,定义一个函数转换为 RGB 格式:

def cv_imread(path):
    img = cv.imread(path)
    return cv.cvtColor(img, cv.COLOR_BGR2RGB)

1.2 显示图片

img_path = '/kaggle/input/common-pictures-of-opencv/LenaRGB.bmp'
img = cv_imread(img_path)
plt.imshow(img)

1.3 存储图片

cv.imwrite('./test.png', img)

2. 几何变换

图像的几何变换包括实现对图像数据的图像剪切、图像平移、图像旋转、图像镜像、图像的缩放,图像仿射功能。

https://zhuanlan.zhihu.com/p/80852438

2.1 图像剪切

imgCrop = img[150:400, 150:350]
plt.imshow(imgCrop)

2.2 图像平移

# 图像平移
rows, cols, ch = img.shape

dx, dy = 100, 50  # dx=100 向右偏移量, dy=50 向下偏移量
MAT = np.float32([[1, 0, dx], [0, 1, dy]])  # 构造平移变换矩阵   
dst = cv.warpAffine(img, MAT, (rows, cols), borderValue=(255,255,255))  # 设置白色填充
plt.imshow(dst)

2.3 图像旋转

theta = np.pi / 12  # 顺时针旋转角度
cosTheta = np.cos(theta)
sinTheta = np.sin(theta)
MAT = np.float32([[cosTheta, -sinTheta, 0], [sinTheta, cosTheta, 0]])  # 构造旋转变换矩阵
dst = cv.warpAffine(img, MAT, (cols, rows), borderValue=(255,255,255))
plt.imshow(dst)

2.4 图像镜像

imgFlip1 = cv.flip(img, 0)  # 垂直翻转
imgFlip2 = cv.flip(img, 1)  # 水平翻转
imgFlip3 = cv.flip(img, -1)  # 水平和垂直翻转

tmp = np.hstack((imgFlip1, imgFlip2, imgFlip3))
plt.imshow(tmp)

2.5 图像缩放

imgZoom = cv.resize(img, (300, 200))
plt.imshow(imgZoom)

3. 图像处理

图像的基本处理包括实现图像灰度化、图像的二值化、图像的亮度和对比度的调整、图像的离散傅里叶变换功能。

3.1 图像灰度化

#  img2 = cv.imread(imgFile, flags=0)  # flags=0 读取为灰度图像
imgGray = cv.cvtColor(img, cv.COLOR_RGB2GRAY)
plt.imshow(imgGray)

3.2 图像二值化

# 自适应二值化
dst = cv.adaptiveThreshold(imgGray,255,cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY,11,2)
plt.imshow(dst)

# 给定值二值化
_, dst = cv.threshold(imgGray, 127, 255, cv.THRESH_BINARY)  # 转换为二值图像, thresh=127
plt.imshow(dst)

3.3 图像的亮度调整和对比度

OpenCV中亮度和对比度应用这个公式来修改:Open CV 图像处理作业,其中:Open CV 图像处理作业 常称为增益与偏置值,分别控制图片的对比度和亮度。

img_hsv = cv.cvtColor(img, cv.COLOR_RGB2HSV)
h,s,v = cv.split(img_hsv)

# 增加图像亮度
v1 = np.clip(cv.add(1*v,30),0,255)

# 增加图像对比度
v2 = np.clip(cv.add(2*v,0),0,255)

img1 = np.uint8(cv.merge((h,s,v1)))
img1 = cv.cvtColor(img1,cv.COLOR_HSV2RGB)

img2 = np.uint8(cv.merge((h,s,v2)))
img2 = cv.cvtColor(img2,cv.COLOR_HSV2RGB)

tmp = np.hstack((img, img1, img2))
plt.imshow(tmp)

3.4 图像的离散傅里叶变换

# np.float32()将图像数据转换成float32 然后进行傅里叶变换cv2.dft()
dft = cv.dft(np.float32(imgGray),flags=cv.DFT_COMPLEX_OUTPUT)
# 将低频信息转换至图像中心
dft_shift = np.fft.fftshift(dft)
# 傅里叶变换后的数据是由实部和虚部构成的,需要进行转换成图像格式才能显示(0,255)
# cv2.magnitude()将实部和虚部转换为实部,乘以20将结果放大
magnitude_spectrum = 20 * np.log(cv.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))
plt.imshow(magnitude_spectrum)

4. 图像边缘检测

图像边缘检测包括实现Canny算法边缘检测,Sobel算法边缘检测,Scharr滤波器算法边缘检测功能。

4.1 Canny 算法边缘检测

img_gs = cv.GaussianBlur(img,(3,3),0)
canny = cv.Canny(img_gs, 50, 150)

plt.imshow(canny)

4.2 Sobel 算法边缘检测

kernSobelX = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])  # SobelX kernel
kernSobelY = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]])  # SobelY kernel
imgSobelX = cv.filter2D(img, -1, kernSobelX, borderType=cv.BORDER_REFLECT)
imgSobelY = cv.filter2D(img, -1, kernSobelY, borderType=cv.BORDER_REFLECT)

SobelX = cv.Sobel(img, cv.CV_16S, 1, 0)  # 计算 x 轴方向
SobelY = cv.Sobel(img, cv.CV_16S, 0, 1)  # 计算 y 轴方向
absX = cv.convertScaleAbs(SobelX)  # 转回 uint8
absY = cv.convertScaleAbs(SobelY)  # 转回 uint8
SobelXY = cv.addWeighted(absX, 0.5, absY, 0.5, 0)  # 用绝对值近似平方根

tmp = np.hstack((SobelX, SobelY, SobelXY))
plt.imshow(tmp)

4.3 Scharr滤波器算法边缘检测

# 使用函数 filter2D 实现 Scharr 算子
kernScharrX = np.array([[-3, 0, 3], [-10, 0, 10], [-3, 0, 3]])  # ScharrX kernel
kernScharrY = np.array([[-3, 10, -3], [0, 0, 10], [3, 10, 3]])  # ScharrY kernel

# 使用 cv.Scharr 实现 Scharr 算子
ScharrX = cv.Scharr(img, cv.CV_16S, 1, 0)  # 计算 x 轴方向
ScharrY = cv.Scharr(img, cv.CV_16S, 0, 1)  # 计算 y 轴方向
absX = cv.convertScaleAbs(ScharrX)  # 转回 uint8
absY = cv.convertScaleAbs(ScharrY)  # 转回 uint8
ScharrXY = cv.addWeighted(absX, 0.5, absY, 0.5, 0)  # 用绝对值近似平方根

tmp = np.hstack((ScharrX, ScharrY, ScharrXY))
plt.imshow(tmp)

5. 图像运算

图像运算包括实现对图像的代数运算(加,减,乘,除)和逻辑运算(与,或,补)功能。
再导入一张图片:

img2 = cv_imread('/kaggle/input/common-pictures-of-opencv/BaboonRGB.bmp')

plt.imshow(img2)

5.1 代数运算

加减乘除:

tmp = np.hstack((cv.add(img, img2), 
                 cv.subtract(img,img2), 
                 cv.multiply(img,img2), 
                 cv.divide(img,img2)))
plt.imshow(tmp)

5.2 逻辑运算

与补非:

tmp = np.hstack((cv.bitwise_and(img,img2), 
                 cv.bitwise_or(img,img2), 
                 cv.bitwise_not(img)))
plt.imshow(tmp)

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2022年5月12日
下一篇 2022年5月12日

相关推荐