准备工作:
1.找一张图片
2.准备python运行环境,并导入库,pip install opencv-python
读取文件,并打印维度
import cv2 #为什么是cv2不是cv呢,这个2指的是c++的api,是为了兼容老板,cv指的就是c,而不是版本的意思,不要换成cv3
path = r'./media/1.jpeg'
print(cv2.getVersionString())
image = cv2.imread(path)
print(image.shape) #输出(720, 1280, 3) 前面代表图片横行和纵列,3表示图片三原色彩色通道
然后把读取到的文件显示到一个窗口
cv2.imshow("image", image) #此时如果是加这个窗口会直接闪没
cv2.waitKey() #加上这个,按任意键关闭窗口(这个函数会窗体暂停,并等待键盘输入)
图像彩色通道学习
任何颜色都是由RGB按一定比例混合而成的,对openCV来说,存储一张彩色图片,等同于存储三张彩色图片,被存储在opencv的第三个维度上(此图来自b站)
opencv对颜色的顺序存储是BGR,与常见的RGB相反,当显示器要渲染一张彩色图片,计算机会依次取出图像数据中的三张灰色图,再把它们分别投影到显示器的蓝,绿红的LED芯片上,从而渲染出彩色画面,如下代码将显示下面四个图片
cv2.imshow("image", image)
cv2.imshow("blue", image[:, :, 0])
cv2.imshow("green", image[:, :, 1])
cv2.imshow("red", image[:, :, 2])
opencv还提供一种彩色图像的灰度变化算法,可以把三个彩色通道的图像做
平方和加权平均,如下,是BRG三原色的平均,他也描述了,图片的明暗分布,如果在计算机视觉中,通常把这个变换后的图像gray称为灰度图,可以基于灰度图,做不同算法,比如黑片检测图片相似度检测等等
图像的裁剪
crop = image[10:170, 40:200]
# 将图片裁剪
绘制功能
OpenCV的图像数据,实际是numpy数组数据结构,所以可以直接使用numpy创建一个黑色画布
image = numpy.zeros([300, 300, 3], dtype=numpy.uint8)
# 灰度的数值类型是无符号八位整数
是一个300*300的黑色画布
画一条线段
cv2.line(image, (100, 100), (200, 250), (255,0,255), 2)
# 线段起点坐标(100, 100),终点坐标(200, 250),线段颜色(255,0,255),线段粗细为两个像素
加一个矩形
cv2.rectangle(image, (30,100), (60, 150), (0,255,33), 2)
#矩形框第一个顶点坐标30,100。对角对标60,150。颜色为(0,255,33),粗细是两个像素
加一个圆
cv2.circle(image, (150,100), 20, (0,12,155), 3)
#圆心坐标,圆的半径,颜色,粗细
绘制字符串
cv2.putText(image, "Hello OpenCV", (100,50) ,0,1,(11,144,67),1,2)
# 文字,坐标,字体需序号(0位默认字体),缩放系数,颜色,粗细,线条类型(1为实线)
# 附加:putText函数不能使用任意字体
均值滤波–可以去噪点,但是会破坏图像细节
# 高斯滤波器,高斯内核为5像素,sigema x设置为0,意思是sigema由内核大小来决定
gauss = cv2.GaussianBlur(image, (5, 5), 0)
cv2.imshow("image", image)
cv2.imshow("gauss", gauss)
如下gauss就比原图噪点要少了
中值滤波器
image = cv2.imread(path)
median = cv2.medianBlur(image, 5) # 设置内核为5个像素
cv2.imshow("image", image)
cv2.imshow("median", median)
cv2.waitKey()
如下
合在一起就是
image = cv2.imread(path)
gauss = cv2.GaussianBlur(image, (5, 5), 0) # 高斯滤波器,高斯内核为5像素,sigema x设置为0,意思是sigema由内核大小来决定
median = cv2.medianBlur(image, 5) # 设置内核为5个像素
cv2.imshow("image", image)
cv2.imshow("gauss", gauss)
cv2.imshow("median", median)
cv2.waitKey()
如下
图像特征的提取—转角特征
image = cv2.imread(path)
gary = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 把彩色图像转换为灰度图
corners = cv2.goodFeaturesToTrack(gary, 500, 0.1, 10) # 最多返回500个点,点的质量优于0。1,特征点之间的距离大于10个像素
for corner in corners: # 遍历,把点标记出来
x, y = corner.ravel()
cv2.circle(image, (int(x), int(y)), 3, (255, 0, 255), -1)
cv2.imshow("image", image)
cv2.waitKey()
opencv的模板匹配学习 — 即,找图片中对应图片
image = cv2.imread(path)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 转换为灰度图片
template = gray[273:370, 392:492] #截图这个位置是一个葡萄
match = cv2.matchTemplate(gray, template, cv2.TM_CCOEFF_NORMED) # 标准相关匹配算法,把检测图片和被检测图片都标准化,再来计算匹配度,这样保证不受光照的影响
locations = numpy.where(match >= 0.9) # 找出匹配系数大于0.9的匹配点
w, h = template.shape[0:2] # 计算模板图案的长和宽
for p in zip(*locations[::-1]): # 遍历每一个匹配点,画出矩形框标记
x1, y1 = p[0], p[1]
x2, y2 = x1 + w, y1 + h
cv2.rectangle(image, (x1,y1),(x2,y2), (0,0,0),2)
cv2.imshow("image", image)
cv2.imshow("temp", template)
cv2.waitKey()
如下所有葡萄都用黑线框起来了, 在这里,如果图案一样,但是比截取的图片小和大的图案都不会被匹配上,也就是对大小敏感,如果想要不同大小的图都匹配到,可以放大缩小图像,匹配多次
图像梯度算法,特征点提取和匹配都使用了图像梯度, 就是图像的明暗变化,可以分别计算图像沿水平和垂直方向的明暗变化,再取这两个变化的平方和,就得到了梯度,可以类比地理中的梯度