opencv图片基础操作之图片读取/保存/显示
1.1 实验目的
熟悉opencv读入图片,存储图片,视频的读取、存储。
1.2 实验设备
安装了python和pychrm的电脑一台。
1.3 实验内容
包含图片的导入、存储,摄像头视频的读取、存储等。
1.4 实验原理
-
读/写图像文件
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 实验步骤
-
打开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.读取路径中不要有中文,否则会报错
标签:img,人工智能,cv2,实践,像素,OpenCV,图像,numpy,png From: https://blog.csdn.net/lin_yu_cheng/article/details/141952688