Python库cv2第一课:cv2的认识与入门(上)

        前两天将numpy库的基本知识做了一个简单的学习和回顾,主要是为了帮自己找回知识和忘记的函数,以及查看使得否需要进行新的应用。我们将两大成员数组与矩阵的知识点一一拉通学习之后,经过多多练习,便可逐渐掌握,numpy是一个计算的大库,在电脑计算有很大用处。

        然而,这仅仅只是python中最常用的一个库而已,对于团队的学习,还需要重点掌握的一个库为:cv2,这个库将在车辆的驾驶,图像处理,动态渲染等方面与重大的贡献,在车路协同,交通大数据的背景下,我们将会做到很多动态变化的图像,由此来看交通试试变化,由此采取实时的措施管理与控制。

        因此,作为模拟的库,自然与图像与计算紧密相连,也就是python中的numpy和matlab库的配合使用,在matlab库中我是用最多的一个模块为:matplotlib.pyplot,相信这也是大多数人接触最多的,用于绘制坐标图。

        然而,对于cv2,我目前仅限于了解有这个东西,那么,既然了解了想变成自己的东西,那就慢慢一步一步来,接下来,就进入入门的学习。

一、cv2库的安装        

首先是针对cv2库的安装,我们依旧在VS Code终端面板采用清华源:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python

        安装完毕之后方可采用import cv2 as cv2即可,也可as成一个可代表的字符。在这里,我们用来学习的照片如下:

cat.jpg

二、cv2的入门函数认识

 1、读取与写入照片

        在cv2中,最基本的函数为读取和写入照片,和保存图片。cv2读取的格式有很多,基本上完全包括了目前素有照片的主流储存模式。读取照片采用的函数为:imread(),写入照片采用的函数为:imwrite。具体用法如下:

        cv2.imread(filename,flags):filename写入想要展示的图片命名,字符串格式,flags表示该如何读取,对于其读取的方式,这里一般采用以下三种:

        IMREAD_COLOR (1):加载彩色图像

        IMREAD_GRAYSCALE (0):以灰度模式加载图像

        IMREAD_UNCHANGED (-1):加载图像,包括 alpha 通道

        通常采用1加载图片。

        而对于图片的保存一般采用imwrite()函数,其用法为:

        cv2.imwrite(filename,img):img为读取的照片的变量参数,照片被读取定义为MatLike,其本质格式为多维数组,将一个像素作为一个坐标点。展示照片的imshow()在目前阶段写法是相同的。

        特别注意的一点为:imwrite() 只能保存 BGR 3通道图像,或 8 位单通道图像、或 PNG/JPEG/TIFF 16位无符号单通道图像

img_test = cv2.imread('cat.jpg', flags=cv2.IMREAD_COLOR)
cv2.imshow('cat_photo', img_test)
# 保持照片窗口停留的时间
cv2.waitKey(3000)
# 销毁所有窗口
cv2.destroyAllWindows()

        输出的仍然是原来的图案,这里的waitKey表示图片展示框停留的时间(ms),destoryALLWindow表示销毁所有串口,保持好习惯,有打开就有关闭,在python中这一点要求并不严格,甚至几乎不检测,但在java中,对每个窗口的进入与关闭是严格的,甚至窗口个数也限制挺大的。

img_test_2 = cv2.imread('cat.jpg', 0)
print(type(img_test))
cv2.imshow('cat_photo_2', img_test_2)
cv2.imwrite("cat_grey.jpg", img_test_2)
key = cv2.waitKey(3000)
cv2.destroyAllWindows()

        可以看到,通过0的方式打开的图片,将显示为灰白色,我们将其重新保存一份放入文件夹中。

 2、通过matplotlib结合渲染

        matplotlib库是一个常用的绘图库,i面提供了各式各样的绘图参数,我们这里主要学习cv2,matplotlib库的内容直接用就可以了。该库的重点在于渲染,改善照片的展示质量,我们在这里做一个三秒的保存渲染并关闭。

img_test_3 = cv2.imread('cat.jpg', 0)
# 运用函数渲染图像
plt.imshow(img_test_3)
# 展示三秒并关闭,这里不采用show,而使用定时展示与关闭
plt.ion()
plt.pause(3)
plt.close()

        这里可以采用一个暂停函数的三组合来代替额传统的plt.show,是一个自动关闭打开的对话框。经过渲染,其图像为:

3、以rgb方式调整图像

        除了对图片进行传统的普通处理,在cv2中,还提供了rgb格式的图像修改方法,其具体的修改方案为将图像看作是一个ndarray多维数组,可以采用多维数组定位的方法。因此,我们需要先知道其图片的像素点大小和图片的尺寸,还有图像通过几RGB通道进行渲染的。

img_test_rgb = cv2.imread('cat.jpg', 1)
print(type(img_test_rgb))
# 得到该ndarray的尺寸:(266,423,3)
print(img_test_rgb.shape)
# 得到该ndarray的像素大小:337554
print(img_test_rgb.size)

        其输出的结果分别为:<class 'numpy.ndarray'>          (266, 423, 3)            337554。其中的3表示其采用的rgb渲染通道为3项,RGB就是通过三个数定义光的颜色,[0,0,0]表示黑色;[255.255,255]表示白色。

        紧接着,在知道其为平面坐标的情况下,我们便可以进行索引与修改:

# 试着访问某位置的元素的rgb值
print(img_test_rgb[200, 200])
# 改变某些位置元素的颜色
# 将左上角100元素内的颜色为黑色
for i in range(100):
    for j in range(100):
        img_test_rgb[i, j] = [0, 0, 0]
cv2.imshow('cat_photo_modify', img_test_rgb)
cv2.waitKey(3000)
cv2.imwrite("cat_rgb.jpg", img_test_rgb)
cv2.destroyAllWindows()

        如此,我们边疆左上角100x100像素的图像全部改为了rgb显示为黑色的图案了。

三、cv2的基础操作

⭐1、图像拆分与合并

        通过split()函数可以将原始图像分割为三个通道,其中“0”表示蓝色,“1”表示绿色,“2”表示红色。而merge()函数则可以将通道合并起来。这里简单学习一下RGB,在RGB色彩的定义中,色彩由三个通道组成:蓝(B),绿(G),红(R)。

# split可以将图像拆分为单独的通道
img_test_rgb_2 = cv2.imread('cat.jpg', 1)
b_img, g_img, r_img = cv2.split(img_test_rgb_2)

        以下分别展示各种单通道的图片:

cv2.imshow("cat_rgb_b.jpg", b_img)

 

cv2.imshow("cat_rgb_g.jpg", g_img)

 

cv2.imwrite("cat_rgb_r.jpg", r_img)

        对于图像,如果只有单通道,那么,他的值只能在0~255之间,也就是每个像素点之间只存在一层通道。纯粹的黑白对比图只存在0或者255的像素点。其他数字的出现会产生不同的灰度,但仍然是灰度图。以上便是三种通道分离开之后的各自通道组成的单通道灰度图。

thoro_rbg = cv2.merge([b_img, b_img])
cv2.imwrite('cat_two_rbg.jpg', thoro_rbg)

        然而,当我们将同一个像素点,再次覆盖的时候便会发生色彩的变化,当我们第三次再覆盖一层同样范围的数的时候,便会出现更加丰富的色彩。我在合并通道的收,尝试过输出两通道合并的图,然而,最终报错,我的目前的学习理解状况来看,应当是cv2能识别的仅仅为单通道图和三通道图,不存在二通道图。

Traceback (most recent call last):
  File "d:\PythonLearn\PythonWork\专题cv2入门(上)_初步认识.py", line 65, in <module>
    cv2.imwrite('cat_two_rbg', thoro_rbg)
cv2.error: OpenCV(4.8.1) D:\a\opencv-python\opencv-python\opencv\modules\imgcodecs\src\loadsave.cpp:696: error: (-2:Unspecified error) could not find a writer for the specified extension in function 'cv::imwrite_'

         因此,我们只能合成三通道,这就回到了imwrite只能读取单通道或者三通道进行文件图片写入。

# 合并通道
img_rgb_test = cv2.imread('cat.jpg', 1)
b_img, g_img, r_img = cv2.split(img_rgb_test)
thoro_three = cv2.merge([r_img, g_img, b_img])
cv2.imwrite('thoro_3rgb.jpg', thoro_three)

         而且还有一点,它分离的时候是按照B+G+R的顺序分离的,在这里我们合并的时候,是按照R+G+B的堆叠模式合成的,堆叠顺序影响图案的形成,最终输出的图案为:

        接下来,虽然山面说不能通过合并两通道的RBG通道进行书写输出,却可以通过关闭某个或两个通道,这在程序看来,还是处于三通道,只是关闭的通道处于透明状态——存在但不可见,因此,就去掉某图层的颜色。示例如下:

# 关闭rbg光学三原色的过程
# 关闭蓝色通道
img_test_rgb_2 = cv2.imread('cat.jpg', 1)
# 此方案写法等同于将源图片分割为三通道,表达法不同
img_test_rgb_2[:, :, 0] = False
cv2.imwrite('cat_rbg_lost_b.jpg',img_test_rgb_2)
img_test_rgb_2[:, :, 0] = True

        其次,对于三通道图,若是三个通道的值是相同的,输出的也是灰度图。区分它们的重点辨识点为属性中查看位深度:当位深度为8的图为单通道灰度图,当深度为24则为三通道灰度图。一般来说,三通道还是彩色图的。

        而三通道与单通道之间是存在转化关系的:

        (1)单通道图转化为三通道图:

img = cv2.cvtColor(img , cv2.COLOR_GRAY2RGB)

        (2)三通道图转化为单通道图,分为读取前转化与读取后转化:

img = cv2.imread('test.jpg', 0)
img = cv2.cvtColor(img , cv2.COLOR_RGB2GRAY)

        至此,图像拆分与合并的难点编导此掌握了。

2、绘制线形

        接下来的一大基础训练为在原始图像上绘制形状。此等操作在我们开发java的时候经常用到,用于开发软件与APP的时候由于手机型号不同,一般都采用相对位置进行开发。此方案同样如此,对每个相对位置的开发,是至关重要的环节。以下学习几个重点的函数:

函数说明命令
cv2.line()绘制连接两点的线段cv2.line(img, pt1, pt2, color, thickness)
cv2.circle()以给定点为中心绘制给定半径的圆cv2.circle(img, center, radius, color, thickness)
cv2.rectangle绘制一个矩形,给定点为左上角和右角cv2.rectangle(img, pt1, pt2, color, thickness)
cv2.ellipse()绘制简单的粗椭圆弧或填充椭圆扇区cv2.ellipse(img, center, axes, angle, startAngle, endAngle, color, thickness)

        对于每个函数,其也有着对应的参数:

        img:表示要绘制形状的图像。

        color:形状的颜色,一般采用RGB方式传递。 对于 BGR,将其作为元组传递。 对于灰度,只需传递标量值。

        thickness:线或圆的粗细。如果为圆或封闭图形,传递-1,它将填充形状。

        lineType:线条的类型,是否8连线,抗锯齿线设置等。

        以下展示一段团绘制的实例,用于自我的学习:

img_draw = cv2.imread('cat.jpg', 1)
# 在图片上添加一个矩形
cv2.rectangle(img_draw, (15, 35), (235, 230), (45, 243, 26), 3)
# 在图片上添加一条横线
cv2.line(img_draw, (30, 50), (240, 50), (190, 92, 19), 5)
# 添加一个填充圆形
cv2.ellipse(img_draw, (280, 100), (70, 10), -20, 0, 360, (0, 0, 255), -1)
# 储存图片
cv2.imwrite('cat_draw.jpg', img_draw)

        其代码绘制的图案如下:

        如今这只是进行简单的线条绘制,等学习到一定程度,可以绘制更多的动态模型,我主要是为了在智慧驾驶,车路协同、信号控制等演示上重点运用此库。 

        到这里,cv2的入门课基本就结束了,我们已经学习了cv2的基本流程,现在,可以进行简单的图形处理了,因此,对于去除背景这件事,是不是就变得很简单了呢?纯色。万丈高楼平地起,每天学习一点点。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值