openCV简介
OpenCV是一款由Intel公司俄罗斯团队发起并参与和维护的一个计算机视觉处理开源软件库,支持与计算机视觉和机器学习相关的众多算法,并且正在日益扩展
openCV安装
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python
openCV基础图像操作
1、读取图像
import cv2
cv2.imread(path,[读取方式])
#参数:
"""
path:你要读取的图片路径
读取方式的标志(彩色-默认,灰色等等)
"""
import cv2
img_data = cv2.imread("./src/img.png",cv2.COLOR_BGR2GRAY)
print(img_data)
2、显示图像
cv2.imshow(arg1,arg2)
"""
arg1:显示图像的窗口名称,以字符串类型表示
arg2:要加载的图像
"""
注意:在调用显示图像的API后,要调用cv2.waitKey(0)给图像绘制留下时间,否则窗口会出现无响应情况,并且图像无法显示出来
img_data = cv2.imread("./src/img.png")
cv2.imshow("img1",img_data)
cv2.waitKey(0)
3、保存图像
cv2.imwrite(arg1,arg2)
"""
arg1:文件名,要保存到哪里
arg2:要保存的图像
"""
import cv2
img_data = cv2.imread("./src/img.png")
cv2.imwrite("./src/1.png",img_data)
绘制几何图形
1、绘制直线
cv2.line(img,start,end,color,thickness)
"""
img:要绘制直线的图像
start:直线的起点
end:直线的终点
color:直线的颜色
thickness:直线的宽度
"""
import cv2
img_data = cv2.imread("./src/img.png")
print(img_data.shape)
cv2.line(img_data,(0,0),(0,607),color=[3,134,254],thickness=3)
cv2.imshow("img1",img_data)
cv2.waitKey(0)
2、绘制圆形
cv2.circle(img,centerpoint, r, color, thickness)
"""
img:要绘制圆形的图像
centerpoint:圆心
r:半径
color:线条的颜色
thickness:线条的宽度,为-1时生成闭合图案并填充颜色
"""
import cv2
img_data = cv2.imread("./src/img.png")
cv2.circle(img_data,(300,300),50,[255,74,59],3)
cv2.imshow("img1",img_data)
cv2.waitKey(0)
3、绘制矩形
cv2.rectangle(img,leftupper,rightdown,color,thickness)
"""
img:要绘制矩形的图像
leftupper:矩形的左上角坐标
rightdown:矩形的右下角坐标
color:线条的颜色
thickness:线条的宽度
"""
import cv2
img_data = cv2.imread("./src/img.png")
cv2.rectangle(img_data,[100,100],[300,300],[0,0,0],3)
cv2.imshow("img",img_data)
cv2.waitKey(0)
4、向图像中添加文字
cv2.putText(img,text,station, font, Fontscale ,color,thickness,cv2.LINE_AA)
"""
img:要添加文字的图片
text:要添加的文字
station:文本的放置位置
font:字体样式
fontscale:字体大小
thickness:线条宽度
cv2.LINE_AA
最后一个参数 `cv2.LINE_AA` 表示使用反走样(Anti-Aliasing)技术来绘制文本边框。
- 反走样是一种提高图形质量的技术,它通过混合颜色和像素边缘以减少锯齿状效果,使文本看起来更加平滑、清晰。
- 在 OpenCV 中,`cv2.LINE_AA` 是一种高级线条类型,用于实现文本边界的高质量渲染。相比于其他线型如 `cv2.LINE_8`(默认值),它能提供更好的视觉效果,特别是在文本较小或者需要高精度显示的情况下
"""
import cv2
img_data = cv2.imread("./src/img.png")
cv2.putText(img_data,"text",(100,100),cv2.FONT_ITALIC,2,[0,0,0],3)
cv2.imshow("img",img_data)
cv2.waitKey(0)
5、获取并修改图像中的像素点
import cv2
img_data = cv2.imread("./src/img.png")
for i in range(200):
img_data[100,100+i] = [255,0,0]
cv2.imshow("img",img_data)
cv2.waitKey(0)
6、捕获摄像头的实时视频流
cap = cv2.VideoCapture(path)
"""
path视频流资源路径设置为0代表从默认摄像头捕获视频流
"""
ret, frame = cap.read()
"""
返回值cap 调用read()方法可以得到一个布尔值和一帧图像。布尔值表示是否成功读取到帧,如果为False,可能是因为视频结束或读取失败;如果为True,第二项则是当前帧的图像数据。
"""
import cv2
cap = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc('X', 'V', 'I', 'D')
vw = cv2.VideoWriter("./src/test.avi", fourcc, 10, [512, 512])
while True:
ret, frame = cap.read()
if ret == False or cv2.waitKey(10) == ord("q"):
break
else:
cv2.imshow("img", frame)
vw.write(frame)
cap.release()
vw.release()
cv2.destroyAllWindows()
计算机眼中的图像
1、像素
像素是图像的基本单元,每个像素存储着图像的颜色、亮度和其他特征。一系列像素组合到一起就形成了完整的图像,在计算机中,图像以像素的形式存在并采用二进制格式进行存储。根据图像的颜色不同,每个像素可以用不同的二进制数表示。
日常生活中常见的图像是RGB三原色图。RGB图上的每个点都是由红(R)、绿(G)、蓝(B)三个颜色按照一定比例混合而成的,几乎所有颜色都可以通过这三种颜色按照不同比例调配而成。在计算机中,RGB三种颜色被称为RGB三通道,根据这三个通道存储的像素值,来对应不同的颜色。
2、图像
计算机采用0/1编码的系统,数字图像也是利用0/1来记录信息,我们平常接触的图像都是8位数图像,包含0~255灰度,其中0,代表最黑,1,表示最白。
1、二值图像
一幅二值图像的二维矩阵仅由0、1两个值构成,“0”代表黑色,“1”代白色。由于每一像素(矩阵中每一元素)取值仅有0、1两种可能,所以计算机中二值图像的数据类型通常为1个二进制位。二值图像通常用于文字、线条图的扫描识别(OCR)和掩膜图像的存储。
2、灰度图
每个像素只有一个采样颜色的图像,这类图像通常显示为从最暗黑色到最亮的白色的灰度,尽管理论上这个采样可以任何颜色的不同深浅,甚至可以是不同亮度上的不同颜色。灰度图像与黑白图像不同,在计算机图像领域中黑白图像只有黑色与白色两种颜色;但是,灰度图像在黑色与白色之间还有许多级的颜色深度。灰度图像经常是在单个电磁波频谱如可见光内测量每个像素的亮度得到的,用于显示的灰度图像通常用每个采样像素8位的非线性尺度来保存,这样可以有256级灰度(如果用16位,则有65536级)。
3、彩色图
每个像素通常是由红(R)、绿(G)、蓝(B)三个分量来表示的,分量介于(0,255)。RGB图像与索引图像一样都可以用来表示彩色图像。与索引图像一样,它分别用红(R)、绿(G)、蓝(B)三原色的组合来表示每个像素的颜色。但与索引图像不同的是,RGB图像每一个像素的颜色值(由RGB三原色表示)直接存放在图像矩阵中,由于每一像素的颜色需由R、G、B三个分量来表示,M、N分别表示图像的行列数,三个M x N的二维矩阵分别表示各个像素的R、G、B三个颜色分量。RGB图像的数据类型一般为8位无符号整形,通常用于表示和存放真彩色图像。
灰度实验
1、最大值法
从R、G、B三个通道的值中选出最大的一个,并将其作为灰度图像中对应位置的像素值。
import cv2
img_data = cv2.imread("./src/img.png")
for i in range(img_data.shape[0]):
for j in range(img_data.shape[1]):
img_data[i,j] = max(img_data[i,j][0],img_data[i,j][1],img_data[i,j][2])
cv2.imshow("img",img_data)
cv2.waitKey(0)
2、平均值法
R、G、B三个通道的像素值全部加起来,然后再除以三,得到的平均值就是灰度图像中对应位置的像素值。
import cv2
img_data = cv2.imread("./src/img.png")
for i in range(img_data.shape[0]):
for j in range(img_data.shape[1]):
img_data[i,j] = (int(img_data[i,j][0])+int(img_data[i,j][1])+int(img_data[i,j][2]))//3
cv2.imshow("img",img_data)
cv2.waitKey(0)
3、加权均值法
对于彩色图像的每个像素,它会按照一定的权重去乘以每个通道的像素值,并将其相加,得到最后的值就是灰度图像中对应位置的像素值。
import cv2
img_data = cv2.imread("./src/img.png")
for i in range(img_data.shape[0]):
for j in range(img_data.shape[1]):
img_data[i,j] = int(img_data[i,j][0]*0.2+img_data[i,j][1]*0.5+img_data[i,j][2]*0.3)
cv2.imshow("img",img_data)
cv2.waitKey(0)
这种是最常用的加权均值方式(cv2内置了)
import cv2
# image=cv2.imread('./1.jpg')
# gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
gray = cv2.imread("1.jpg",cv2.IMREAD_GRAYSCALE)#0.299R + 0.587G + 0.114*B
print(gray)
cv2.imshow("gray",gray)
cv2.waitKey(0)
二值化实验
1、阈值值(THRESH_BINARY)
阈值法就是通过设置一个阈值,将灰度图中的每一个像素值与该阈值进行比较,小于等于阈值的像素就被设置为0(黑),大于阈值的像素就被设置为maxval。
import cv2
img_data = cv2.imread("./src/test.png",cv2.IMREAD_GRAYSCALE)
_,re = cv2.threshold(img_data,127,255,cv2.THRESH_BINARY)
cv2.imshow("img",re)
cv2.waitKey(0)
2、反阈值法(THRESH_BINARY_INV)
顾名思义,就是与阈值法相反。反阈值法是当灰度图的像素值大于阈值时,该像素值将会变成0(黑),当灰度图的像素值小于等于阈值时,该像素值将会变成maxval。
import cv2
img_data = cv2.imread("./src/test.png",cv2.IMREAD_GRAYSCALE)
_,re = cv2.threshold(img_data,127,255,cv2.THRESH_BINARY_INV)
cv2.imshow("img",re)
cv2.waitKey(0)
3、截断阈值法(THRESH_TRUNC)
截断阈值法,指将灰度图中的所有像素与阈值进行比较,像素值大于阈值的部分将会被修改为阈值,小于等于阈值的部分不变。换句话说,经过截断阈值法处理过的二值化图中的最大像素值就是阈值。
import cv2
img_data = cv2.imread("./src/test.png",cv2.IMREAD_GRAYSCALE)
_,re = cv2.threshold(img_data,127,255,cv2.THRESH_TRUNC)
cv2.imshow("img",re)
cv2.waitKey(0)
4、低阈值零处理法(THRESH_TOZERO)
低阈值零处理,字面意思,就是像素值小于等于阈值的部分被置为0(也就是黑色),大于阈值的部分不变。
import cv2
img_data = cv2.imread("./src/test.png",cv2.IMREAD_GRAYSCALE)
_,re = cv2.threshold(img_data,127,255,cv2.THRESH_TOZERO)
cv2.imshow("img",re)
cv2.waitKey(0)
5、超阈值零处理法(THRESH_TOZERO_INV)
超阈值零处理就是将灰度图中的每个像素与阈值进行比较,像素值大于阈值的部分置为0(也就是黑色),像素值小于等于阈值的部分不变。
import cv2
img_data = cv2.imread("./src/test.png",cv2.IMREAD_GRAYSCALE)
_,re = cv2.threshold(img_data,127,255,cv2.THRESH_TOZERO_INV)
cv2.imshow("img",re)
cv2.waitKey(0)
6、OTSU阈值法
自适应二值化
与二值化算法相比,自适应二值化更加适合用在明暗分布不均的图片,因为图片的明暗不均,导致图片上的每一小部分都要使用不同的阈值进行二值化处理,这时候传统的二值化算法就无法满足我们的需求了,于是就出现了自适应二值化。
自适应二值化方法会对图像中的所有像素点计算其各自的阈值,这样能够更好的保留图片里的一些信息。
cv2.adaptiveThreshold(image_np_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 7, 10)
其中各个参数的含义如下:
maxval:最大阈值,一般为255
adaptiveMethod:小区域阈值的计算方式:
ADAPTIVE_THRESH_MEAN_C:小区域内取均值
ADAPTIVE_THRESH_GAUSSIAN_C:小区域内加权求和,权重是个高斯核
thresholdType:二值化方法,只能使用THRESH_BINARY、THRESH_BINARY_INV,也就是阈值法和反阈值法
blockSize:选取的小区域的面积,如7就是7*7的小块。
c:最终阈值等于小区域计算出的阈值再减去此值
下面介绍一下这两种方法。
1、取均值
import cv2
img_data = cv2.imread("./src/test.png",cv2.IMREAD_GRAYSCALE)
img = cv2.adaptiveThreshold(img_data,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,3,1)
cv2.imshow("img",img)
cv2.waitKey(0)
2、加权求和
import cv2
img_data = cv2.imread("./src/test.png",cv2.IMREAD_GRAYSCALE)
img = cv2.adaptiveThreshold(img_data,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,3,1)
cv2.imshow("img",img)
cv2.waitKey(0)
SCALE)
img = cv2.adaptiveThreshold(img_data,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,3,1)
cv2.imshow(“img”,img)
cv2.waitKey(0)
[外链图片转存中...(img-N3Pmu3CT-1723469850555)]
## 2、加权求和
```python
import cv2
img_data = cv2.imread("./src/test.png",cv2.IMREAD_GRAYSCALE)
img = cv2.adaptiveThreshold(img_data,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,3,1)
cv2.imshow("img",img)
cv2.waitKey(0)