哔哩哔哩:《黑马程序员人工智能教程_10小时学会图像处理OpenCV入门教程》
图:物体反射或透射光的分布
像:人的视觉系统所接受的图在人脑中所形成的印象或认识
模拟图像:连续存储的数据
数字图像:分级存储的数据
位数:图像的表示,常见是8位
分类:二值图像、灰度图像和彩色图像
OpenCV是一款由Intel公司俄罗斯团队发起并参与和维护的一个计算机视觉处理开源软件库,支持与计算机视觉和机器学习相关的众多算法。
参考:https://www.jianshu.com/p/453184d63fb7
pip install opencv-python==3.4.2.17
conda install opencv-python==3.4.2.17
使用anaconda安装出现:PackagesNotFoundError: The following packages are not available from current channels
使用pip安装包时,出现Cannot unpack file xxx的问题的解决以及pip安装速度慢或出现readtime out问题的解决。
import cv2
lena = cv2.imread('1.jpg')
cv2.imshow('image',lena)
cv2.waitKey(0)
pip install opencv-contrib-python==3.4.2.17
其中core、highgui、imgproc是最基础的模块,介绍如下:
总结:
opencv的模块:
core:最核心的数据结构
highgui:视频与图像的读取、显示、存储
imgproc:图像处理的基础方法
features2d:图像特征以及特征匹配
主要内容:
# opencv显示
import cv2
img = cv2.imread('1.jpg',0)
cv2.imshow('image',img)
cv2.waitKey(0)
# matplotlib显示
#img是以BGR通道顺序存储,而plt是以RGB的顺序,这里是要实现通道顺序转换
# plt.show(img[:,:,::-1])
import cv2 as cv
import matplotlib.pyplot as plt
# 1.读取图像
img = cv.imread('1.jpg',0)
# 2.显示图像
# 2.1 opencv显示
# cv.imshow('image',img)
# cv.waitKey(0)
# 2.2 matplotlib显示
plt.imshow(img,cmap=plt.cm.gray) #读取灰度图
plt.show()
# 3.图像保存
cv.imwrite('2.png',img)
生成一个全黑的图像,然后在里面绘制图像并添加文字
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 1.创建一个空白的图像
img = np.zeros((512,512,3),np.uint8)
# 2.绘制图形
cv.line(img,(0,0),(511,511),(255,0,0),5)
cv.rectangle(img,(384,0),(510,128),(0,255,0),3)
cv.circle(img,(447,63),63,(0,0,255),-1)
font = cv.FONT_HERSHEY_SIMPLEX
cv.putText(img,'OpenCV',(10,500),font,4,(255,255,255),2,cv.LINE_AA)
# 3.图像展示
plt.imshow(img[:,:,::-1])
plt.title('Result')
plt.xticks([]),plt.yticks([]) #将图的横纵坐标刻度设置为空
plt.show()
import cv2 as cv
img = cv.imread('1.jpg')
# 获取某个像素点的值
px1 = img[100,100]
# 仅获取蓝色通道的强度值
blue = img[100,100,0]
# 修改某个位置的像素值
img[100,100] = [255,255,255]
# print(img.shape)
# print(img.dtype)
# print(img.size)
# 通道拆分
b,g,r = cv.split(img)
# 通道合并
img = cv.merge((b,g,r))
opencv有150多种颜色空间转换的方法。最广泛使用的转换方法有两种,BGR<=>Gray 和BGR<=>HSV
既然前面已经是转为灰度图了,为什么还是需要cmap参数呢?
不加cmap的话,还是不够灰色的,求解!!!
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
plt.imshow(gray,cmap=plt.cm.gray)
plt.show()
hsv = cv.cvtColor(img,cv.COLOR_BGR2HSV)
plt.imshow(hsv)
plt.show()
import cv2 as cv
import numpy as np
x = np.uint8([250])
y = np.uint8([10])
print(cv.add(x,y)) # 250+10 = 260 =>255
print(x+y) # 250+10 = 260 % 256 => 4
两个大小不一样的图像相加:
(参考:用OpenCV合成PNG和JPG图片)
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img1 = cv.imread('1.jpg',1)
img2 = cv.imread('rabbit.png',1)
width = int((1440 - 1090) / 2)
height = int((1080 - 720) / 2)
img1 = img1[height:height + 720, width:width + 1090]
img_res = cv.add(img1,img2)
plt.imshow(img_res)
plt.show()
通过cv.add(img1,img2)
img1+img2—直接相加
其实也是加法,但是两者的权重不同,给人一种混合的或者透明的感觉。图像混合的计算公式如下:
g(x) = (1-α)f0(x) + αf1(x)
通过修改α的值0 ==> 1,可以实现炫酷的组合。
dst = k1img1 + k2img2 + b
cv.addWeighted(img1,k1,img2,k2,b)
import cv2 as cv
import matplotlib.pyplot as plt
img = cv.imread('1.jpg')
rows,cols = img.shape[:2]
res1 = cv.resize(img,(2*rows,2*cols))
print(res1.shape)
res2 = cv.resize(img,None,fx=0.5,fy=0.5)
print(res2.shape)
# 2、图像平移
M = np.float32([[1,0,100],[0,1,50]])
img = cv.imread('1.jpg')
rows,cols = img.shape[:2]
res = cv.warpAffine(img,M,(cols,rows))
plt.imshow(res[:,:,::-1])
plt.show()
除了改变图像内像素点的位置,还要修正原点的位置(因为原点的位置跟着动了)
# 3、图像旋转
# 读取图像
img = cv.imread('1.jpg')
# 图像旋转
# (1)获取宽度(列数)、高度(行数)
rows,cols = img.shape[:2]
# (2)生成旋转矩阵
# (cols/2,rows/2):指定旋转中心
# 45:旋转角度
# 1:缩放比例,1代表原大小
M = cv.getRotationMatrix2D((cols/2,rows/2),45,1)
# (3)旋转变换
dst = cv.warpAffine(img,M,(cols,rows))
# 3 图像展示
fig,axes = plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img[:,:,::-1])
axes[0].set_title('Start')
axes[1].imshow(dst[:,:,::-1])
axes[1].set_title('Process')
plt.show()
待求解矩阵中有六个未知量,我们给定前后各三组点,这样就得到六个方程,就可以解方程了。
# 图像仿射变换
# 1、读取图像
img = cv.imread('1.jpg')
# 2、仿射变换
rows,cols = img.shape[:2]
# 2.1 创建变换矩阵
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[100,100],[200,50],[100,250]])
M = cv.getAffineTransform(pts1,pts2)
# 2.2 完成仿射变换
dst = cv.warpAffine(img,M,(cols,rows))
# 3、图像显示
fig,axes = plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img[:,:,::-1])
axes[0].set_title('Start')
axes[1].imshow(dst[:,:,::-1])
axes[1].set_title('Process')
plt.show()
透射变换是指利用透视中心、像点、目标点三点共线的条件,按透视旋转定律使承影面(透视面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光线束,仍能保持承影面上投影几何图形不变的变换。
经过之前仿射变换介绍为什么要三组点(因为有六个未知数,需要留个方程),那现在是八个未知数,因此需要四组点了。
# 图像透射变换
# 1、读取图像
img = cv.imread('1.jpg')
# 2、透射变换
rows,cols = img.shape[:2]
# 2.1 创建变换矩阵
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[100,145],[300,100],[80,290],[310,300]])
T = cv.getPerspectiveTransform(pts1,pts2)
# 2.2 完成仿射变换
dst = cv.warpPerspective(img,T,(cols,rows))
# 3、图像显示
fig,axes = plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img[:,:,::-1])
axes[0].set_title('Start')
axes[1].imshow(dst[:,:,::-1])
axes[1].set_title('Process')
plt.show()
# 图像金字塔
# 1 图像读取
img = cv.imread('rabbit.png')
# 2 进行图像采样
up_img = cv.pyrUp(img)
down_img = cv.pyrDown(img)
# 3 图像显示
cv.imshow('up_img',up_img)
cv.imshow('img',img)
cv.imshow('down_img',down_img)
cv.waitKey(0)