基于人工智能实验平台的OpenCV图片基础操作实践

opencv图片基础操作之图片读取/保存/显示

1.1 实验目的

熟悉opencv读入图片,存储图片,视频的读取、存储。

1.2 实验设备

安装了python和pychrm的电脑一台。

1.3 实验内容

包含图片的导入、存储,摄像头视频的读取、存储等。

1.4 实验原理

  1. 读/写图像文件

OpenCV的imread()函数和imwrite()函数能支持各种静态图像文件格式。不同系统支

持的文件格式不一样,但都支持BMP格式,通常还应该支持PNG、JPEG和TIFF格式。

接下来将介绍在Python和NumPy中表示一幅图像的细节。

无论哪种格式,每个像素都会有一个值,但不同格式表示像素的方式有所不同。例如,

可以通过二维NumPy数组来简单创建一个黑色的正方形图像:

 Img=np.zeros((3,3),dtype=numpy.uint8)
 ​
   如果在控制台打印这张图像,可得到如下结果:
 ​
 araay([[0,0,0],
 ​
 [0,0,0],
 ​
 [0,0,0]],dtype=uint8)

每个像素都由一个8位整数来表示,即每个像素值的范围是0~255。现在利用cv2.cvtColor函数将该图像转换成BIue-green-red(BGR)格式:

 Img=cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)

下面来看看这幅图像发生了什么变化:

araay([[[0,0,0],
 [0,0,0],
 [0,0,0]],
 ​
 [[0,0,0],
 [0,0,0],
 [0,0,0]],
 ​
 [[0,0,0],
 [0,0,0],
 [0,0,0]],dtype=uint8)

从这个结果可看出:现在每个像素都由一个三元数组表示,并且每个整型(integer)向量分别表示一个B、G和R通道。其他色彩空间(如HSV)也以同样的方式来表示像素,只是取值范围和通道数目不同(例如,HSV色彩空间的色度值范围是0~180)。

可以通过shape属性来查看图像的结构,它会返回行和列。如果有1个以上的通道,还

会返回通道数。

考虑下面这个例子:

img=np.zeros((3,3),dtype=numpy.uint8)
 print(img.shape)

执行上面代码得到的结果为(3,3)。如果将图像转化为BGR格式,shape会返回(3,3,3),这表明每个像素存在三个通道,前面两个3就代表图像的宽高像素,最后的3就代表通道数,也就是RBG三个通道。

可读取一种格式的图像文件,然后将其保存为另一种格式,imwrite函数就是另存函数。例如,下面的代码会将图像从PNG格式转换为JPEG格式:

 import cv2
 image=cv2.imread(‘xxx.png’)
 cv2.imwrite(‘xxx.jpg’,image)

在默认情况下,即使图像文件为灰度格式,imread0函数也会返回BGR格式的图像。

BGR与red-green-blue(RGB)所表示的色彩空间相同,但字节顺序相反。

下面列出的选项可作为imread()函数的参数:

IMRERD_RNYCOLOR=4
 IMRERD_RNYDEPTH=2
 IMRERD_COLOR=1
 IMREAD_GRAYSCALE=0
 IMREAD_LOAD_GDAD=8
 IMRERD_UNCHRNGED=-1

 例如下面的例子将加载的PNG文件作为灰度图像(在这个过程中会丢失所有的颜色信

息),然后又将其保存为灰度的PNG图像:

import cv2
 grayImage=cv2.imread(“xxx.png”,cv2.IMRERD_GRAYSCALE)
 cv2.imwrite(“xxx.png”,grayImage)

  若对OpenCV API不太熟悉,为了避免不必要的麻烦,最好对图像使用绝对路径

(例如,Windows下的绝对路径为C:/Joe/PicturestMyPic.png)。图像的相对路径是指Python脚本所在的文件夹。因此,在前面的例子,图片必须放在Python脚本所在的文件夹中,否则系统会找不到该图像。

  无论采用哪种模式,imread()函数会删除所有alpha通道的信息(透明度)。imwrite()函数要求图像为BGR或灰度格式,并且每个通道要有一定的位(bit),输出格式要支持这些

通道。例如,bmp格式要求每个通道有8位,而PNG允许每个通道有8位或16位。

2.  图像与原始字节之间的转换

  从概念上讲,一个字节能表示0到255的整数。目前,对于所有的实时图像应用而言,

虽然有其他的表示形式,但一个像素通常由每个通道的一个字节表示。

  一个OpenCV图像是.array类型的二维或三维数组。8位的灰度图像是一个含有字节值

的二维数组。一个24位的BGR图像是一个三维数组,它也包含了字节值。可使用表达式访问这些值,例如image[0,0]或image[0,0,0]。第一个值代表像素的y坐标或行,0表示

顶部;第二个值是像素的x坐标或列,0表示最左边;第三个值(如果可用的话)表示颜色

通道。

  例如,对于一个左上角有白色像素的8位灰度图像而言,image[0,0]的值为255。对于

一个左上角有蓝色像素的24位BGR图像而言,image[0,0]是[255,0,0]。

  若一幅图像的每个通道为8位,则可将其显式转换为标准的一维Pythonbytearray格式,反之,bytearray含有恰当顺序的字节,可以通过显式转换和重构,得到numpy.array形式的图像。

grayImage=numpy.array(grayByteArray).reshape(height,width)
 bgrImage=numpy.array(bgrByteArray).reshape(height,wtdth,3)

下面介绍一个更详细的例孔,即将含有随机字节的bytearray转换为灰度图像和BGR

图像:

 import cv2
 import numpy
 import os
 ​
 randomByteRrray=bytearray(os.urandom(120000))
 flatNumpyArray=numpy.array(randomByteArray)
 ​
 \#转换数组以制作400x300灰度图像。
 grayImage=flatNumpyArray.reshape(300,400)
 ​
 \#写图像
 cv2.imwrite(“RandomGray.png”,grayImage)
 ​
 \#转换数组以制作400 x 100彩色图像。
 bgrImage=flatNumpyArray.reshape(100,400,3)
 cv2.imwrite(“RandomColor.png”,bgrImage)

运行该脚本,会随机生成两个图像,它们位于脚本所在的目录,图像名为RandomGray.png和RandomColor.png.

 3. 使用numpy.array访问图像数据

现在对如何生成图像有了较好的理解,接下来就可以执行基本的图像操作了。众所周

知,加载OpenCV图像最简单的(也是最常见)的方式是使用imread函数,该函数会返回一幅图像,这幅图像是一个数组(根据imread()输入参数的不同,该图像可能是二维数组,也可能是三维数组)。

使用一个最基础的例子:将BGR图像在(0,0)处的像素转化为白像素。

 import cv2
 import numpy as np 
 ​
 img=cv2.imread(“xxx.png”)
 img[0,0]=[255,255,255]
 cv2.imshow('a',img)
 cv2.waitKey()

如果进一步调用标准的imshow()函数就能显示图像,并且在显示图像的左上角能看到一个白点。当然,这个功能不是很有用,但可以展示图像处理能够取得什么样的效果。现在,利用numpy.array函数来转换数组比用普通的Python数组转换要快得多。

假设想要改变一个特定像素的蓝色值,例如,像素坐标(150,120)。numpy.array提供的item()方法会非常方便,该函数有三个参数:x(或左)位置,y(或顶部)位置以及(x,y)位置的数组索引(注意,在BGR图像中,某一位置的数据是按B、G和R这样的顺序保存的三元数组),该函数能返回索引位置的值。另一个方法是通过itemset()函数可设置指定像素在指定通道的值(itemset()有两个参数:一个三元组(x、y和索引)和要设定的值)。

本例将坐标(150,120)的当前蕙色值(127)变为255:

import cv2
 import numpy as np
 img=cv2.itmread(“xxx.png”)
 print(“img.ttem(150,120,0))  #打印该像素的当前B值
 ​
 img.ittemset((150,120,0),255)
 print(“img.item(150,120,0”)   #prints255

下面介绍一个常见的操作,即操作通道:将挡定通道(B、G或R)的所有值置为零。

使用下面的代码可将图像所有的G(绿色)值设为0。可把img[:,:,1]=0里的1改成0或者2,0代表BGR通道里的B,2代表BGR通道里的R,而冒号则表示所有行或者列。

 import cv2
 import numpy as np
 img=cv2.imread(“xxx.png”)
 img[:,:,1]=0

最后一行是相关行img[:,:,1]=0,该命令行基本上可以让程序获得所有行和列的全部像素,可通过三元数组的索引将像素的颜色值设为0。如果显示此图像,会发现该图像完全没有绿色。

通过Numpy数组的索引访问原始像素,会发现许多有趣的事情;其中一件事情为设定感兴趣区域。一旦设定了该区域,就可以执行许多操作。例如,将该区域与变量绑定,然后设定第二个区域,并将第一个区域的值分配给第二个区域(将图像的一部分拷贝到该图像的另一个位置):

import cv2
 import numpy as np
 img=cv2.imread(“xxx.png”)
 my_roi=img[0:100,0:100]
 img[300:400,300:400]=my_roi
 cv2.imshow('a',img)
 cv2.waitKey()

图1.1 运行结果图

1.5 实验步骤

  1. 打开pycharm

我们右击相应的文件目录,选择new--->点击Python File,然后输入新建的文件名,点击确定,相应的.py文件就建好了,可以进行编写代码了。

图片的导入和保存:

opencv的imread()函数能支持各种静态图像文件格式,imread()函数会删除所有alpha通道的信息(透明度)。

impoert cv2
 img=cv2.imread('images\\apple.jpg')

imshow()函数显示图片,第一个参数是窗口名,第二个参数就是我们要显示的图片,waitKey函数显示图片的时间,不填参数就一直显示,是以微秒为单位的,比如1000就是1秒后窗口就会关闭。

cv2.imshow('apple', img)
 cv2.waitKey()

图1.1 运行结果图

图片保存我们用imwrite函数,第一个参数是要保存的路径,第二个参数是要保存的图片。

 cv2.imwrite('images\\apple_one.jpg',img)

图1.2

可以看到在当前文件夹下多出了一张图片。

注:1.文件路径有两个\是因为某些字符加上斜杠有特定的意义,如\r是回车、\n是换行,所以需要在家一个斜杠进行转义,说明这斜杠没有特殊意义,它就只是个斜杠,当然你可以直接用/,不需要转义,如./images/xxx.png。

2.读取路径中不要有中文,否则会报错

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值