Python图像认知与opencv基础
目录
一、图像表示
二、图像存储
三、基本图像操作
1.图像基础
2.黑白和随即像素图像
3.调整图像的大小
4.图像剪裁
5.图像绘制
6.读取视频
四、总结
OpenCV(开放源代码计算机视觉库)是一个开源的计算机视觉和机器学习软件库。由一系列 C++ 类和函数构成,用于图像处理、计算机视觉领域的算法实现。
一、图像表示
因为Opencv主要用于图像处理、计算机视觉领域的算法实现,那么我们首先就要了解计算机的图像表示原理。
像素是图像的基本单元,每个像素存储着图像的颜色、亮度和其他特征。一系列像素组合到一起就形成了完整的图像,在计算机中,图像以像素的形式存在并采用二进制格式进行存储。根据图像的颜色不同,每个像素可以用不同的二进制数表示。
计算机采用0/1编码的系统,数字图像也是利用0/1来记录信息,我们平常接触的图像都是8位数图像。opencv中常用的是8位图像,大多数彩色和灰度图像使用8位表示每个通道的像素值,范围从0到255,其中0,代表最黑,255,表示最白。
日常生活中常见的图像是RGB三原色图。RGB图上的每个点都是由红(R)、绿(G)、蓝(B)三个颜色按照一定比例混合而成的,几乎所有颜色都可以通过这三种颜色按照不同比例调配而成。在计算机中,RGB三种颜色被称为RGB三通道,每个通道的取值都是0-255,根据这三个通道存储的像素值,来对应不同的颜色。
二、图像存储
在OpenCV中,无论是读取还是创建图像,结果都是一个NumPy数组。
-
彩色图像:三维数组
-
灰度图像:二维
图像本质上是像素值的二维或三维矩阵(对于彩色图像)。
-
形状(Shape):图像的尺寸由其高(height)、宽(width)和通道数(channels)决定。可以通过
img.shape
属性获取这些信息。-
对于彩色图像(如RGB),返回的是一个包含三个值的元组 (height, width, channels)。
-
对于灰度图像,返回的是一个包含两个值的元组 (height, width),因为灰度图像只有一个通道。
-
-
数据类型(dtype):图像中的每个像素值的数据类型决定了可以存储的最大值。例如,8位无符号整数(uint8)允许的范围是从0到255。
-
像素表示
-
单通道图像(灰度图像):每个像素由一个数值表示,代表该点的亮度。值越低(接近0),颜色越暗;值越高(接近255),颜色越亮。
-
多通道图像(彩色图像): 在OpenCV中,默认情况下,彩色图像是以BGR(蓝-绿-红)顺序存储
-
三、基本图像操作
了解了图像的表示以及图像的存储原理后,我们就可以学习一些简单的Opencv的基本图像操作,在学习了这些操作的过程中,同时也会对图像的表示以及其存储原理理解更加的透彻。
1.图像基础
import cv2 as cv#读取图像cv.imread(path,读取方式)path是图像的路径,读取方式默认为彩色cat = cv.imread(\"./images/1.jpg\")print(cat)print(cat.shape)print(cat.size)#显示图像cv.imshow(winname,img)winname是显示图像的窗口名,img是要显示的图像cv.imshow(\"myimg\",cat)#cv.IMREAD_GRAYSCALE将读取方式设为灰色cat1 = cv.imread(\"./images/1.jpg\",cv.IMREAD_GRAYSCALE)print(cat1)print(cat1.shape)print(cat1.size)cv.imshow(\"catimg\",cat1)#保存图像cv.imwrite(path,img)path是图片保存的路径和图片名,img是要保存的图像cv.imwrite(\"./images/1_gray.jpg\",cat1)#设置图像绘制(显示)的时间cv.waitKey(n),n的单位是ms,n=0表示无期限地等待cv.waitKey(0)#释放窗口资源cv.destroyAllWindows
注:当显示多个图像时cv.imshow(winname,img)中的winname应该设置多个(如示例中的myimg和catimg),不然新显示的图像会覆盖掉前面的图像。
显示的图像:
打印的结果:
cat:
cat1:
根据打印的结果我们可以发现打印cat时,其本质就是一个三维数组,拆掉最外面的中括号[],显示的元素个数是651,对应的也就是图像的高height,再拆掉一个中括号[],显示的元素个数是650,就是图像的宽650,拆掉最后一个中括号,此时元素的个数是3,对应的是图像的通道数channels。
而根据打印的cat1的结果,它是一个二维数组,这正好对应我们前面图像表示中灰色图像的本质就是一个二维数组,651是图像的高,650是图像的宽。
2.黑白和随即像素图像
import numpy as npimport cv2 as cvheight=360width=480c=3#使用np.zeros()创建全0数组,表示黑色图像black=np.zeros((height,width,c),dtype=np.uint8)cv.imshow(\"black\",black)#使用np.full()创建白色图像,其中参数为255white=np.full((height,width,c),255,dtype=np.uint8)cv.imshow(\"white\",white)#索引修改像素值表示图像,这里black[:,:]或者black[:]都能行black[:,:,:]=255cv.imshow(\"newwhite\",black)#使用random.randint()创建随机像素值图像,参数为(0,256)左闭右开表示范围0-255是像素值random_img=np.random.randint(0,256,(360,480,3),dtype=np.uint8)cv.imshow(\"random\",random_img)cv.waitKey(0)cv.destroyAllWindows()
运行结果:
3.调整图像的大小
import cv2 as cvcat=cv.imread(\"./images/1.jpg\")#调整图片大小cv.resize(img,(w,h)),img是要调整大小的图像,(w,h)是要调整的尺寸,注意这里是先宽度再高度cat1=cv.resize(cat,(400,100))print(cat1.shape)print(cat1.size)cv.imshow(\"cat\",cat)cv.imshow(\"newcat\",cat1)cv.waitKey(0)cv.destroyAllWindows()
运行结果:
与原图片对比
size和shape也会改变:
4.图像剪裁
这里假设我们要裁剪猫的眼睛,要裁剪一个图片,我们只需要知道所需要裁剪图片的左上角坐标和右下角坐标,那么坐标我们该如何得到呢,将图片用画图编辑器打开,然后将鼠标至于图随意一个位置,画图编辑器的左下角会出现下图数据:
这就是鼠标置于图片上的产生的一个坐标,这样我们就可以获得所需要裁剪的图像的左上角坐标和右下角坐标
import cv2 as cv# 读取图像cat = cv.imread(\"./images/1.jpg\")# 切片 arr[h1:h2,w1:w2]289,231 368,397cateye=cat[231:297,289:368]cv.imshow(\"cat\",cat)cv.imshow(\"cateye\",cateye)cv.waitKey(0)cv.destroyAllWindows()
运行结果:
5.图像绘制
import cv2 as cvcat = cv.imread(\"./images/1.jpg\")# 绘制直线cv.line(img,start,end,color,thickness)cv.line(cat,(100,0),(100,100),(255,0,0),2)# 绘制矩形cv.rectangle(img,lefttop,righbottom,color,thickness=-1表示填充)cv.rectangle(cat,(319,287),(394,362),(0,0,0),2)# 绘制圆cv.clrcle(img,center,r,color,thickness=-1表示填充)cv.circle(cat,(325,269),50,(0,0,0),2,cv.LINE_AA)#LINE_AA反走样技术 抗锯齿 平滑 默认使用的是LINE_8cv.imshow(\"cat\",cat)cv.waitKey(0)cv.destroyAllWindows()
运行结果:
这里绘制直线,矩形,圆形都可以指定绘制的位置,只需要给好位置参数即可。
6.读取视频
import cv2 as cv# 创建一个videocapture对象# 读取视频文件 cap=cv.VideoCapture(\"./images/videocap.mp4\")# 从摄像头获取实时视频流cap=cv.VideoCapture(0)感兴趣可以试一下# 循环读取每一帧图像while True: # 调用read方法读取每一帧图像 ret,img=cap.read() # 判断是否读取成功 if not ret: print(\"error!\") break cv.imshow(\"video\",img) # if cv.waitKey(40)&0xFF==ord(\'q\'): print(\"按键退出!\") breakcap.release()cv.destroyAllWindows()
运行结果:
四、总结
学习了opencv的基础图像操作以及图像的表示与图像存储,对计算机图像显示的本质有了更清晰的认识,学习opencv基础图像操作的前提是对图像表示和图像存储有初步的了解,但是在真正学习opencv基础图像操作时,又会对图像表示和图像的存储有不一样的理解和感触。