OpenCV——第一课 图像基本操作

本文介绍了计算机眼中图像的基本概念,包括颜色模型如RGB,图像的像素表示,以及分辨率(PPI)的计算。详细阐述了图像的基本操作,如读取图像、图像处理流程、显示结果,还涉及了OpenCV库在Python中的使用,包括读取和保存图像、视频,以及图像的截取、颜色通道提取、像素值计算和图像融合等操作。此外,文章讨论了边界填充的不同方法和像素数值的计算规则。
摘要由CSDN通过智能技术生成

图像基本操作

计算机眼中的图像

首先我们可以把图像看成一个二维视图,针对图像的处理,我们需要将2D图像转化为具体数据,因此可分为以下几种情况:

  1. 形成新的图像
  2. 决策目标
  3. 目标结果
  4. 提取相关信息

图像的处理流程分为三步:

  1. 读取图像
  2. 图像处理
  3. 显示结果

基础知识
在表示图像时,有多种颜色模型(RGB、HSB、CMYK等),最常见的是RGB(红绿蓝)模型,这是一种加法颜色模型,其中三原色混合在一起就可以用来表示广泛的颜色范围。

每个原色(R,G,B)通常表示一个通道,其中三个值取值范围为[0,255]内的整数值,每个取值共有256个可能离散值,因此RGB模型总共需要3*8=24比特数,又称为24位色深图像。

我们可以把RGB看作一个三维直角坐标系,R G B的值分别对应坐标系的xyz轴的值,因此任何一种颜色都可以在坐标系中直接表示出来,在原点时,即取值全为0表示黑色,当取值全为255时表示白色,在连接黑色和白色的对角线上,是亮度等量的三基色混合而成的灰色,该线称为灰色线。

分辨率指横纵方向的像素点数,单位为px 800 × 1200 800\times1200 800×1200的图像是一个包含800列和1200行的网格,每个网格就是一个像素,因此包含了96万像素。但是图像中的像素并不表示物理尺寸,像素的大小取决于为该图像设置的每英寸像素数(Pixels Per Inch,PPI)。图像的计算PPI的基本公式如下:

  • PPI=宽度(像素)/图像宽度(英寸)
  • PPI=高度(像素)/图像高度(英寸)

一个2×3英寸的图像,图像分辨率为800×1200,则PPI是200
注意:出于历史原因,OpenCV的颜色模型为BGR,与RGB正好相反

图像描述
图像可以描述为一个二元函数 f ( x , y ) f(x,y) f(x,y),其中x、y为二维图像的坐标, f ( x , y ) f(x,y) f(x,y)表示在点(x,y)处的亮度或者颜色值,当两者皆为有限离散量时,该图像称为数字图像,此时:

  • x∈[0,h-1],其中h为图像的高度
  • y∈[0,w-1],其中w为图像的宽度
  • f ( x , y ) f(x,y) f(x,y)∈[0,L-1],这里L=256(RGB模型),同时有三种函数 f f f,即 f R f_R fR f G f_G fG f B f_B fB,分别对应R、G、B的三个分量

不同的图像类别通道数也不一样:

  • RGB模型的彩色图共有三个通道R、G、B表示R、G、B的分量
  • 灰度图只有一个通道表示亮度
  • 黑白图有一个通道,0表示黑色,1表示白色

基本操作

读取图像

首先导入cv2库,即openCV工具库

import cv2   #opencv读取的格式是BGR
import matplotlib.pyplot as plt
import numpy as np 
%matplotlib inline 

注:%matplotlib inline 为python内置的魔法命令,通常以%或者%%开头,可以在IPython的环境的操作中更加得心应手,这里是内嵌画图,省略plt.show(),自动生成对应图像显示在页面中,而不用弹出窗口

img=cv2.imread('cat.jpg',IMREAD_COLOR)  #读取图像,第二个参数不填时默认为彩色图像

#图像的显示,也可以创建多个窗口
cv2.imshow('image',img) 
# 等待时间,毫秒级,0表示任意键终止
cv2.waitKey(0) #n表示图片显示n毫秒后消失
cv2.destroyAllWindows()		#销毁窗口
  • IMREAD_COLOR: 彩色图像
  • IMREAD_GRAYSCALE: 灰度图像

图像如下图:
cat.jpg

img对象的类型

img.shape

输出: 当为彩图时:(414,500,3)
灰度图时:(414,500)

#保存,成功会返回true,失败返回false
cv2.imwrite('mycat.png',img)
像素个数(彩图时=414*500*3)
img.size

读取视频

cv2.VideoCapture可以捕获摄像头,用数字控制不同的设备,如果是视频文件,直接指定路径即可.
对于视频其实也可以看作是由一帧一帧的二维图像组成的,因此读取视频时,需要不断循环读取所有的帧

vc = cv2. VideoCapture('test.mp4')

# 检查是否打开正确
if vc.isOpened(): 
    oepn, frame = vc.read()   #open为true,frame为视频中的一帧
else:
    open = False
while open:
    ret, frame = vc.read()
    if frame is None:
        break
    if ret == True:
        gray = cv2.cvtColor(frame,  cv2.COLOR_BGR2GRAY)  #把三通道转化为灰度图
        cv2.imshow('result', gray)   #展示结果
        if cv2.waitKey(100) & 0xFF == 27:    #前者表示处理帧的速度,后者表示Esc键退出
            break
vc.release()
cv2.destroyAllWindows()

截取部分图像数据

cat=img[0:50,0:200]    # h,w,左闭右开

颜色通道提取

图片的拆分和合并

b,g,r=cv2.split(img)  #OpenCV中是bgr顺序,这里是拆分
img=cv2.merge((b,g,r))    #三个通道重新组合成一张图片

更改像素值

# 只保留R (BGR,一共三个通道,取0-2)
cur_img = img.copy()
cur_img[:,:,0] = 0   #B取0;‘:’表示取所有,即整个B通道的像素点全取0
cur_img[:,:,1] = 0   #G取0
cv_show('R',cur_img)

边界填充

顾名思义,即在图片的四周填充相应区域,cv2.copyMakerBorder函数可在图像周围形成边框

top_size,bottom_size,left_size,right_size = (50,50,50,50)     #上下左右

replicate = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_CONSTANT, value=0)

borderType参数类型:

  • BORDER_REPLICATE:复制法,也就是复制最边缘像素。
  • BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制例如: fedcba|abcdefgh|hgfedcb
  • BORDER_REFLECT_101:反射法,也就是以最边缘像素为轴,对称,gfedcb|abcdefgh|gfedcba
  • BORDER_WRAP:外包装法cdefgh|abcdefgh|abcdefg
  • BORDER_CONSTANT:常量法,常数值填充,不同value值对应不同的颜色填充。

像素数值计算

img_cat=cv2.imread('cat.jpg')
img_dog=cv2.imread('dog.jpg')

img_cat2= img_cat +10 #所有像素点都加10
img_cat[:5,:,0]       #取前五行,所有列,B通道

#相当于数值之和%256
(img_cat + img_cat2)[:5,:,0] 

cv2.add(img_cat,img_cat2)[:5,:,0]      #超过255,越界了,取255

图像融合

只有分辨率大小相同且类型相同的图片才能相加,否则会报错,可以用resize函数更改图像的像素点

img_dog = cv2.resize(img_dog, (500, 414))      #resize函数(w,h)直接更该

res = cv2.resize(img, (0, 0), fx=4, fy=4)      #img表示原图像,(w,h)表示输出图像的大小,fx值表示w扩大倍数,fy值表示h扩大倍数,输出为(0,0)时fxy生效

图像融合:

res = cv2.addWeighted(img_cat, 0.4, img_dog, 0.6, 0)      #添加权重值公式(x1,α,x2,β,b(偏置项))result=x1*α+x2*β+b

合并后的效果图:
在这里插入图片描述
这里的α和β没用范围,皆为双精度,最好相加为1。

总结

本篇文章主要讲述了读取图片和视频的一些操作

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zero3_msh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值