当前位置:   article > 正文

Python库cv2第一课: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位无符号单通道图像

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

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

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

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

 2、通过matplotlib结合渲染

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

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

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

3、以rgb方式调整图像

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

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

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

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

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

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

三、cv2的基础操作

⭐1、图像拆分与合并

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

  1. # split可以将图像拆分为单独的通道
  2. img_test_rgb_2 = cv2.imread('cat.jpg', 1)
  3. 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的像素点。其他数字的出现会产生不同的灰度,但仍然是灰度图。以上便是三种通道分离开之后的各自通道组成的单通道灰度图。

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

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

  1. Traceback (most recent call last):
  2. File "d:\PythonLearn\PythonWork\专题cv2入门(上)_初步认识.py", line 65, in <module>
  3. cv2.imwrite('cat_two_rbg', thoro_rbg)
  4. 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只能读取单通道或者三通道进行文件图片写入。

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

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

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

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

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

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

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

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

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

  1. img = cv2.imread('test.jpg', 0)
  2. 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连线,抗锯齿线设置等。

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

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

        其代码绘制的图案如下:

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/木道寻08/article/detail/807716
推荐阅读
相关标签
  

闽ICP备14008679号