计算机视觉:OpenCV入门

首先先创建一个文件夹,命名为OpenCV。命名为别的名字也可以,但后面的代码你可能要修改。

再新建一个1.1py文件。main.py是创建好文件夹就有的了,不予理会。

再找一张图片命名为1.1.jpg放进文件夹。

一、图像处理

1.1  读取图像

# 读取图像
import cv2

image = cv2.imread("1.1.jpg")
print(image)

imread()函数里传入字符串,字符串是文件名,可设置为绝对路径来自内容根的路径

print()函数打印输出图像的矩阵值。

1.2  显示图像

# 读取图像
import cv2

image = cv2.imread("1.1.jpg")         # 读取图片
cv2.imshow("lovely", image)           # 显示图片,命名为lovely,image是待显示的图片
cv2.waitKey()                         # 按下任何键盘按键后
cv2.destroyAllWindows()               # 关闭所有窗口

waitKey()函数:可以传入参数,如1000 就是 1000ms=1s,8000就是8s。 waitKey(1000)

1.3  保存图像

# 读取图像
import cv2

image = cv2.imread("1.1.jpg")          # 读取图片
 # 保存图片,命名为lovely,image是待保存的图片
cv2.imwrite("E:\桌面\Algo\OpenCV\lovely.jpg", image)  

1.4  色彩空间

  GRAY色彩空间指的是灰度图。像素数组中,从0到255代表256个级别,0~255表示不同亮度(色彩的深浅程度),即每个数值表示从黑变白的颜色深浅程度。0表示纯黑色,255表示纯白色,数值由小到大,从黑变白。

# 读取图像
import cv2


image = cv2.imread("1.1.jpg")                      # 读取图片
cv2.imshow("1.1", image)                           # 显示图片
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)   # 将图片由BGR转换为GRAY 
cv2.imshow("Gray", gray_image)                     # 显示图片
cv2.waitKey()
cv2.destroyAllWindows()

cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)函数

第一个参数为待转换的图片,第二个为转换模式。

1.5   HSV色彩空间

BGR色彩空间是Blue、Green、Red。而HSV色彩空间是色调、饱和度、亮度。

色调(H)是指光的颜色。在OpenCV中,色调在[0, 180]内取值,如红 黄 绿 蓝 分别为 0,30,60,120。

饱和度(S)是指色彩的深浅。在OpenCV中,饱和度在区间[0,255]内取值。饱和度为0,就变成了灰度图。

亮度(V)是指光的明暗。在OpenCV中,亮度在区间[0,255]内取值。数值越大,图像越亮。亮度值为0时,图像呈纯黑色。

# 读取图像
import cv2


image = cv2.imread("1.1.jpg")            # 读取图片
cv2.imshow("1.1", image)                 # 显示图片
hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)   # 将图片由BGR转换为HSV
cv2.imshow("HSV",hsv_image)               # 显示图片
cv2.waitKey()
cv2.destroyAllWindows()

cv2.cvtColor(image, cv2.COLOR_BGR2HSV)函数

cv2.cvtColor(image, cv2.COLOR_RGB2HSV)函数           这两个都可以,自行更换。

二、绘图

2.1 绘制线段

cv2.line(img, pt1, pt2, color, thickness) 函数

pt1:线段的起点坐标

pt2:线段的终点坐标

color:绘制线段时的线条颜色

thicness:绘制线段时的线条宽度

# 读取图像
import numpy as np
import cv2

# 创建一个大小300*300,具有三个颜色空间RGB的画布,以unin8类型存储
canvas = np.zeros((300, 300, 3), np.uint8)
# 在画布上,绘制一个起点坐标为(50, 50), 终点坐标为(250, 50), 蓝色的, 线条宽度为5的线段
canvas = cv2.line(canvas,(50, 50), (250, 50), (255, 0, 0), 5)

canvas = cv2.line(canvas,(50, 150), (250, 150), (0, 255, 0), 10)

canvas = cv2.line(canvas,(50, 250), (250, 250), (0, 0, 255), 15)

canvas = cv2.line(canvas,(150, 50), (150, 250), (0, 255, 255), 20)

cv2.imshow("Lines", canvas)
cv2.waitKey()
cv2.destroyAllWindows()

2.2  绘制矩形

# 读取图像
import numpy as np
import cv2

# 创建一个大小300*300,具有三个颜色空间RGB的画布,以unin8类型存储
canvas = np.zeros((300, 300, 3), np.uint8)
# 在画布上,绘制一个起点坐标为(50, 50), 终点坐标为(250, 150), 青色的, 线条宽度为20的矩形
canvas = cv2.rectangle(canvas,(50, 50), (250, 150), (255, 255, 0), 20)

cv2.imshow("Rectangle", canvas)
cv2.waitKey()
cv2.destroyAllWindows()

注:

rectangle函数线条宽度参数可写成 -1,就变成画实心的矩形了。

绘制正方形也一样,如画一个(50, 50)、(250, 250)的正方形,改一下起点终点坐标就可以画了。

2.3  绘制圆形

# 读取图像
import numpy as np
import cv2

# 创建一个大小300*300,具有三个颜色空间RGB的画布,以unin8类型存储
canvas = np.zeros((300, 300, 3), np.uint8)
# 在画布上,绘制一个圆心坐标为(150, 150), 半径为40, 青色的, 线条宽度为20的矩形
canvas = cv2.circle(canvas,(150, 150), 40 , (255, 255, 0), 20)

cv2.imshow("Rectangle", canvas)
cv2.waitKey()
cv2.destroyAllWindows()

circle(canvas,圆心坐标,半径,颜色,线条宽度) 函数  

线条宽度设置为 -1,即可画实心圆。

2.4  绘制文字

# 读取图像
import numpy as np
import cv2

# 创建一个大小300*300,具有三个颜色空间RGB的画布,以unin8类型存储
canvas = np.zeros((100, 500, 3), np.uint8)
# 在画布上, 绘制一段文字为(10, 70), 字体样式为FONT_HERSHEY_TRIPLEX,
# 字体大小为2, 绿色的, 线条宽度为5的矩形
canvas = cv2.putText(canvas,"Almost Lover", (10, 70) , cv2.FONT_HERSHEY_TRIPLEX, 2, (0, 255, 0), 5)

cv2.imshow("Text", canvas)
cv2.waitKey()
cv2.destroyAllWindows()

结果:       

putText()函数的参数分别为 1要绘制的图像(画布)  2要绘制的文字  3字体样式 

4字体大小  5颜色  6线条宽度

其中3字体样式有多种,可自行百度搜索。

三、阈值

阈值化的作用:使图像的轮廓更加鲜明

3.1  阈值处理函数

threshold()函数用于对图像进行阈值处理。

retval, dst = cv2.threshold(image, thresh, maxval, type)

返回值  retval:处理时所采用的阈值  dst:阈值处理后的图像

参数 :

image:图像 

thresh:阈值 

maxval:阈值处理采用的最大值 

type:阈值处理类型

常用的阈值处理类型有:

cv2.THRESH_BINARY             二值化阈值处理

cv2.THRESH_BINARY_INV     反二值化阈值处理

cv2.THRESH_TOZERO           低于阈值零处理

cv2.THRESH_TOZERO_INV   超出阈值零处理

cv2.THRESH_TRUNC              截断阈值处理

cv2.ADAPTIVE_THRESH_MEAN_C            对一个正方形区域内的像素值进行加权平均

cv2.ADAPTIVE_THRESH_GAUSSIAN_C    按高斯函数一个正方形区域内的像素值进行加权

3.2  二值化处理

二值化处理会使图像仅仅保留两种像素值,意味着所有像素的取值只有两种。

公式:

if 像素值 <= 阈值 :像素值 = 0

if 像素值 > 阈值:像素值 = 最大值

代码:

import cv2
img = cv2.imread("1.1.jpg", 0)
r1, d1 = cv2.threshold(img, 125, 255, cv2.THRESH_BINARY)
cv2.imshow("img", img)
cv2.imshow("d1_THRESH_BINARY", d1)
cv2.waitKey()
cv2.destroyAllWindows()

第三行对应:retval, dst = cv2.threshold(image, thresh, maxval, type) 函数。

反二值化处理就是把cv2.THRESH_BINARY换成cv2.THRESH_BINARY_INV

3.3  零处理

import cv2
img = cv2.imread("1.1.jpg", 0)
r1, d1 = cv2.threshold(img, 125, 255, cv2.THRESH_TOZERO)
cv2.imshow("img", img)
cv2.imshow("d1_THRESH_TOZERO", d1)
cv2.waitKey()
cv2.destroyAllWindows()

主要变化了阈值处理类型type参数。

超出阈值零处理就是把cv2.THRESH_TOZERO换成cv2.THRESH_TOZERO_INV

3.4  截断处理

使图像中大于阈值的像素值变为阈值,小于或等于阈值的像素保持原值不变。

公式:

if 像素值 <= 阈值 :像素值 = 原值

if 像素值 > 阈值:像素值 = 阈值

import cv2
img = cv2.imread("1.1.jpg", 0)
r1, d1 = cv2.threshold(img, 125, 255, cv2.THRESH_TRUNC)
cv2.imshow("img", img)
cv2.imshow("d1_THRESH_TRUNC", d1)
cv2.waitKey()
cv2.destroyAllWindows()

主要变化了阈值处理类型type参数。

截断处理 type参数:cv2.THRESH_TRUNC

3.5  自适应处理

import cv2
img = cv2.imread("1.1.jpg", 0)
r1, d1 = cv2.threshold(img, 125, 255, cv2.ADAPTIVE_THRESH_MEAN_C)
r2, d2 = cv2.threshold(img, 125, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C)

cv2.imshow("img", img)
cv2.imshow("d1_ADAPTIVE_THRESH_MEAN_C", d1)
cv2.imshow("d2_ADAPTIVE_THRESH_GAUSSIAN_C", d2)

cv2.waitKey()
cv2.destroyAllWindows()

参数 cv2.ADAPTIVE_THRESH_MEAN_C  对一个正方形区域内的像素值进行加权平均

参数 cv2.ADAPTIVE_THRESH_GAUSSIAN_C  按高斯函数一个正方形区域内的像素值进行加权

四、几何变换

4.1  缩放

dst = cv2.resize(image, dsize, fx, fy, interpolation)

参数:

image:原始图像

dsize:输出图像的大小,格式为(宽,高)

fx:可选参数。水平方向的缩放比例

fy:可选参数。竖直方向的缩放比例

interpolation:可选参数。缩放的插值方式。

注:实际上dsize和fx,fy都可实现缩放效果

import cv2
img = cv2.imread("1.1.jpg", 0)
dst1 = cv2.resize(img, (400,400))
dst2 = cv2.resize(img, (800,800))

dst3 = cv2.resize(img, None, fx = 1/3, fy = 1/2)
dst4 = cv2.resize(img, None, fx = 2, fy = 2)

cv2.imshow("img", img)
cv2.imshow("dst1", dst1)
cv2.imshow("dst2", dst2)
cv2.imshow("dst3", dst3)
cv2.imshow("dst4", dst4)

cv2.waitKey()
cv2.destroyAllWindows()

注意:由于第二个参数dsize不是可选参数,所以当使用后面的可选参数时一定要对其赋None值,否则会报错。

4.2  翻转

dst = cv2.flip(image, flipCode)

image:原始图像

flipCode:翻转类型参数 0(沿X轴翻转)  正数(沿Y轴翻转)  负数(同时沿X轴、Y轴翻转)

import cv2
img = cv2.imread("1.1.jpg")
dst1 = cv2.flip(img, 0)
dst2 = cv2.flip(img,  1)
dst3 = cv2.flip(img, -1)

cv2.imshow("img", img)
cv2.imshow("dst1", dst1)
cv2.imshow("dst2", dst2)
cv2.imshow("dst3", dst3)

cv2.waitKey()
cv2.destroyAllWindows()

4.3  仿射变换

dst = cv2.warpAffine(image, M, dsize, flags, borderMode, borderValue)

image:原始图像

M:一个两行三列的矩阵,根据此矩阵的值变换原图中的像素位置

dsize:输出图像的尺寸大小

flags:可选参数,插值方式。

borderMode:可选参数,边界类型,建议使用默认值

borderValue:可选参数,边界值,默认为0,建议使用默认值

五、图像运算

5.1  掩膜

英文叫mask,用0值表示被遮盖部分,用255值表示暴露的部分

import cv2
import numpy as np

# 创建宽150,高150,3通道,像素类型为无符号8位数字的零值图像
mask = np.zeros((150, 150, 3), np.uint8)
mask[50:100, 20:80, :] = 255;            # 第50-100行、20-80列改为纯白255像素
cv2.imshow("mask1", mask)       # 显示掩膜

mask[:, :, :] = 255;                    # 全部改为纯白像素
mask[50:100, 20:80, :] = 0;             # 第50-100行、20-80列改为纯黑0像素
cv2.imshow("mask2", mask)      # 显示掩膜

cv2.waitKey()
cv2.destroyAllWindows()

5.2  图像的加法运算

dst = cv2.add(image1, image2, mask, dtype)

image1,image2:第一幅图象,第二幅图像

mask:可选参数,掩膜,建议使用默认值

dtype:可选参数,图像深度,建议使用默认值

import cv2

img = cv2.imread("1.1.jpg")
sum1 = img + img
sum2 = cv2.add(img, img)
cv2.imshow("img", img)
cv2.imshow("sum1", sum1)
cv2.imshow("sum2", sum2)
cv2.waitKey()
cv2.destroyAllWindows()

用 ”+“  运算符的计算结果如果超出255,就会取相加和除以255的余数作为该点像素值,也就是取模运算,这样子超出255的像素值反而变小了。

用add()函数的计算结果如果超出255,就会取255作为该点像素值。

5.3  图形的位运算

按位与运算

import cv2
import numpy as np
 
img = cv2.imread("1.1.jpg")                 # 打开原始图像
mask = np.zeros(img.shape, np.uint8)        # 生成与img大小相同的掩膜图像
mask[120:180, :, :] = 255                   # 生成白色区域掩膜
mask[:, 80:180, :] = 255
bitwise_and = cv2.bitwise_and(img, mask)    # 与运算

cv2.imshow("img", img)                      # 分别打开图像
cv2.imshow("mask", mask)
cv2.imshow("bitwise_and", bitwise_and)
cv2.waitKey()
cv2.destroyAllWindows()

同理,按位或运算将cv2.bitwise_and改成 cv2.bitwise_or 即可。

按位取反运算将将cv2.bitwise_and改成 cv2.bitwise_not 即可。

六、滤波器

滤波器的功能用作图像的平滑处理。

效果:尽可能保留原图像信息,去除图像内噪声、降低细节层次。

dst = cv2.blur(image, ksize, anchor, borderType)

image:原始图像

ksize:滤波核大小,格式为(高度,宽度),一般用等宽高的奇数的滤波核,如(3, 3)

anchor:可选参数,滤波核的锚点,建议使用默认值,可自动计算锚点

borderType:可选参数,边界样式。

6.1  均值滤波器

import cv2

img = cv2.imread("1.1.jpg")

dst1 = cv2.blur(img, (3, 3))
dst2 = cv2.blur(img, (5, 5))
dst3 = cv2.blur(img, (7, 7))

cv2.imshow("img", img)
cv2.imshow("3*3", dst1)
cv2.imshow("5*5", dst2)
cv2.imshow("7*7", dst3)

cv2.waitKey()
cv2.destroyAllWindows()

6.2  中值滤波器

dst = cv2.medianBlur(image, ksize)

image:原始图像

ksize:滤波核的边长,必须是大于1的奇数,该函数会根据此边长自动创建一个正方形的滤波核

import cv2

img = cv2.imread("1.1.jpg")

dst1 = cv2.medianBlur(img, 3)
dst2 = cv2.medianBlur(img, 5)
dst3 = cv2.medianBlur(img, 9)

cv2.imshow("img", img)
cv2.imshow("3", dst1)
cv2.imshow("5", dst2)
cv2.imshow("9", dst3)

cv2.waitKey()
cv2.destroyAllWindows()

注意 cv2.medianBlur(image, ksize)的ksize参数格式 !

6.3  高斯滤波器

dst = cv2.GaussianBlur (image, ksize, sigmaX, sigmaY, borderType)

image:原始图像

ksize:滤波核大小。格式(宽, 高)必须是奇数,如(3, 3)

sigmaX:卷积核水平方向的标准差                 sigmaY:卷积核垂直方向的标准差

修改sigmaX和sigmaY都会改变卷积核的权重比例。如果不明白高斯滤波器设计原理,可直接将这两个值设置为0。 方法会自动计算合适的权重比例。

borderType:可选参数,边界样式,建议使用默认值。 

import cv2

img = cv2.imread("1.1.jpg")

dst1 = cv2.GaussianBlur(img, (3,3), 0 ,0)
dst2 = cv2.GaussianBlur(img, (9, 9), 0, 0)
dst3 = cv2.GaussianBlur(img, (15, 15), 0, 0)

cv2.imshow("img", img)
cv2.imshow("5*5", dst1)
cv2.imshow("9*9", dst2)
cv2.imshow("15*15", dst3)

cv2.waitKey()
cv2.destroyAllWindows()

6.4  双边滤波器

由于均值滤波、中值滤波、高斯滤波都会使整幅图像变得平滑,而图像中的边界会变得模糊。

双边滤波器可更加有效的保护边界信息的滤波操作。

dst = cv2.bilateralFilter(image,d,sigmaColor,sigmaColor,sigmaSpace,borderType)

iamge:原始图像

d:以当前像素为中心的整个滤波区域的直径。如果是 d < 0 ,则自动根据sigmaSpace参数计算得到。该值与保留的边缘信息数量成正比,与方法运行效率成反比。

simgaSpace:坐标空间sigma的值越大,参与计算的像素数量也就越多

borderType:可选参数,边界样式。

import cv2

img = cv2.imread("1.1.jpg")


dst1 = cv2.GaussianBlur(img, (9, 9), 0, 0)
# 双边滤波器,选用范围直径为15,颜色差为120的
dst2 = cv2.bilateralFilter(img, 9, 120, 100)

cv2.imshow("img", img)
cv2.imshow("GaussianBlur", dst1)
cv2.imshow("bilateralFilter", dst2)

cv2.waitKey()
cv2.destroyAllWindows()

七、腐蚀与膨胀

7.1  腐蚀

腐蚀会使图像沿着自己的边界向内收缩

dst = cv2.erode(image,kernal,anchor,iterations,borderType,borderValue)

kernal:腐蚀使用的核

anchor:可选参数,核的锚点位置。

iterations:可选参数,腐蚀操作的迭代次数,默认值为1。

borderType:可选参数,边界样式,建议默认。

borderValue:可选参数,边界值,建议默认。

import cv2
import numpy as np

img = cv2.imread("1.1.jpg")
k = np.ones((3, 3), np.uint8)

dst1 = cv2.erode(img, k)

cv2.imshow("img", img)
cv2.imshow("erode", dst1)

cv2.waitKey()
cv2.destroyAllWindows()

7.2  膨胀

膨胀会使图像沿着自己的边界向外扩张

dst = cv2.dilate(image, kernal,anchor,iterations,borderType,borderValue)

kernal:膨胀使用的核

anchor:可选参数,核的锚点位置。

iterations:可选参数,膨胀操作的迭代次数,默认值为1。

borderType:可选参数,边界样式,建议默认。

borderValue:可选参数,边界值,建议默认。

import cv2
import numpy as np

img = cv2.imread("1.1.jpg")
k = np.ones((3, 3), np.uint8) # k是核

dst1 = cv2.dilate(img, k)

cv2.imshow("img", img)
cv2.imshow("dilate", dst1)

cv2.waitKey()
cv2.destroyAllWindows()

7.3  开运算

开运算就是先进行腐蚀操作,再进行膨胀操作。可用来抹除图像外部的无关细节(或噪声)。

import cv2
import numpy as np

img = cv2.imread("1.1.jpg")
k = np.ones((3, 3), np.uint8)

dst = cv2.erode(img, k)   # 先腐蚀操作
dst = cv2.dilate(dst, k)  # 后膨胀操作

cv2.imshow("img", img)
cv2.imshow("open", dst)

cv2.waitKey()
cv2.destroyAllWindows()

7.4  闭运算 

闭运算就是先进行膨胀操作,再进行腐蚀操作。可用来抹除图像内部的无关细节(或噪声)。

import cv2
import numpy as np

img = cv2.imread("1.1.jpg")
k = np.ones((3, 3), np.uint8)

dst = cv2.dilate(img, k)
dst = cv2.erode(dst, k)

cv2.imshow("img", img)
cv2.imshow("close", dst)

cv2.waitKey()
cv2.destroyAllWindows()

八、图形检测

8.1  图像的轮廓

轮廓是什么?轮廓指的是图像中图形或物体的外边缘线条。

检测:   contours, hierarchy = cv2.findContours(image,mode,methode)

mode:轮廓的检索模式。可选模式如下:

        cv2.RETR_EXTERNAL                        只检测外轮廓

        cv2.RETR_LIST                                   检测所有轮廓,但不建立层次关系

        cv2.RETR_CCOMP                             检测所有轮廓,并建立两级层次关系

        cv2,RETR_TREE                                 检测所有轮廓,并建立树状结构的层次关系

methode:检测轮廓时使用的方法。可选如下:

        cv2.CHAIN_APPROX_NONE              储存轮廓上的所有点

        cv2.CHAIN_APPROX_SIMPLE           只保存水平、垂直或对角线轮廓的端点

        cv2.CHAIN_APPROX_TC89_L1         Ten-Chinl 近似算法中的一种

        cv2.CHAIN_APPROX_TC89_KCOS   Ten-Chinl 近似算法中的一种

contours:检测出的所有轮廓,list类型,每一个元素都是某个轮廓的像素坐标数组。

hierarchy:轮廓之间的层次关系。

画轮廓: drawContours(image,contours,contourIdx,color,thickness,lineTypee,hierarchy,maxLevel,offse)

import cv2

img = cv2.imread("1.1.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)                  # 变为灰度图
t, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)  # 灰度图转换为二值图像
# 检测图像轮廓,记录轮廓的每一个点
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
# 绘制轮廓,颜色为红色,线条宽度为5
cv2.drawContours(img, contours, -1, (0, 0, 255), 5)

cv2.imshow("img", img)

cv2.waitKey()
cv2.destroyAllWindows()

8.2  轮廓拟合

矩形包围框

retval = cv2.boundingRect(array)

array:轮廓数组

返回值  retval:元组类型。包括四个整数值,分别是最小矩形包围框左上角顶点的横坐标、左上角顶点的纵坐标、矩形的宽和矩形的高。也可以写成x, y, w, h =  cv2.boundingRect(array)

import cv2

img = cv2.imread("1.1.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 变为灰度图
t, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)  # 灰度图转换为二值图像

# 检测图像轮廓,记录轮廓的每一个点
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
x, y, w, h = cv2.boundingRect(contours[0])  # 获取第一个轮廓的最小矩形边框,记录坐标和宽高

# 绘制红色矩形
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)

cv2.imshow("img", img)

cv2.waitKey()
cv2.destroyAllWindows()

九、视频处理

PC没有摄像头,笔者罢工啦~~~

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值